waybetter 0.1.1 → 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +139 -6
- package/bin/waybetter.mjs +43 -0
- package/build/runtime.mjs +105 -0
- package/cli/buildenv.mjs +130 -0
- package/cli/dev.mjs +97 -0
- package/cli/i18n.mjs +382 -0
- package/cli/manifests.mjs +383 -0
- package/cli/release.mjs +437 -0
- package/cli/releasecheck.mjs +15 -0
- package/cli/remote.mjs +260 -0
- package/cli/store.mjs +378 -0
- package/cli/strings.mjs +123 -0
- package/dist/runtime/column.d.ts +93 -0
- package/dist/runtime/column.js +451 -0
- package/dist/runtime/column.js.map +1 -0
- package/dist/runtime/commandReport.d.ts +19 -0
- package/dist/runtime/commandReport.js +47 -0
- package/dist/runtime/commandReport.js.map +1 -0
- package/dist/runtime/commands.d.ts +72 -0
- package/dist/runtime/commands.js +214 -0
- package/dist/runtime/commands.js.map +1 -0
- package/dist/runtime/devErrors.d.ts +16 -0
- package/dist/runtime/devErrors.js +30 -0
- package/dist/runtime/devErrors.js.map +1 -0
- package/dist/runtime/domHub.d.ts +21 -0
- package/dist/runtime/domHub.js +139 -4
- package/dist/runtime/domHub.js.map +1 -1
- package/dist/runtime/featureModules.d.ts +157 -0
- package/dist/runtime/featureModules.js +484 -0
- package/dist/runtime/featureModules.js.map +1 -0
- package/dist/runtime/featureTable.d.ts +144 -0
- package/dist/runtime/featureTable.js +223 -0
- package/dist/runtime/featureTable.js.map +1 -0
- package/dist/runtime/fonts.d.ts +22 -0
- package/dist/runtime/fonts.js +72 -0
- package/dist/runtime/fonts.js.map +1 -0
- package/dist/runtime/i18n.d.ts +138 -0
- package/dist/runtime/i18n.js +614 -0
- package/dist/runtime/i18n.js.map +1 -0
- package/dist/runtime/i18nCheck.d.ts +30 -0
- package/dist/runtime/i18nCheck.js +224 -0
- package/dist/runtime/i18nCheck.js.map +1 -0
- package/dist/runtime/pageLang.d.ts +8 -0
- package/dist/runtime/pageLang.js +64 -0
- package/dist/runtime/pageLang.js.map +1 -0
- package/dist/runtime/pageStrings.d.ts +35 -0
- package/dist/runtime/pageStrings.js +76 -0
- package/dist/runtime/pageStrings.js.map +1 -0
- package/dist/runtime/panelButton.d.ts +33 -0
- package/dist/runtime/panelButton.js +83 -0
- package/dist/runtime/panelButton.js.map +1 -0
- package/dist/runtime/permissions.d.ts +47 -0
- package/dist/runtime/permissions.js +141 -0
- package/dist/runtime/permissions.js.map +1 -0
- package/dist/runtime/pluginApi.d.ts +51 -2
- package/dist/runtime/pluginApi.js +137 -22
- package/dist/runtime/pluginApi.js.map +1 -1
- package/dist/runtime/pluginI18n.d.ts +29 -0
- package/dist/runtime/pluginI18n.js +119 -0
- package/dist/runtime/pluginI18n.js.map +1 -0
- package/dist/runtime/settingsForm.d.ts +66 -0
- package/dist/runtime/settingsForm.js +114 -0
- package/dist/runtime/settingsForm.js.map +1 -0
- package/dist/runtime/site.d.ts +5 -0
- package/dist/runtime/site.js +1 -1
- package/dist/runtime/site.js.map +1 -1
- package/dist/runtime/siteRuntime.d.ts +144 -0
- package/dist/runtime/siteRuntime.js +175 -0
- package/dist/runtime/siteRuntime.js.map +1 -0
- package/dist/runtime/stringPackHook.d.ts +84 -0
- package/dist/runtime/stringPackHook.js +220 -0
- package/dist/runtime/stringPackHook.js.map +1 -0
- package/dist/runtime/stringPackTranslate.d.ts +61 -0
- package/dist/runtime/stringPackTranslate.js +267 -0
- package/dist/runtime/stringPackTranslate.js.map +1 -0
- package/dist/runtime/stringPacks.d.ts +248 -0
- package/dist/runtime/stringPacks.js +610 -0
- package/dist/runtime/stringPacks.js.map +1 -0
- package/dist/runtime/styles.d.ts +15 -0
- package/dist/runtime/styles.js +81 -0
- package/dist/runtime/styles.js.map +1 -0
- package/dist/runtime/textNet.d.ts +15 -0
- package/dist/runtime/textNet.js +131 -0
- package/dist/runtime/textNet.js.map +1 -0
- package/dist/runtime/themeApi.d.ts +121 -0
- package/dist/runtime/themeApi.js +220 -0
- package/dist/runtime/themeApi.js.map +1 -0
- package/dist/runtime/themeBar.d.ts +28 -0
- package/dist/runtime/themeBar.js +82 -0
- package/dist/runtime/themeBar.js.map +1 -0
- package/dist/runtime/themeChoice.d.ts +52 -0
- package/dist/runtime/themeChoice.js +69 -0
- package/dist/runtime/themeChoice.js.map +1 -0
- package/dist/runtime/themeComponents.d.ts +435 -0
- package/dist/runtime/themeComponents.js +476 -0
- package/dist/runtime/themeComponents.js.map +1 -0
- package/dist/runtime/themeDecor.d.ts +73 -0
- package/dist/runtime/themeDecor.js +133 -0
- package/dist/runtime/themeDecor.js.map +1 -0
- package/dist/runtime/themeDerive.d.ts +69 -0
- package/dist/runtime/themeDerive.js +117 -0
- package/dist/runtime/themeDerive.js.map +1 -0
- package/dist/runtime/themeDoctor.d.ts +52 -0
- package/dist/runtime/themeDoctor.js +112 -0
- package/dist/runtime/themeDoctor.js.map +1 -0
- package/dist/runtime/themeGuards.d.ts +60 -0
- package/dist/runtime/themeGuards.js +235 -0
- package/dist/runtime/themeGuards.js.map +1 -0
- package/dist/runtime/themeIcons.d.ts +130 -0
- package/dist/runtime/themeIcons.js +271 -0
- package/dist/runtime/themeIcons.js.map +1 -0
- package/dist/runtime/themeInk.d.ts +37 -0
- package/dist/runtime/themeInk.js +111 -0
- package/dist/runtime/themeInk.js.map +1 -0
- package/dist/runtime/themeInvariants.d.ts +39 -0
- package/dist/runtime/themeInvariants.js +273 -0
- package/dist/runtime/themeInvariants.js.map +1 -0
- package/dist/runtime/themeRuntime.d.ts +114 -0
- package/dist/runtime/themeRuntime.js +570 -0
- package/dist/runtime/themeRuntime.js.map +1 -0
- package/dist/runtime/themeSchema.d.ts +10 -0
- package/dist/runtime/themeSchema.js +150 -0
- package/dist/runtime/themeSchema.js.map +1 -0
- package/dist/runtime/themeSpec.d.ts +263 -0
- package/dist/runtime/themeSpec.js +435 -0
- package/dist/runtime/themeSpec.js.map +1 -0
- package/dist/runtime/themeTokens.d.ts +12 -0
- package/dist/runtime/themeTokens.js +14 -6
- package/dist/runtime/themeTokens.js.map +1 -1
- package/dist/runtime/themeVariants.d.ts +30 -0
- package/dist/runtime/themeVariants.js +53 -0
- package/dist/runtime/themeVariants.js.map +1 -0
- package/dist/runtime/ui.d.ts +192 -0
- package/dist/runtime/ui.js +926 -0
- package/dist/runtime/ui.js.map +1 -0
- package/dist/shell/InstallDialog.d.ts +40 -0
- package/dist/shell/InstallDialog.js +176 -0
- package/dist/shell/InstallDialog.js.map +1 -0
- package/dist/shell/StoreView.d.ts +78 -0
- package/dist/shell/StoreView.js +108 -0
- package/dist/shell/StoreView.js.map +1 -0
- package/dist/shell/addressModel.js.map +1 -1
- package/dist/shell/chrome.js.map +1 -1
- package/dist/shell/deckModel.d.ts +117 -0
- package/dist/shell/deckModel.js +267 -0
- package/dist/shell/deckModel.js.map +1 -0
- package/dist/shell/frame/AccountSwitcher.d.ts +42 -0
- package/dist/shell/frame/AccountSwitcher.js +243 -0
- package/dist/shell/frame/AccountSwitcher.js.map +1 -0
- package/dist/shell/frame/AddColumnDialog.d.ts +8 -0
- package/dist/shell/frame/AddColumnDialog.js +81 -0
- package/dist/shell/frame/AddColumnDialog.js.map +1 -0
- package/dist/shell/frame/AppMenu.d.ts +44 -0
- package/dist/shell/frame/AppMenu.js +721 -0
- package/dist/shell/frame/AppMenu.js.map +1 -0
- package/dist/shell/frame/CommandPalette.d.ts +7 -0
- package/dist/shell/frame/CommandPalette.js +118 -0
- package/dist/shell/frame/CommandPalette.js.map +1 -0
- package/dist/shell/frame/DeckView.d.ts +13 -0
- package/dist/shell/frame/DeckView.js +287 -0
- package/dist/shell/frame/DeckView.js.map +1 -0
- package/dist/shell/frame/FindBar.d.ts +10 -0
- package/dist/shell/frame/FindBar.js +108 -0
- package/dist/shell/frame/FindBar.js.map +1 -0
- package/dist/shell/frame/MediaPanel.d.ts +8 -0
- package/dist/shell/frame/MediaPanel.js +76 -0
- package/dist/shell/frame/MediaPanel.js.map +1 -0
- package/dist/shell/frame/NewTabPage.d.ts +9 -0
- package/dist/shell/frame/NewTabPage.js +71 -0
- package/dist/shell/frame/NewTabPage.js.map +1 -0
- package/dist/shell/frame/PaneTheme.d.ts +16 -0
- package/dist/shell/frame/PaneTheme.js +67 -0
- package/dist/shell/frame/PaneTheme.js.map +1 -0
- package/dist/shell/frame/ReportDialog.d.ts +3 -0
- package/dist/shell/frame/ReportDialog.js +95 -0
- package/dist/shell/frame/ReportDialog.js.map +1 -0
- package/dist/shell/frame/Shell.d.ts +9 -0
- package/dist/shell/frame/Shell.js +1139 -0
- package/dist/shell/frame/Shell.js.map +1 -0
- package/dist/shell/frame/Titlebar.d.ts +17 -0
- package/dist/shell/frame/Titlebar.js +79 -0
- package/dist/shell/frame/Titlebar.js.map +1 -0
- package/dist/shell/frame/TitlebarExtras.d.ts +4 -0
- package/dist/shell/frame/TitlebarExtras.js +202 -0
- package/dist/shell/frame/TitlebarExtras.js.map +1 -0
- package/dist/shell/frame/WebPanel.d.ts +4 -0
- package/dist/shell/frame/WebPanel.js +185 -0
- package/dist/shell/frame/WebPanel.js.map +1 -0
- package/dist/shell/frame/accountModel.d.ts +49 -0
- package/dist/shell/frame/accountModel.js +67 -0
- package/dist/shell/frame/accountModel.js.map +1 -0
- package/dist/shell/frame/accountSwitcher.css +91 -0
- package/dist/shell/frame/appI18n.d.ts +44 -0
- package/dist/shell/frame/appI18n.js +64 -0
- package/dist/shell/frame/appI18n.js.map +1 -0
- package/dist/shell/frame/appMenu.css +127 -0
- package/dist/shell/frame/backupModel.d.ts +38 -0
- package/dist/shell/frame/backupModel.js +192 -0
- package/dist/shell/frame/backupModel.js.map +1 -0
- package/dist/shell/frame/boot.d.ts +8 -0
- package/dist/shell/frame/boot.js +37 -0
- package/dist/shell/frame/boot.js.map +1 -0
- package/dist/shell/frame/brand.d.ts +1 -0
- package/dist/shell/frame/brand.js +4 -0
- package/dist/shell/frame/brand.js.map +1 -0
- package/dist/shell/frame/bridge.d.ts +35 -0
- package/dist/shell/frame/bridge.js +70 -0
- package/dist/shell/frame/bridge.js.map +1 -0
- package/dist/shell/frame/chromeTheme.d.ts +47 -0
- package/dist/shell/frame/chromeTheme.js +118 -0
- package/dist/shell/frame/chromeTheme.js.map +1 -0
- package/dist/shell/frame/deck.css +209 -0
- package/dist/shell/frame/deckStore.d.ts +89 -0
- package/dist/shell/frame/deckStore.js +239 -0
- package/dist/shell/frame/deckStore.js.map +1 -0
- package/dist/shell/frame/devHost.d.ts +35 -0
- package/dist/shell/frame/devHost.js +80 -0
- package/dist/shell/frame/devHost.js.map +1 -0
- package/dist/shell/frame/devModel.d.ts +7 -0
- package/dist/shell/frame/devModel.js +17 -0
- package/dist/shell/frame/devModel.js.map +1 -0
- package/dist/shell/frame/diag.d.ts +7 -0
- package/dist/shell/frame/diag.js +39 -0
- package/dist/shell/frame/diag.js.map +1 -0
- package/dist/shell/frame/edges.css +159 -0
- package/dist/shell/frame/findBar.css +14 -0
- package/dist/shell/frame/frameMessages.d.ts +248 -0
- package/dist/shell/frame/frameMessages.js +252 -0
- package/dist/shell/frame/frameMessages.js.map +1 -0
- package/dist/shell/frame/hooks.d.ts +39 -0
- package/dist/shell/frame/hooks.js +97 -0
- package/dist/shell/frame/hooks.js.map +1 -0
- package/dist/shell/frame/i18n.d.ts +27 -0
- package/dist/shell/frame/i18n.js +66 -0
- package/dist/shell/frame/i18n.js.map +1 -0
- package/dist/shell/frame/iconPack.d.ts +11 -0
- package/dist/shell/frame/iconPack.js +45 -0
- package/dist/shell/frame/iconPack.js.map +1 -0
- package/dist/shell/frame/icons.d.ts +71 -0
- package/dist/shell/frame/icons.js +75 -0
- package/dist/shell/frame/icons.js.map +1 -0
- package/dist/shell/frame/index.d.ts +34 -0
- package/dist/shell/frame/index.js +43 -0
- package/dist/shell/frame/index.js.map +1 -0
- package/dist/shell/frame/language.d.ts +58 -0
- package/dist/shell/frame/language.js +165 -0
- package/dist/shell/frame/language.js.map +1 -0
- package/dist/shell/frame/mediaModel.d.ts +47 -0
- package/dist/shell/frame/mediaModel.js +67 -0
- package/dist/shell/frame/mediaModel.js.map +1 -0
- package/dist/shell/frame/menuMessages.en.json +96 -0
- package/dist/shell/frame/menuModel.d.ts +319 -0
- package/dist/shell/frame/menuModel.js +301 -0
- package/dist/shell/frame/menuModel.js.map +1 -0
- package/dist/shell/frame/nativeMenu.d.ts +5 -0
- package/dist/shell/frame/nativeMenu.js +178 -0
- package/dist/shell/frame/nativeMenu.js.map +1 -0
- package/dist/shell/frame/nativeMenuModel.d.ts +102 -0
- package/dist/shell/frame/nativeMenuModel.js +186 -0
- package/dist/shell/frame/nativeMenuModel.js.map +1 -0
- package/dist/shell/frame/paletteModel.d.ts +139 -0
- package/dist/shell/frame/paletteModel.js +114 -0
- package/dist/shell/frame/paletteModel.js.map +1 -0
- package/dist/shell/frame/paneTheme.css +9 -0
- package/dist/shell/frame/pluginCommandStore.d.ts +23 -0
- package/dist/shell/frame/pluginCommandStore.js +70 -0
- package/dist/shell/frame/pluginCommandStore.js.map +1 -0
- package/dist/shell/frame/reportModel.d.ts +52 -0
- package/dist/shell/frame/reportModel.js +105 -0
- package/dist/shell/frame/reportModel.js.map +1 -0
- package/dist/shell/frame/safeStore.d.ts +7 -0
- package/dist/shell/frame/safeStore.js +40 -0
- package/dist/shell/frame/safeStore.js.map +1 -0
- package/dist/shell/frame/searchInput.d.ts +2 -0
- package/dist/shell/frame/searchInput.js +11 -0
- package/dist/shell/frame/searchInput.js.map +1 -0
- package/dist/shell/frame/shell.css +634 -0
- package/dist/shell/frame/site.d.ts +206 -0
- package/dist/shell/frame/site.js +22 -0
- package/dist/shell/frame/site.js.map +1 -0
- package/dist/shell/frame/state.d.ts +101 -0
- package/dist/shell/frame/state.js +286 -0
- package/dist/shell/frame/state.js.map +1 -0
- package/dist/shell/frame/syncGate.d.ts +10 -0
- package/dist/shell/frame/syncGate.js +36 -0
- package/dist/shell/frame/syncGate.js.map +1 -0
- package/dist/shell/frame/syncHost.d.ts +35 -0
- package/dist/shell/frame/syncHost.js +85 -0
- package/dist/shell/frame/syncHost.js.map +1 -0
- package/dist/shell/frame/tabStill.d.ts +2 -0
- package/dist/shell/frame/tabStill.js +62 -0
- package/dist/shell/frame/tabStill.js.map +1 -0
- package/dist/shell/frame/themeScopes.d.ts +29 -0
- package/dist/shell/frame/themeScopes.js +61 -0
- package/dist/shell/frame/themeScopes.js.map +1 -0
- package/dist/shell/frame/themeStore.d.ts +99 -0
- package/dist/shell/frame/themeStore.js +267 -0
- package/dist/shell/frame/themeStore.js.map +1 -0
- package/dist/shell/frame/windowBinding.d.ts +2 -0
- package/dist/shell/frame/windowBinding.js +7 -0
- package/dist/shell/frame/windowBinding.js.map +1 -0
- package/dist/shell/frame/workspaceModel.d.ts +82 -0
- package/dist/shell/frame/workspaceModel.js +250 -0
- package/dist/shell/frame/workspaceModel.js.map +1 -0
- package/dist/shell/frame/workspaces.css +84 -0
- package/dist/shell/frame/workspaces.d.ts +22 -0
- package/dist/shell/frame/workspaces.js +125 -0
- package/dist/shell/frame/workspaces.js.map +1 -0
- package/dist/shell/frame/zoomStore.d.ts +10 -0
- package/dist/shell/frame/zoomStore.js +65 -0
- package/dist/shell/frame/zoomStore.js.map +1 -0
- package/dist/shell/installController.d.ts +137 -0
- package/dist/shell/installController.js +172 -0
- package/dist/shell/installController.js.map +1 -0
- package/dist/shell/installerMessages.d.ts +30 -0
- package/dist/shell/installerMessages.js +36 -0
- package/dist/shell/installerMessages.js.map +1 -0
- package/dist/shell/linkDrop.js.map +1 -1
- package/dist/shell/messages.d.ts +16 -0
- package/dist/shell/messages.js +27 -0
- package/dist/shell/messages.js.map +1 -0
- package/dist/shell/palette.js.map +1 -1
- package/dist/shell/paneModel.d.ts +22 -0
- package/dist/shell/paneModel.js +24 -1
- package/dist/shell/paneModel.js.map +1 -1
- package/dist/shell/panel/Appearance.d.ts +8 -0
- package/dist/shell/panel/Appearance.js +265 -0
- package/dist/shell/panel/Appearance.js.map +1 -0
- package/dist/shell/panel/BackupPanel.d.ts +5 -0
- package/dist/shell/panel/BackupPanel.js +198 -0
- package/dist/shell/panel/BackupPanel.js.map +1 -0
- package/dist/shell/panel/DeveloperPanel.d.ts +4 -0
- package/dist/shell/panel/DeveloperPanel.js +51 -0
- package/dist/shell/panel/DeveloperPanel.js.map +1 -0
- package/dist/shell/panel/FeatureToggles.d.ts +13 -0
- package/dist/shell/panel/FeatureToggles.js +42 -0
- package/dist/shell/panel/FeatureToggles.js.map +1 -0
- package/dist/shell/panel/Home.d.ts +3 -0
- package/dist/shell/panel/Home.js +23 -0
- package/dist/shell/panel/Home.js.map +1 -0
- package/dist/shell/panel/IconPackInstall.d.ts +15 -0
- package/dist/shell/panel/IconPackInstall.js +41 -0
- package/dist/shell/panel/IconPackInstall.js.map +1 -0
- package/dist/shell/panel/LanguageSettings.d.ts +1 -0
- package/dist/shell/panel/LanguageSettings.js +54 -0
- package/dist/shell/panel/LanguageSettings.js.map +1 -0
- package/dist/shell/panel/MakePanel.d.ts +3 -0
- package/dist/shell/panel/MakePanel.js +237 -0
- package/dist/shell/panel/MakePanel.js.map +1 -0
- package/dist/shell/panel/MarkdownDoc.d.ts +6 -0
- package/dist/shell/panel/MarkdownDoc.js +35 -0
- package/dist/shell/panel/MarkdownDoc.js.map +1 -0
- package/dist/shell/panel/Modes.d.ts +40 -0
- package/dist/shell/panel/Modes.js +270 -0
- package/dist/shell/panel/Modes.js.map +1 -0
- package/dist/shell/panel/NavIcon.d.ts +4 -0
- package/dist/shell/panel/NavIcon.js +6 -0
- package/dist/shell/panel/NavIcon.js.map +1 -0
- package/dist/shell/panel/Panel.d.ts +7 -0
- package/dist/shell/panel/Panel.js +139 -0
- package/dist/shell/panel/Panel.js.map +1 -0
- package/dist/shell/panel/PluginFeatures.d.ts +24 -0
- package/dist/shell/panel/PluginFeatures.js +165 -0
- package/dist/shell/panel/PluginFeatures.js.map +1 -0
- package/dist/shell/panel/Plugins.d.ts +33 -0
- package/dist/shell/panel/Plugins.js +112 -0
- package/dist/shell/panel/Plugins.js.map +1 -0
- package/dist/shell/panel/PowerSettings.d.ts +4 -0
- package/dist/shell/panel/PowerSettings.js +52 -0
- package/dist/shell/panel/PowerSettings.js.map +1 -0
- package/dist/shell/panel/Settings.d.ts +23 -0
- package/dist/shell/panel/Settings.js +117 -0
- package/dist/shell/panel/Settings.js.map +1 -0
- package/dist/shell/panel/ShareSetup.d.ts +8 -0
- package/dist/shell/panel/ShareSetup.js +130 -0
- package/dist/shell/panel/ShareSetup.js.map +1 -0
- package/dist/shell/panel/StoreSection.d.ts +7 -0
- package/dist/shell/panel/StoreSection.js +78 -0
- package/dist/shell/panel/StoreSection.js.map +1 -0
- package/dist/shell/panel/StringPacks.d.ts +20 -0
- package/dist/shell/panel/StringPacks.js +131 -0
- package/dist/shell/panel/StringPacks.js.map +1 -0
- package/dist/shell/panel/ThemeBuilder.d.ts +5 -0
- package/dist/shell/panel/ThemeBuilder.js +205 -0
- package/dist/shell/panel/ThemeBuilder.js.map +1 -0
- package/dist/shell/panel/backup.css +34 -0
- package/dist/shell/panel/builder.css +240 -0
- package/dist/shell/panel/builderModel.d.ts +55 -0
- package/dist/shell/panel/builderModel.js +95 -0
- package/dist/shell/panel/builderModel.js.map +1 -0
- package/dist/shell/panel/compare.d.ts +10 -0
- package/dist/shell/panel/compare.js +51 -0
- package/dist/shell/panel/compare.js.map +1 -0
- package/dist/shell/panel/controls.d.ts +135 -0
- package/dist/shell/panel/controls.js +213 -0
- package/dist/shell/panel/controls.js.map +1 -0
- package/dist/shell/panel/featureModel.d.ts +69 -0
- package/dist/shell/panel/featureModel.js +79 -0
- package/dist/shell/panel/featureModel.js.map +1 -0
- package/dist/shell/panel/fonts/FontBrowser.d.ts +10 -0
- package/dist/shell/panel/fonts/FontBrowser.js +189 -0
- package/dist/shell/panel/fonts/FontBrowser.js.map +1 -0
- package/dist/shell/panel/fonts/FontRoles.d.ts +20 -0
- package/dist/shell/panel/fonts/FontRoles.js +77 -0
- package/dist/shell/panel/fonts/FontRoles.js.map +1 -0
- package/dist/shell/panel/fonts/catalog.d.ts +37 -0
- package/dist/shell/panel/fonts/catalog.js +68 -0
- package/dist/shell/panel/fonts/catalog.js.map +1 -0
- package/dist/shell/panel/fonts/googleFontsCatalog.json +1 -0
- package/dist/shell/panel/index.d.ts +20 -0
- package/dist/shell/panel/index.js +34 -0
- package/dist/shell/panel/index.js.map +1 -0
- package/dist/shell/panel/languageModel.d.ts +5 -0
- package/dist/shell/panel/languageModel.js +7 -0
- package/dist/shell/panel/languageModel.js.map +1 -0
- package/dist/shell/panel/make.css +73 -0
- package/dist/shell/panel/makeModel.d.ts +32 -0
- package/dist/shell/panel/makeModel.js +84 -0
- package/dist/shell/panel/makeModel.js.map +1 -0
- package/dist/shell/panel/markdown.d.ts +46 -0
- package/dist/shell/panel/markdown.js +100 -0
- package/dist/shell/panel/markdown.js.map +1 -0
- package/dist/shell/panel/nav.d.ts +12 -0
- package/dist/shell/panel/nav.js +50 -0
- package/dist/shell/panel/nav.js.map +1 -0
- package/dist/shell/panel/panel.css +401 -0
- package/dist/shell/panel/panelMessages.d.ts +803 -0
- package/dist/shell/panel/panelMessages.js +779 -0
- package/dist/shell/panel/panelMessages.js.map +1 -0
- package/dist/shell/panel/plugins.css +59 -0
- package/dist/shell/panel/setupModel.d.ts +87 -0
- package/dist/shell/panel/setupModel.js +152 -0
- package/dist/shell/panel/setupModel.js.map +1 -0
- package/dist/shell/panel/site.d.ts +259 -0
- package/dist/shell/panel/site.js +25 -0
- package/dist/shell/panel/site.js.map +1 -0
- package/dist/shell/panel/strings.css +7 -0
- package/dist/shell/panel/themes.d.ts +10 -0
- package/dist/shell/panel/themes.js +8 -0
- package/dist/shell/panel/themes.js.map +1 -0
- package/dist/shell/profileModel.d.ts +3 -2
- package/dist/shell/profileModel.js +7 -5
- package/dist/shell/profileModel.js.map +1 -1
- package/dist/shell/store.css +250 -0
- package/dist/shell/storeMessages.d.ts +193 -0
- package/dist/shell/storeMessages.js +196 -0
- package/dist/shell/storeMessages.js.map +1 -0
- package/dist/shell/storeModel.d.ts +205 -0
- package/dist/shell/storeModel.js +146 -0
- package/dist/shell/storeModel.js.map +1 -0
- package/dist/shell/stringPacksModel.d.ts +44 -0
- package/dist/shell/stringPacksModel.js +99 -0
- package/dist/shell/stringPacksModel.js.map +1 -0
- package/dist/shell/updateModel.d.ts +2 -1
- package/dist/shell/updateModel.js +5 -4
- package/dist/shell/updateModel.js.map +1 -1
- package/dist/shell/windowControls.d.ts +4 -0
- package/dist/shell/windowControls.js +5 -0
- package/dist/shell/windowControls.js.map +1 -1
- package/i18n-config.schema.json +29 -0
- package/i18n-meta.schema.json +26 -0
- package/i18n.schema.json +42 -0
- package/icons.schema.json +655 -0
- package/languages.schema.json +23 -0
- package/locales/ar-x-fm.json +11 -0
- package/locales/ar.json +1388 -0
- package/locales/bg.json +1387 -0
- package/locales/bn.json +1387 -0
- package/locales/ca.json +1387 -0
- package/locales/cs.json +1387 -0
- package/locales/da.json +1387 -0
- package/locales/de.json +1387 -0
- package/locales/el.json +1387 -0
- package/locales/en-GB.json +27 -0
- package/locales/en.json +1386 -0
- package/locales/en.meta.json +51 -0
- package/locales/es.json +1387 -0
- package/locales/eu.json +1387 -0
- package/locales/fa.json +1388 -0
- package/locales/fi.json +1387 -0
- package/locales/fil.json +1387 -0
- package/locales/fr.json +1387 -0
- package/locales/ga.json +1387 -0
- package/locales/gl.json +1387 -0
- package/locales/gu.json +1387 -0
- package/locales/ha.json +1387 -0
- package/locales/he.json +1388 -0
- package/locales/hi.json +1387 -0
- package/locales/hr.json +1387 -0
- package/locales/hu.json +1387 -0
- package/locales/id.json +1387 -0
- package/locales/ig.json +1387 -0
- package/locales/it.json +1387 -0
- package/locales/ja.json +1387 -0
- package/locales/kn.json +1387 -0
- package/locales/ko.json +1387 -0
- package/locales/mr.json +1387 -0
- package/locales/ms.json +1387 -0
- package/locales/nb.json +1387 -0
- package/locales/nl.json +1387 -0
- package/locales/pl.json +1387 -0
- package/locales/pt.json +1387 -0
- package/locales/ro.json +1387 -0
- package/locales/ru.json +1387 -0
- package/locales/sk.json +1387 -0
- package/locales/sr.json +1387 -0
- package/locales/sv.json +1387 -0
- package/locales/ta.json +1387 -0
- package/locales/th.json +1387 -0
- package/locales/tr.json +1387 -0
- package/locales/uk.json +1387 -0
- package/locales/ur.json +1388 -0
- package/locales/vi.json +1387 -0
- package/locales/yo.json +1387 -0
- package/locales/zh-Hans.json +1387 -0
- package/locales/zh-Hant.json +1387 -0
- package/package.json +138 -5
- package/store-catalog.schema.json +78 -0
- package/theme.schema.json +4668 -0
- package/windows/installer.nsi +946 -0
- package/windows/languages/Basque.nsh +28 -0
- package/windows/languages/Catalan.nsh +28 -0
- package/windows/languages/Croatian.nsh +28 -0
- package/windows/languages/Czech.nsh +28 -0
- package/windows/languages/Danish.nsh +28 -0
- package/windows/languages/Finnish.nsh +28 -0
- package/windows/languages/Galician.nsh +28 -0
- package/windows/languages/Greek.nsh +28 -0
- package/windows/languages/Hungarian.nsh +28 -0
- package/windows/languages/Indonesian.nsh +28 -0
- package/windows/languages/Irish.nsh +28 -0
- package/windows/languages/Malay.nsh +28 -0
- package/windows/languages/Polish.nsh +28 -0
- package/windows/languages/Romanian.nsh +28 -0
- package/windows/languages/Serbian.nsh +28 -0
- package/windows/languages/Slovak.nsh +28 -0
- package/windows/languages/Thai.nsh +28 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stringPacks.js","sourceRoot":"","sources":["../../../runtime/src/stringPacks.ts"],"names":[],"mappings":"AAAA,6FAA6F;AAC7F,8FAA8F;AAC9F,6FAA6F;AAC7F,kGAAkG;AAClG,mFAAmF;AACnF,EAAE;AACF,wEAAwE;AACxE,iGAAiG;AACjG,4FAA4F;AAC5F,kGAAkG;AAClG,mCAAmC;AACnC,gGAAgG;AAChG,kFAAkF;AAClF,+FAA+F;AAC/F,uFAAuF;AACvF,EAAE;AACF,+FAA+F;AAC/F,0DAA0D;AAC1D,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AAqFzC,MAAM,CAAC,MAAM,kBAAkB,GAAG,MAAM,CAAC,MAAM,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC,CAAC;AACxG,MAAM,CAAC,MAAM,UAAU,GAAG,MAAM,CAAC;AAEjC,MAAM,GAAG,GAAG,uCAAuC,CAAC;AACpD,MAAM,KAAK,GAAG,wBAAwB,CAAC;AACvC,MAAM,OAAO,GAAG,sDAAsD,CAAC;AACvE,MAAM,YAAY,GAAG,uBAAuB,CAAC;AAC7C,MAAM,UAAU,GAAG,sCAAsC,CAAC;AAC1D,MAAM,YAAY,GAAG,EAAE,CAAC;AACxB,MAAM,UAAU,GAAG,IAAI,GAAG,CAAC,CAAC,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;AAE3E,8GAA8G;AAC9G,MAAM,UAAU,YAAY,CAAC,IAAqD;IAChF,MAAM,EAAE,IAAI,EAAE,CAAC,EAAE,KAAK,EAAE,GAAG,OAAO,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;IACxF,OAAO,CAAC,KAAK,MAAM,IAAI,CAAC,KAAK,SAAS,IAAI,CAAC,CAAC,KAAK,MAAM,IAAI,KAAK,KAAK,SAAS,CAAC,CAAC;AAClF,CAAC;AAED,iEAAiE;AACjE,MAAM,UAAU,cAAc,CAAC,IAA+B,EAAE,QAA4B;IAC1F,IAAI,CAAC,IAAI,EAAE,SAAS;QAAE,OAAO,IAAI,CAAC;IAClC,IAAI,CAAC,QAAQ;QAAE,OAAO,KAAK,CAAC;IAC5B,MAAM,IAAI,GAAG,QAAQ,CAAC,WAAW,EAAE,CAAC;IACpC,OAAO,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,GAAG,MAAM,IAAI,GAAG,GAAG,CAAC,WAAW,EAAE,CAAC,CAAC,OAAO,IAAI,KAAK,IAAI,IAAI,IAAI,CAAC,UAAU,CAAC,GAAG,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAC9H,CAAC;AAED,oFAAoF;AACpF,MAAM,UAAU,QAAQ,CAAC,IAAY;IACnC,IAAI,EAAE,GAAG,UAAU,CAAC;IACpB,IAAI,EAAE,GAAG,UAAU,CAAC;IACpB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC;QACxC,MAAM,EAAE,GAAG,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;QAC9B,EAAE,GAAG,IAAI,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,EAAE,UAAU,CAAC,CAAC;QACpC,EAAE,GAAG,IAAI,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,EAAE,UAAU,CAAC,CAAC;IACtC,CAAC;IACD,EAAE,GAAG,IAAI,CAAC,IAAI,CAAC,EAAE,GAAG,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,UAAU,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,EAAE,GAAG,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,UAAU,CAAC,CAAC;IACvF,EAAE,GAAG,IAAI,CAAC,IAAI,CAAC,EAAE,GAAG,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,UAAU,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,EAAE,GAAG,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,UAAU,CAAC,CAAC;IACvF,OAAO,CAAC,UAAU,GAAG,CAAC,OAAO,GAAG,EAAE,CAAC,GAAG,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,EAAE,EAAE,GAAG,CAAC,CAAC;AACnF,CAAC;AA0BD,SAAS,OAAO,CAAC,IAAY,EAAE,OAAe,EAAE,MAAsC;IACpF,MAAM,IAAI,GAAa,EAAE,CAAC;IAC1B,MAAM,MAAM,GAAa,EAAE,CAAC;IAC5B,MAAM,OAAO,GAA2B,EAAE,CAAC;IAC3C,MAAM,IAAI,GAA2B,EAAE,CAAC;IACxC,KAAK,MAAM,CAAC,EAAE,EAAE,KAAK,CAAC,IAAI,MAAM,EAAE,CAAC;QACjC,IAAI,KAAK,CAAC,IAAI,KAAK,MAAM,IAAI,KAAK,CAAC,KAAK,KAAK,SAAS,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,MAAM;YAAE,IAAI,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,KAAK,CAAC;aACjG,IAAI,KAAK,CAAC,IAAI,KAAK,MAAM,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,MAAM;YAAE,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;aAChE,IAAI,KAAK,CAAC,IAAI,KAAK,SAAS,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,MAAM,EAAE,CAAC;YACzD,OAAO,CAAC,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,IAAI,GAAG,KAAK,CAAC,MAAM,EAAE,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,GAAG,KAAK,CAAC,MAAM,EAAE,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAC1J,CAAC;;YAAM,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACzB,CAAC;IACD,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC;AACnI,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,SAA0B;IACtD,OAAO,OAAO,CAAC,SAAS,CAAC,IAAI,EAAE,SAAS,CAAC,OAAO,EAAE,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC;AACvF,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,cAAc,CAAC,SAA0C,EAAE,GAAqB;IAC9F,MAAM,MAAM,GAAG,eAAe,CAAC,SAAS,CAAC,CAAC;IAC1C,MAAM,MAAM,GAA2B,EAAE,CAAC;IAC1C,KAAK,MAAM,EAAE,IAAI,IAAI,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;QAC9B,MAAM,KAAK,GAAG,MAAM,CAAC,EAAE,CAAC,CAAC;QACzB,IAAI,KAAK;YAAE,MAAM,CAAC,IAAI,CAAC,CAAC,EAAE,EAAE,KAAK,CAAC,CAAC,CAAC;IACtC,CAAC;IACD,OAAO,EAAE,GAAG,OAAO,CAAC,SAAS,CAAC,IAAI,EAAE,SAAS,CAAC,OAAO,EAAE,MAAM,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;AAClF,CAAC;AAED,+FAA+F;AAC/F,MAAM,UAAU,eAAe,CAAC,KAAc;IAC5C,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC;IACnC,MAAM,GAAG,GAAG,CAAC,KAAc,EAAE,EAAE,CAAC,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,MAAM,IAAI,SAAS,IAAI,aAAa,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACpH,OAAO,OAAO,KAAK,CAAC,IAAI,KAAK,QAAQ,IAAI,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,OAAO,KAAK,CAAC,OAAO,KAAK,QAAQ,IAAI,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC;WAC5H,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,QAAQ,CAAC,KAAK,CAAC,OAAO,CAAC;WAC/D,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,aAAa,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;WACrI,CAAC,KAAK,CAAC,IAAI,KAAK,SAAS,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,IAAK,CAAY,IAAI,CAAC,IAAK,CAAY,IAAI,EAAE,CAAC,CAAC,CAAC;WAChM,CAAC,KAAK,CAAC,OAAO,KAAK,SAAS,IAAI,OAAO,KAAK,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC;AAC3E,CAAC;AAED,MAAM,UAAU,GAAe,MAAM,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC;AAC/D,MAAM,YAAY,GAAe,MAAM,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC;AAEjE,wEAAwE;AACxE,MAAM,UAAU,eAAe,CAAC,SAA0C;IACxE,IAAI,SAAS,IAAI,SAAS,EAAE,CAAC;QAC3B,MAAM,OAAO,GAAG,SAAS,CAAC,OAAO,CAAC;QAClC,OAAO,EAAE,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,cAAc,CAAC,IAAI,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;IAC7F,CAAC;IACD,IAAI,KAAK,GAAmC,IAAI,CAAC;IACjD,MAAM,MAAM,GAAG,GAAG,EAAE;QAClB,MAAM,GAAG,GAAG,IAAI,GAAG,EAAsB,CAAC;QAC1C,IAAI,SAAS,CAAC,IAAI;YAAE,KAAK,MAAM,EAAE,IAAI,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC;gBAAE,GAAG,CAAC,GAAG,CAAC,EAAE,EAAE,UAAU,CAAC,CAAC;QACxF,IAAI,SAAS,CAAC,MAAM;YAAE,KAAK,MAAM,EAAE,IAAI,SAAS,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC;gBAAE,GAAG,CAAC,GAAG,CAAC,EAAE,EAAE,YAAY,CAAC,CAAC;QAC9F,IAAI,SAAS,CAAC,IAAI;YAAE,KAAK,MAAM,CAAC,EAAE,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,IAAI,CAAC;gBAAE,GAAG,CAAC,GAAG,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC;QACnH,KAAK,MAAM,CAAC,EAAE,EAAE,IAAI,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,OAAO,CAAC,EAAE,CAAC;YAC3D,MAAM,KAAK,GAAG,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;YAC1C,GAAG,CAAC,GAAG,CAAC,EAAE,EAAE;gBACV,IAAI,EAAE,SAAS;gBACf,MAAM,EAAE,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;gBACrD,MAAM,EAAE,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;gBACxF,MAAM,EAAE,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;aACzF,CAAC,CAAC;QACL,CAAC;QACD,OAAO,GAAG,CAAC;IACb,CAAC,CAAC;IACF,OAAO,EAAE,CAAC,EAAE,CAAC,CAAC,KAAK,KAAK,MAAM,EAAE,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;AAC5C,CAAC;AAOD,MAAM,QAAQ,GAAG,CAAC,KAAc,EAAoC,EAAE,CAAC,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;AAE5I,gFAAgF;AAChF,MAAM,UAAU,cAAc,CAAC,KAAc;IAC3C,MAAM,MAAM,GAAgB,EAAE,CAAC;IAC/B,MAAM,KAAK,GAAG,CAAC,OAAe,EAAE,EAAE,GAAG,MAAM,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;IACjF,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC;QAAE,OAAO,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,gCAAgC,EAAE,CAAC,CAAC;IAC7F,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;QAAE,KAAK,CAAC,oBAAoB,CAAC,CAAC;IACpD,KAAK,MAAM,KAAK,IAAI,CAAC,MAAM,EAAE,SAAS,CAAU,EAAE,CAAC;QACjD,IAAI,OAAO,KAAK,CAAC,KAAK,CAAC,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;YAAE,KAAK,CAAC,IAAI,KAAK,gCAAgC,CAAC,CAAC;IACtH,CAAC;IACD,IAAI,OAAO,KAAK,CAAC,QAAQ,KAAK,QAAQ,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC;QAAE,KAAK,CAAC,4DAA4D,CAAC,CAAC;IACzI,IAAI,KAAK,CAAC,IAAI,KAAK,SAAS,IAAI,CAAC,OAAO,KAAK,CAAC,IAAI,KAAK,QAAQ,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAAE,KAAK,CAAC,+BAA+B,CAAC,CAAC;IAClI,IAAI,OAAO,KAAK,CAAC,IAAI,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,KAAK,CAAC,IAAI,CAAC,MAAM,GAAG,kBAAkB,CAAC,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;QAC/J,KAAK,CAAC,uBAAuB,kBAAkB,CAAC,IAAI,2BAA2B,CAAC,CAAC;IACnF,CAAC;IACD,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,GAAG,kBAAkB,CAAC,OAAO;WACjF,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,OAAO,MAAM,KAAK,QAAQ,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,IAAI,MAAM,CAAC,MAAM,GAAG,kBAAkB,CAAC,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC;QAC1K,KAAK,CAAC,uCAAuC,kBAAkB,CAAC,OAAO,mBAAmB,CAAC,CAAC;IAC9F,CAAC;IACD,IAAI,KAAK,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;QAC7B,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC;QACxB,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,WAAW,CAAC;YAAE,KAAK,CAAC,sCAAsC,CAAC,CAAC;aACpH,IAAI,IAAI,CAAC,SAAS,KAAK,SAAS,IAAI,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,IAAI,IAAI,CAAC,SAAS,CAAC,MAAM,GAAG,EAAE;eAC3H,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,OAAO,GAAG,KAAK,QAAQ,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;YAAE,KAAK,CAAC,0DAA0D,CAAC,CAAC;IACjJ,CAAC;IACD,IAAI,KAAK,CAAC,OAAO,KAAK,SAAS,EAAE,CAAC;QAChC,MAAM,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC;QAC9B,MAAM,KAAK,GAAG,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC;QAC5D,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,MAAM,IAAI,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,MAAM,GAAG,YAAY;eACpK,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,OAAO,EAAE,KAAK,QAAQ,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC;YAC5H,KAAK,CAAC,iEAAiE,YAAY,cAAc,CAAC,CAAC;QACrG,CAAC;IACH,CAAC;IACD,KAAK,MAAM,KAAK,IAAI,CAAC,SAAS,EAAE,aAAa,CAAU,EAAE,CAAC;QACxD,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC;QAC3B,IAAI,KAAK,KAAK,SAAS,IAAI,CAAC,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,MAAM,GAAG,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YAAE,KAAK,CAAC,IAAI,KAAK,sBAAsB,CAAC,CAAC;IACpK,CAAC;IACD,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,OAAO,CAAC;QAAE,KAAK,CAAC,+CAA+C,CAAC,CAAC;SAChF,IAAI,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,MAAM,GAAG,kBAAkB,CAAC,OAAO;QAAE,KAAK,CAAC,2BAA2B,kBAAkB,CAAC,OAAO,UAAU,CAAC,CAAC;IAChJ,MAAM,KAAK,GAAG,IAAI,GAAG,CAAC,CAAC,SAAS,EAAE,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,SAAS,EAAE,aAAa,EAAE,SAAS,CAAC,CAAC,CAAC;IAC/J,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC;QAAE,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC;YAAE,MAAM,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,SAAS,EAAE,OAAO,EAAE,kBAAkB,GAAG,cAAc,EAAE,CAAC,CAAC;IAC3I,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,MAAM,SAAS,GAAG,+BAA+B,CAAC;AAElD,wGAAwG;AACxG,SAAS,SAAS,CAAC,KAAa,EAAE,IAAuB;IACvD,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;QACjD,OAAO,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,oCAAoC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,GAAG,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;IAC1G,CAAC;IACD,IAAI,CAAC,IAAI,CAAC,MAAM;QAAE,OAAO,+DAA+D,CAAC;IACzF,MAAM,IAAI,GAAa,EAAE,CAAC;IAC1B,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;IAC/B,KAAK,MAAM,KAAK,IAAI,KAAK,CAAC,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC;QAC9C,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAE,CAAC;QACvB,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC;YAAE,OAAO,IAAI,IAAI,gCAAgC,CAAC;QAC1E,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;YAC9B,IAAI,IAAI,CAAC,GAAG,EAAE,KAAK,IAAI;gBAAE,OAAO,KAAK,IAAI,8BAA8B,CAAC;QAC1E,CAAC;aAAM,CAAC;YACN,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAChB,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QACjB,CAAC;IACH,CAAC;IACD,IAAI,IAAI,CAAC,MAAM;QAAE,OAAO,IAAI,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,iBAAiB,CAAC;IACnE,IAAI,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC;QAAE,OAAO,mDAAmD,CAAC;IAC1G,MAAM,OAAO,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC;IACnD,OAAO,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,oCAAoC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,GAAG,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;AAChH,CAAC;AAED,iFAAiF;AACjF,SAAS,UAAU,CAAC,KAAY,EAAE,KAAiB;IACjD,MAAM,MAAM,GAAG,KAAK,CAAC,MAAM,IAAI,EAAE,CAAC;IAClC,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,IAAI,CAAC,IAAI,KAAK,OAAO;YAAE,SAAS;QAChE,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;YAChC,OAAO,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,IAAI,iDAAiD,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,IAAI,qCAAqC,CAAC;QACjK,CAAC;QACD,IAAI,IAAI,CAAC,IAAI,KAAK,KAAK,EAAE,CAAC;YACxB,IAAI,IAAI,CAAC,MAAM;gBAAE,OAAO,IAAI,IAAI,CAAC,IAAI,KAAK,IAAI,CAAC,MAAM,oDAAoD,CAAC;YAC1G,SAAS;QACX,CAAC;QACD,IAAI,IAAI,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;YAC3B,IAAI,IAAI,CAAC,OAAO;gBAAE,OAAO,IAAI,IAAI,CAAC,IAAI,mEAAmE,CAAC;YAC1G,IAAI,IAAI,CAAC,MAAM;gBAAE,OAAO,IAAI,IAAI,CAAC,IAAI,sCAAsC,CAAC;YAC5E,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC;gBAAE,OAAO,IAAI,IAAI,CAAC,IAAI,mCAAmC,CAAC;YAChG,KAAK,MAAM,QAAQ,IAAI,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;gBACjD,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,QAAQ,CAAC;oBAAE,OAAO,IAAI,QAAQ,+DAA+D,CAAC;YAChJ,CAAC;QACH,CAAC;aAAM,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;YAC9C,OAAO,IAAI,IAAI,CAAC,IAAI,mCAAmC,CAAC;QAC1D,CAAC;QACD,KAAK,MAAM,MAAM,IAAI,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;YACjD,MAAM,MAAM,GAAG,UAAU,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;YACzC,IAAI,MAAM;gBAAE,OAAO,MAAM,CAAC;QAC5B,CAAC;IACH,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,cAAc,CAAC,KAAiB,EAAE,KAAc;IAC9D,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC;QAAE,OAAO,EAAE,MAAM,EAAE,yBAAyB,KAAK,CAAC,IAAI,GAAG,EAAE,CAAC;IACpF,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAO,EAAE,MAAM,EAAE,wBAAwB,EAAE,CAAC;IAC3E,IAAI,CAAC,KAAK;QAAE,OAAO,EAAE,MAAM,EAAE,oBAAoB,EAAE,CAAC;IACpD,IAAI,KAAK,CAAC,MAAM,GAAG,kBAAkB,CAAC,KAAK;QAAE,OAAO,EAAE,MAAM,EAAE,eAAe,kBAAkB,CAAC,KAAK,aAAa,EAAE,CAAC;IACrH,IAAI,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC;QAAE,OAAO,EAAE,MAAM,EAAE,qDAAqD,EAAE,CAAC;IAClG,MAAM,IAAI,GAAG,SAAS,CAAC,KAAK,EAAE,KAAK,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC;IAChD,IAAI,IAAI;QAAE,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC;IAClC,IAAI,KAAY,CAAC;IACjB,IAAI,CAAC;QACH,KAAK,GAAG,YAAY,CAAC,KAAK,CAAC,CAAC;IAC9B,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,EAAE,MAAM,EAAE,2BAA2B,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,EAAE,CAAC;IACzG,CAAC;IACD,IAAI,KAAK,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;QAC1B,8HAA8H;QAC9H,MAAM,KAAK,GAAG,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC,KAAK,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,EAAE,CAAC,IAAI,KAAK,EAAE,CAAC,CAAC;QAClF,MAAM,GAAG,GAAG,UAAU,CAAC,KAAK,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC;QAClE,IAAI,GAAG;YAAE,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC;QAChC,MAAM,IAAI,GAAG,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,OAAO,IAAI,KAAK,QAAQ,IAAI,IAAI,CAAC,IAAI,KAAK,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;QACzG,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YACzB,MAAM,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,KAAK,IAAI,CAAC,CAAC,MAAM,CAAC;YACxD,uFAAuF;YACvF,IAAI,KAAK,KAAK,CAAC,IAAI,IAAI,KAAK,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC;gBAAE,SAAS;YAClF,IAAI,KAAK,KAAK,CAAC;gBAAE,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,CAAC,CAAC,IAAI,IAAI,oDAAoD,KAAK,QAAQ,CAAC,CAAC,CAAC,2BAA2B,IAAI,cAAc,EAAE,CAAC;QACxK,CAAC;QACD,OAAO,EAAE,KAAK,EAAE,CAAC;IACnB,CAAC;IACD,MAAM,OAAO,GAAG,UAAU,CAAC,KAAK,EAAE,KAAK,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC;IACvF,OAAO,OAAO,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC;AACnD,CAAC;AAqCD,yEAAyE;AACzE,SAAS,OAAO,CAAC,KAAY;IAC3B,OAAO,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,OAAO,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;AAC5E,CAAC;AAED,iEAAiE;AACjE,SAAS,cAAc,CAAC,IAAiB;IACvC,MAAM,KAAK,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;IAClD,yEAAyE;IACzE,MAAM,YAAY,GAAG,CAAC,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACrF,MAAM,OAAO,GAAG,IAAI,MAAM,CAAC,MAAM,CAAC,GAAG,CAAA,wBAAwB,YAAY,oBAAoB,EAAE,IAAI,CAAC,CAAC;IACrG,OAAO,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,IAAI,CAAC,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,CAAC;AACxE,CAAC;AAED,0DAA0D;AAC1D,SAAS,YAAY,CAAC,KAAY;IAChC,MAAM,MAAM,GAAa,EAAE,CAAC;IAC5B,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,IAAI,OAAO,GAAG,EAAE,CAAC;IACjB,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,IAAI,OAAO,IAAI,KAAK,QAAQ;YAAE,OAAO,IAAI,IAAI,CAAC;aACzC,IAAI,IAAI,CAAC,IAAI,KAAK,KAAK,EAAE,CAAC;YAAC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;QAAC,CAAC;IAC/G,CAAC;IACD,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IACrB,OAAO,MAAM,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;AACvF,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,WAAW,CAAC,KAAc,EAAE,SAA0C;IACpF,MAAM,WAAW,GAAG,cAAc,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,KAAK,KAAK,OAAO,CAAC,CAAC;IACnF,IAAI,WAAW,CAAC,MAAM;QAAE,MAAM,IAAI,KAAK,CAAC,wBAAwB,WAAW,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACtH,MAAM,IAAI,GAAG,KAAmB,CAAC;IACjC,IAAI,IAAI,CAAC,IAAI,KAAK,SAAS,CAAC,IAAI,IAAI,IAAI,CAAC,OAAO,KAAK,SAAS,CAAC,OAAO,EAAE,CAAC;QACvE,MAAM,IAAI,KAAK,CAAC,mBAAmB,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,OAAO,sBAAsB,SAAS,CAAC,IAAI,IAAI,SAAS,CAAC,OAAO,EAAE,CAAC,CAAC;IAC3H,CAAC;IACD,MAAM,MAAM,GAAG,eAAe,CAAC,SAAS,CAAC,CAAC;IAC1C,MAAM,MAAM,GAAG,IAAI,GAAG,EAAyB,CAAC;IAChD,MAAM,MAAM,GAAe,EAAE,KAAK,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,OAAO,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC;IAC7E,KAAK,MAAM,CAAC,EAAE,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;QACvD,MAAM,CAAC,KAAK,IAAI,CAAC,CAAC;QAClB,MAAM,KAAK,GAAG,MAAM,CAAC,EAAE,CAAC,CAAC;QACzB,IAAI,CAAC,KAAK,EAAE,CAAC;YAAC,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YAAC,SAAS;QAAC,CAAC;QAClD,MAAM,MAAM,GAAG,cAAc,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;QAC5C,IAAI,QAAQ,IAAI,MAAM,EAAE,CAAC;YAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC;YAAC,SAAS;QAAC,CAAC;QAC1F,MAAM,CAAC,GAAG,CAAC,EAAE,EAAE,KAAK,CAAC,IAAI,KAAK,MAAM,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,KAAK,MAAM,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,YAAY,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC;QACjK,MAAM,CAAC,KAAK,IAAI,CAAC,CAAC;IACpB,CAAC;IACD,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,QAAQ,EAAE,IAAI,CAAC,QAAQ,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,cAAc,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC;AAClN,CAAC;AAED,8FAA8F;AAC9F,gFAAgF;AAEhF,MAAM,UAAU,GAAG,IAAI,GAAG,EAAmC,CAAC;AAE9D,8FAA8F;AAC9F,SAAS,QAAQ,CAAC,SAA0C;IAC1D,MAAM,GAAG,GAAG,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAChC,IAAI,KAAK,GAAG,UAAU,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAChC,IAAI,KAAK,KAAK,SAAS;QAAE,OAAO,KAAK,CAAC;IACtC,KAAK,GAAG,IAAI,CAAC;IACb,KAAK,MAAM,QAAQ,IAAI,SAAS,EAAE,CAAC;QACjC,IAAI,CAAC,QAAQ;YAAE,SAAS;QACxB,MAAM,GAAG,GAAG,QAAQ,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAE,CAAC;QACvC,IAAI,CAAC;YACH,IAAI,IAAI,CAAC,WAAW,CAAC,kBAAkB,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;gBAAC,KAAK,GAAG,IAAI,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;gBAAC,MAAM;YAAC,CAAC;QACtG,CAAC;QAAC,MAAM,CAAC;YACP,gDAAgD;QAClD,CAAC;IACH,CAAC;IACD,UAAU,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;IAC3B,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,aAAa,CAAC,KAAY,EAAE,MAAyC,EAAE,SAA0C,EAAE,QAAiB,SAAS;IAC3J,IAAI,GAAG,GAAG,EAAE,CAAC;IACb,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,IAAI,OAAO,IAAI,KAAK,QAAQ,EAAE,CAAC;YAAC,GAAG,IAAI,IAAI,CAAC;YAAC,SAAS;QAAC,CAAC;QACxD,wFAAwF;QACxF,IAAI,IAAI,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;YAAC,GAAG,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;YAAC,SAAS;QAAC,CAAC;QAC3G,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAChC,IAAI,IAAI,CAAC,IAAI,KAAK,KAAK,EAAE,CAAC;YAAC,GAAG,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;YAAC,SAAS;QAAC,CAAC;QACzG,IAAI,IAAI,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;YAC3B,GAAG,IAAI,aAAa,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,IAAI,IAAI,CAAC,OAAO,CAAC,KAAM,EAAE,MAAM,EAAE,SAAS,EAAE,KAAK,CAAC,CAAC;YACnG,SAAS;QACX,CAAC;QACD,MAAM,CAAC,GAAG,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QAC5D,MAAM,MAAM,GAAG,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC;YAC/B,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC,IAAI,OAAO,CAAC,IAAI,IAAI,CAAC,OAAO,CAAC,KAAM;YACzG,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,KAAM,CAAC;QACxB,GAAG,IAAI,aAAa,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,KAAK,CAAC,CAAC;IACzD,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,4HAA4H;AAC5H,SAAS,YAAY,CAAC,KAAiB,EAAE,KAAc,EAAE,OAAiC;IACxF,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAO,OAAO,CAAC,KAAK,CAAC,CAAC;IACrD,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QACzB,MAAM,MAAM,GAAG,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC;QACxF,OAAO,MAAM,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE,CAAC,KAAK,KAAK,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC;IAChF,CAAC;IACD,IAAI,OAAO,KAAK,KAAK,UAAU,EAAE,CAAC;QAChC,MAAM,OAAO,GAAG,KAAqD,CAAC;QACtE,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC;QAC3C,OAAO,UAAyB,MAAgB;YAC9C,MAAM,KAAK,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC;YAC7C,2FAA2F;YAC3F,MAAM,OAAO,GAA4B,EAAE,GAAG,KAAK,EAAE,CAAC;YACtD,MAAM,IAAI,GAAwB,EAAE,CAAC;YACrC,KAAK,MAAM,IAAI,IAAI,KAAK,CAAC,MAAM,IAAI,EAAE,EAAE,CAAC;gBACtC,IAAI,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,IAAI,KAAK,CAAC;oBAAE,SAAS;gBACnD,MAAM,MAAM,GAAG,SAAS,IAAI,CAAC,MAAM,QAAQ,CAAC;gBAC5C,IAAI,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;gBACjC,OAAO,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC;YACzB,CAAC;YACD,IAAI,CAAC;gBACH,MAAM,GAAG,GAAG,OAAO,CAAC,IAAI,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;gBACxC,IAAI,OAAO,GAAG,KAAK,QAAQ;oBAAE,OAAO,OAAO,CAAC,IAAI,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;gBAC/D,IAAI,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC;gBACxB,KAAK,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,IAAI,IAAI;oBAAE,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC;gBACxF,OAAO,IAAI,CAAC;YACd,CAAC;YAAC,MAAM,CAAC;gBACP,OAAO,OAAO,CAAC,IAAI,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;YACpC,CAAC;QACH,CAAC,CAAC;IACJ,CAAC;IACD,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,IAAI,QAAQ,IAAI,KAAK,EAAE,CAAC;QACrE,MAAM,QAAQ,GAAG,KAAqB,CAAC;QACvC,OAAO,MAAM,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,EAAE,KAAK,EAAE,QAAQ,CAAC,KAAK,EAAE,CAAC,CAAC;IACvG,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAgCD,MAAM,UAAU,GAAG,GAAG,CAAC;AAEvB,4FAA4F;AAC5F,MAAM,UAAU,kBAAkB,CAAC,SAA4D,EAAE,KAA8B;IAC7H,MAAM,MAAM,GAAG,OAAO,SAAS,KAAK,UAAU,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,eAAe,CAAC,SAAS,CAAC,CAAC;IACxF,kFAAkF;IAClF,MAAM,KAAK,GAAG,OAAO,SAAS,KAAK,UAAU,IAAI,CAAC,CAAC,SAAS,IAAI,SAAS,IAAI,SAAS,CAAC,OAAO,CAAC,CAAC;IAChG,MAAM,SAAS,GAAG,IAAI,GAAG,EAAmB,CAAC;IAC7C,MAAM,OAAO,GAAG,IAAI,GAAG,EAAmB,CAAC;IAC3C,MAAM,QAAQ,GAAG,IAAI,OAAO,EAAmB,CAAC;IAChD,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;IAC/B,MAAM,QAAQ,GAAG,IAAI,GAAG,EAAU,CAAC;IACnC,MAAM,UAAU,GAAG,IAAI,GAAG,EAAU,CAAC;IACrC,IAAI,YAAgC,CAAC;IAErC,MAAM,MAAM,GAAG,CAAC,EAAU,EAAsE,EAAE;QAChG,KAAK,IAAI,KAAK,GAAG,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,KAAK,IAAI,CAAC,EAAE,KAAK,IAAI,CAAC,EAAE,CAAC;YAC1D,IAAI,CAAC,cAAc,CAAC,KAAK,CAAC,KAAK,CAAE,CAAC,IAAI,EAAE,YAAY,CAAC;gBAAE,SAAS;YAChE,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,CAAE,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;YAC3C,IAAI,KAAK;gBAAE,OAAO,EAAE,IAAI,EAAE,KAAK,CAAC,KAAK,CAAE,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC;QAC1D,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC,CAAC;IAEF,MAAM,OAAO,GAAG,CAAC,EAAU,EAAE,QAAiB,EAAW,EAAE;QACzD,IAAI,QAAQ,GAAG,QAAQ,CAAC;QACxB,+FAA+F;QAC/F,IAAI,CAAC,OAAO,QAAQ,KAAK,UAAU,IAAI,CAAC,OAAO,QAAQ,KAAK,QAAQ,IAAI,QAAQ,KAAK,IAAI,CAAC,CAAC,IAAI,QAAQ,CAAC,GAAG,CAAC,QAAQ,CAAC;YAAE,QAAQ,GAAG,QAAQ,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;aACpJ,IAAI,OAAO,QAAQ,KAAK,QAAQ,IAAI,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,KAAK,QAAQ;YAAE,QAAQ,GAAG,SAAS,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QACvH,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QACb,MAAM,KAAK,GAAG,MAAM,CAAC,EAAE,CAAC,CAAC;QACzB,wFAAwF;QACxF,MAAM,QAAQ,GAAG,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC,CAAC,KAAK,GAAG,CAAC,KAAK,EAAE,KAAK,IAAI,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,OAAO,IAAI,cAAc,CAAC,IAAI,CAAC,IAAI,EAAE,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;QACjK,IAAI,CAAC,KAAK,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC;YAC/B,IAAI,KAAK,IAAI,QAAQ,CAAC,IAAI,GAAG,UAAU,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC;gBAAE,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;YACzE,OAAO,QAAQ,CAAC;QAClB,CAAC;QACD,MAAM,KAAK,GAAG,MAAM,CAAC,EAAE,CAAC,CAAC;QACzB,IAAI,CAAC,KAAK,IAAI,KAAK,CAAC,IAAI,KAAK,QAAQ,IAAI,CAAC,KAAK,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC;YAAE,OAAO,QAAQ,CAAC;QAC1F,IAAI,KAAK,CAAC,IAAI,KAAK,MAAM,CAAC,CAAC,CAAC,OAAO,QAAQ,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,KAAK,MAAM,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,OAAO,QAAQ,KAAK,UAAU,EAAE,CAAC;YAC7I,IAAI,UAAU,CAAC,IAAI,GAAG,UAAU;gBAAE,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;YACrD,OAAO,QAAQ,CAAC;QAClB,CAAC;QACD,IAAI,SAAS,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,SAAS,CAAC,GAAG,CAAC,EAAE,CAAC,KAAK,QAAQ;YAAE,OAAO,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAChF,IAAI,IAAI,GAAY,QAAQ,CAAC;QAC7B,IAAI,KAAK,EAAE,CAAC;YACV,IAAI,MAAM,IAAI,KAAK,CAAC,KAAK,EAAE,CAAC;gBAC1B,IAAI,GAAG,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC;YAC1B,CAAC;iBAAM,IAAI,MAAM,IAAI,KAAK,CAAC,KAAK,EAAE,CAAC;gBACjC,IAAI,GAAG,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC;YAC1B,CAAC;iBAAM,CAAC;gBACN,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC;gBAChC,MAAM,SAAS,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,QAAQ,EAAE,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;gBACzD,IAAI,GAAG,CAAC,MAAgB,EAAU,EAAE,CAAC,aAAa,CAAC,KAAK,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,SAAS,CAAC,CAAC;YACvG,CAAC;QACH,CAAC;QACD,KAAK,MAAM,OAAO,IAAI,QAAQ;YAAE,IAAI,GAAG,YAAY,CAAC,KAAK,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC;QAC1E,IAAI,IAAI,KAAK,QAAQ;YAAE,OAAO,QAAQ,CAAC;QACvC,IAAI,OAAO,IAAI,KAAK,UAAU,IAAI,OAAO,IAAI,KAAK,QAAQ;YAAE,QAAQ,CAAC,GAAG,CAAC,IAAc,EAAE,QAAkB,CAAC,CAAC;QAC7G,SAAS,CAAC,GAAG,CAAC,EAAE,EAAE,QAAQ,CAAC,CAAC;QAC5B,OAAO,CAAC,GAAG,CAAC,EAAE,EAAE,IAAI,CAAC,CAAC;QACtB,OAAO,IAAI,CAAC;IACd,CAAC,CAAC;IAEF,OAAO;QACL,OAAO;QACP,WAAW,CAAC,QAAQ,IAAI,YAAY,GAAG,QAAQ,CAAC,CAAC,CAAC;QAClD,SAAS,EAAE,GAAG,EAAE,CAAC,SAAS;QAC1B,KAAK,EAAE,GAAG,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,OAAO,EAAE,OAAO,CAAC,IAAI,EAAE,QAAQ,EAAE,CAAC,GAAG,QAAQ,CAAC,EAAE,UAAU,EAAE,CAAC,GAAG,UAAU,CAAC,EAAE,CAAC;KAChH,CAAC;AACJ,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,UAAU,CAAC,OAA0C,EAAE,MAAoB;IACzF,MAAM,GAAG,GAA4B,EAAE,CAAC;IACxC,KAAK,MAAM,EAAE,IAAI,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC;QAAE,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,CAAC,OAAO,CAAC,EAAE,EAAE,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC;IACjF,OAAO,GAAG,CAAC;AACb,CAAC;AAED,iGAAiG;AACjG,MAAM,UAAU,cAAc,CAAC,OAA0C,EAAE,MAAoB;IAC7F,MAAM,SAAS,GAAG,MAAM,CAAC,SAAS,EAAE,CAAC;IACrC,MAAM,GAAG,GAA4B,EAAE,CAAC;IACxC,KAAK,MAAM,EAAE,IAAI,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC;QAAE,GAAG,CAAC,EAAE,CAAC,GAAG,SAAS,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;IACrG,OAAO,GAAG,CAAC;AACb,CAAC;AAcD,0EAA0E;AAC1E,MAAM,UAAU,QAAQ,CAAC,SAA0B,EAAE,IAAkC;IACrF,MAAM,GAAG,GAA6B,EAAE,GAAG,EAAE,EAAE,YAAY,EAAE,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;IAC7F,KAAK,MAAM,CAAC,EAAE,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,OAAO,CAAC,EAAE,CAAC;QAC5D,MAAM,KAAK,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,IAAI,UAAU,CAAC,KAAK,EAAE,YAAY,EAAE,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,CAAC,CAAC;QACjG,KAAK,MAAM,MAAM,IAAI,CAAC,KAAK,EAAE,GAAG,CAAC,GAAI,CAAC,EAAE,CAAC;YACvC,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,EAAE,CAAC;gBAAC,MAAM,CAAC,MAAM,IAAI,CAAC,CAAC;gBAAC,SAAS;YAAC,CAAC;YAC3D,MAAM,CAAC,YAAY,IAAI,CAAC,CAAC;YACzB,IAAI,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC;gBAAE,MAAM,CAAC,UAAU,IAAI,CAAC,CAAC;QAClD,CAAC;IACH,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAgBD,MAAM,QAAQ,GAAG,CAAC,IAAuB,EAAE,EAAE,IAAuB,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC,MAAM,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAE1J;;;;GAIG;AACH,MAAM,UAAU,WAAW,CAAC,SAA0B,EAAE,QAAkD,EAAE,MAAyB;IACnI,MAAM,MAAM,GAAgB,EAAE,KAAK,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC;IACpF,KAAK,MAAM,CAAC,EAAE,EAAE,GAAG,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC;QACjD,MAAM,MAAM,GAAG,MAAM,CAAC,SAAS,CAAC,cAAc,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;QAC/G,IAAI,CAAC,MAAM,EAAE,CAAC;YAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YAAC,SAAS;QAAC,CAAC;QACjD,IAAI,MAAM,CAAC,IAAI,KAAK,GAAG,CAAC,IAAI,IAAI,MAAM,CAAC,KAAK,KAAK,GAAG,CAAC,KAAK,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,EAAE,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;YACvN,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QAC3B,CAAC;aAAM,IAAI,MAAM,CAAC,IAAI,KAAK,GAAG,CAAC,IAAI,EAAE,CAAC;YACpC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QAC3B,CAAC;IACH,CAAC;IACD,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,CAAC;IAC/B,KAAK,MAAM,CAAC,EAAE,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,OAAO,CAAC,EAAE,CAAC;QAC5D,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,cAAc,CAAC,IAAI,CAAC,QAAQ,EAAE,EAAE,CAAC,IAAI,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,IAAI,UAAU,CAAC;YAAE,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAC7H,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC","sourcesContent":["// String packs: data-only packs that replace the wrapped site's own UI strings (published as\n// `waybetter/runtime/stringPacks`). A pack adds a language the site does not offer, fixes its\n// translation or rewords it. This file is the data side: the pack and inventory formats, the\n// validator, the ordered application engine, coverage and the drift report. It touches no DOM and\n// runs the same in the page, in the shell and in Node (`waybetter strings check`).\n//\n// The rules (they are the owner's, and every function here keeps them):\n// - Idempotent. The result is a pure function of (the site's own values, the ordered pack list):\n// applying twice equals applying once, and a later pack wins over an earlier one per key.\n// - The site's own language is the fallback. A key no pack changes keeps exactly the site's value\n// (the same object, not a copy).\n// - An inventory of the site's known keys. A pack may change only inventory keys, and only keys\n// whose kind can be replaced by data; unknown keys are reported, never applied.\n// - Packs are data: plain text in an ICU MessageFormat subset ({param}, plural, select). Never\n// HTML, never code. A message is interpreted by closures here; nothing is evaluated.\n//\n// One site can have several catalogs (each with its own key space, inventory and hook adapter,\n// see stringPackHook.ts); a pack names the one it is for.\nimport { parseMessage } from './i18n.ts';\n\ntype Parts = ReturnType<typeof parseMessage>;\n\n// -------------------------------------------------------------------------------------------\n// Formats\n\n/**\n * What the site's value for a key is:\n * - `text`: a plain string;\n * - `message`: a function of a parameter object that returns a string;\n * - `rich`: text with element slots (a link or a button inside a sentence). It can be replaced when\n * the inventory knows its slot count (`slots`): the pack value then places the site's own\n * elements with `{e0}`, `{e1}`, …, each exactly once (the last may be left out); the value itself is still plain text;\n * - `format`: a compiled number/date/currency formatter (not text).\n * Only `text`, `message` and `rich` with known `slots` can be replaced by a pack.\n */\nexport type StringKind = 'text' | 'message' | 'rich' | 'format';\n\nexport type InventoryEntry = {\n kind: StringKind;\n /** Parameter names the site's value takes (`message`). */\n params?: string[];\n /** Parameters the site's value pluralizes: known to be numbers, so a pack may pluralize them. */\n plural?: string[];\n /** Parameters the site's value selects on. */\n select?: string[];\n /** Element slots of a `rich` value (`{e0}` … `{e<slots-1>}` in a pack value; the last may be left out). Without it the key is closed. */\n slots?: number;\n /** Tag slot names, for catalogs whose values carry `<tag>…</tag>` slots. */\n tags?: string[];\n /** Hash of the base-language value (`hashText`): drift detection; never the text itself. */\n hash: string;\n /** Part of the catalog the key arrives with (default `main`), e.g. a lazily loaded `emoji` group. */\n group?: string;\n};\n\n/** The known keys of one catalog of one site. It carries ids and shapes, never the site's text. */\nexport type StringInventory = {\n format: 1;\n site: string;\n catalog: string;\n /** Language the hashes were taken from. */\n base: string;\n /** The site build the inventory was read from. */\n build?: string;\n entries: Record<string, InventoryEntry>;\n};\n\n/**\n * When a pack applies. Without a condition it always does. `languages`: only while the site shows\n * one of these languages (a tag matches itself and its regional forms: `en` matches `en-GB`), for\n * example a rewording of English that must not touch a Turkish page.\n */\nexport type PackCondition = { languages?: string[] };\n\n/**\n * A pack's rewording rule: whole words replaced inside the site's own text, wherever it appears\n * (`{ \"Post\": \"Tweet\", \"posts\": \"tweets\" }`). It carries none of the site's sentences, so it keeps\n * working when the site words a string differently, and it applies to a value of the site (or of an\n * earlier pack) that no later pack replaced. Words are matched exactly (case as written), never\n * inside a longer word, and never in a parameter's value (a user named \"Post\" stays \"Post\").\n */\nexport type PackRewrite = { words: Record<string, string> };\n\n/** A string pack document: metadata and `key id -> text`. */\nexport type StringPack = {\n format: 1;\n site: string;\n catalog: string;\n /** BCP 47 tag of the pack's language (private-use tags are fine: `en-x-pirate`). */\n language: string;\n name: string;\n authors: string[];\n /** A language whose plural rules the pack follows when the runtime does not know `language`. */\n base?: string;\n /** The pack applies only when this holds (default: always). */\n when?: PackCondition;\n /** Rewords the site's text instead of (or besides) replacing keys. */\n rewrite?: PackRewrite;\n version?: string;\n description?: string;\n strings: Record<string, string>;\n};\n\nexport const STRING_PACK_LIMITS = Object.freeze({ strings: 40000, value: 2000, name: 80, authors: 16 });\nexport const MAIN_GROUP = 'main';\n\nconst TAG = /^[A-Za-z]{2,8}(?:-[A-Za-z0-9]{1,8})*$/;\nconst IDENT = /^[a-z][a-z0-9-]{0,31}$/;\nconst CONTROL = /[\\u0000-\\u0008\\u000b\\u000c\\u000e-\\u001f\\u007f--]/;\nconst REWRITE_FROM = /^[\\p{L}\\p{N}]{1,40}$/u;\nconst REWRITE_TO = /^[\\p{L}\\p{N}][\\p{L}\\p{N}'’-]{0,39}$/u;\nconst MAX_REWRITES = 64;\nconst CATEGORIES = new Set(['zero', 'one', 'two', 'few', 'many', 'other']);\n\n/** Whether a pack can replace a value of this kind (a `rich` one only with known `slots`: pass the shape). */\nexport function translatable(kind: StringKind | Pick<EntryShape, 'kind' | 'slots'>): boolean {\n const { kind: k, slots } = typeof kind === 'string' ? { kind, slots: undefined } : kind;\n return k === 'text' || k === 'message' || (k === 'rich' && slots !== undefined);\n}\n\n/** Whether `language` (the site's) satisfies a pack's `when`. */\nexport function conditionHolds(when: PackCondition | undefined, language: string | undefined): boolean {\n if (!when?.languages) return true;\n if (!language) return false;\n const have = language.toLowerCase();\n return when.languages.some(tag => { const want = tag.toLowerCase(); return have === want || have.startsWith(`${want}-`); });\n}\n\n/** 53-bit hash of a text as 11 base-36 characters. Same result in every runtime. */\nexport function hashText(text: string): string {\n let h1 = 0xdeadbeef;\n let h2 = 0x41c6ce57;\n for (let i = 0; i < text.length; i += 1) {\n const ch = text.charCodeAt(i);\n h1 = Math.imul(h1 ^ ch, 2654435761);\n h2 = Math.imul(h2 ^ ch, 1597334677);\n }\n h1 = Math.imul(h1 ^ (h1 >>> 16), 2246822507) ^ Math.imul(h2 ^ (h2 >>> 13), 3266489909);\n h2 = Math.imul(h2 ^ (h2 >>> 16), 2246822507) ^ Math.imul(h1 ^ (h1 >>> 13), 3266489909);\n return (4294967296 * (2097151 & h2) + (h1 >>> 0)).toString(36).padStart(11, '0');\n}\n\n// -------------------------------------------------------------------------------------------\n// Inventory lookup (the full inventory, or its compact page form)\n\n/** The facts the validator and the engine need about one key. */\nexport type EntryShape = Pick<InventoryEntry, 'kind' | 'params' | 'plural' | 'select' | 'tags' | 'slots'>;\nexport type InventoryLookup = (id: string) => EntryShape | undefined;\n\n/**\n * The inventory as it ships inside a page runtime: ids and shapes only, no hashes, a fraction of\n * the size. `text` and `closed` are space-separated ids; a message is `name name*` (`*` = plural,\n * `?` = select).\n */\nexport type PageInventory = {\n site: string;\n catalog: string;\n text: string;\n message: Record<string, string>;\n closed: string;\n /** Rich entries a pack can replace: id -> slot count. */\n rich?: Record<string, number>;\n /** A slice: only the keys some pack names. A key missing from a slice is not a new key of the site. */\n partial?: boolean;\n};\n\nfunction compact(site: string, catalog: string, shapes: Iterable<[string, EntryShape]>): PageInventory {\n const text: string[] = [];\n const closed: string[] = [];\n const message: Record<string, string> = {};\n const rich: Record<string, number> = {};\n for (const [id, entry] of shapes) {\n if (entry.kind === 'rich' && entry.slots !== undefined && !entry.tags?.length) rich[id] = entry.slots;\n else if (entry.kind === 'text' && !entry.tags?.length) text.push(id);\n else if (entry.kind === 'message' && !entry.tags?.length) {\n message[id] = (entry.params ?? []).map(name => `${name}${entry.plural?.includes(name) ? '*' : ''}${entry.select?.includes(name) ? '?' : ''}`).join(' ');\n } else closed.push(id);\n }\n return { site, catalog, text: text.join(' '), message, closed: closed.join(' '), ...(Object.keys(rich).length ? { rich } : {}) };\n}\n\nexport function packInventory(inventory: StringInventory): PageInventory {\n return compact(inventory.site, inventory.catalog, Object.entries(inventory.entries));\n}\n\n/**\n * The part of an inventory that the given keys need: what travels to a page together with the\n * packs it should apply (a page never needs the rest). Keys the inventory does not have are left\n * out, so they stay unknown there too.\n */\nexport function sliceInventory(inventory: StringInventory | PageInventory, ids: Iterable<string>): PageInventory {\n const lookup = inventoryLookup(inventory);\n const shapes: [string, EntryShape][] = [];\n for (const id of new Set(ids)) {\n const shape = lookup(id);\n if (shape) shapes.push([id, shape]);\n }\n return { ...compact(inventory.site, inventory.catalog, shapes), partial: true };\n}\n\n/** Whether untrusted data has the shape of a page inventory (ids and parameter names only). */\nexport function isPageInventory(input: unknown): input is PageInventory {\n if (!isRecord(input)) return false;\n const ids = (value: unknown) => typeof value === 'string' && value.length <= 2_000_000 && /^[\\w$. -]*$/.test(value);\n return typeof input.site === 'string' && IDENT.test(input.site) && typeof input.catalog === 'string' && IDENT.test(input.catalog)\n && ids(input.text) && ids(input.closed) && isRecord(input.message)\n && Object.entries(input.message).every(([id, names]) => /^[\\w$.-]+$/.test(id) && typeof names === 'string' && /^[\\w$*? ]*$/.test(names))\n && (input.rich === undefined || (isRecord(input.rich) && Object.entries(input.rich).every(([id, n]) => /^[\\w$.-]+$/.test(id) && Number.isInteger(n) && (n as number) >= 0 && (n as number) <= 32)))\n && (input.partial === undefined || typeof input.partial === 'boolean');\n}\n\nconst TEXT_SHAPE: EntryShape = Object.freeze({ kind: 'text' });\nconst CLOSED_SHAPE: EntryShape = Object.freeze({ kind: 'rich' });\n\n/** A lookup over either form. The page form is decoded on first use. */\nexport function inventoryLookup(inventory: StringInventory | PageInventory): InventoryLookup {\n if ('entries' in inventory) {\n const entries = inventory.entries;\n return id => (Object.prototype.hasOwnProperty.call(entries, id) ? entries[id] : undefined);\n }\n let table: Map<string, EntryShape> | null = null;\n const decode = () => {\n const map = new Map<string, EntryShape>();\n if (inventory.text) for (const id of inventory.text.split(' ')) map.set(id, TEXT_SHAPE);\n if (inventory.closed) for (const id of inventory.closed.split(' ')) map.set(id, CLOSED_SHAPE);\n if (inventory.rich) for (const [id, slots] of Object.entries(inventory.rich)) map.set(id, { kind: 'rich', slots });\n for (const [id, spec] of Object.entries(inventory.message)) {\n const names = spec ? spec.split(' ') : [];\n map.set(id, {\n kind: 'message',\n params: names.map(name => name.replace(/[*?]+$/, '')),\n plural: names.filter(name => name.includes('*')).map(name => name.replace(/[*?]+$/, '')),\n select: names.filter(name => name.includes('?')).map(name => name.replace(/[*?]+$/, '')),\n });\n }\n return map;\n };\n return id => (table ??= decode()).get(id);\n}\n\n// -------------------------------------------------------------------------------------------\n// Validator\n\nexport type PackIssue = { level: 'error' | 'warning'; key?: string; message: string };\n\nconst isRecord = (value: unknown): value is Record<string, unknown> => typeof value === 'object' && value !== null && !Array.isArray(value);\n\n/** Checks the document envelope. Errors mean the pack is not applied at all. */\nexport function checkPackShape(input: unknown): PackIssue[] {\n const issues: PackIssue[] = [];\n const error = (message: string) => { issues.push({ level: 'error', message }); };\n if (!isRecord(input)) return [{ level: 'error', message: 'a string pack is a JSON object' }];\n if (input.format !== 1) error('\"format\" must be 1');\n for (const field of ['site', 'catalog'] as const) {\n if (typeof input[field] !== 'string' || !IDENT.test(input[field])) error(`\"${field}\" must be a short lowercase id`);\n }\n if (typeof input.language !== 'string' || !TAG.test(input.language)) error('\"language\" must be a language tag (en, pt-BR, en-x-pirate)');\n if (input.base !== undefined && (typeof input.base !== 'string' || !TAG.test(input.base))) error('\"base\" must be a language tag');\n if (typeof input.name !== 'string' || !input.name.trim() || input.name.length > STRING_PACK_LIMITS.name || CONTROL.test(input.name) || /[<>]/.test(input.name)) {\n error(`\"name\" must be 1 to ${STRING_PACK_LIMITS.name} characters of plain text`);\n }\n if (!Array.isArray(input.authors) || input.authors.length > STRING_PACK_LIMITS.authors\n || input.authors.some(author => typeof author !== 'string' || !author.trim() || author.length > STRING_PACK_LIMITS.name || CONTROL.test(author) || /[<>]/.test(author))) {\n error(`\"authors\" must be a list of at most ${STRING_PACK_LIMITS.authors} plain-text names`);\n }\n if (input.when !== undefined) {\n const when = input.when;\n if (!isRecord(when) || Object.keys(when).some(key => key !== 'languages')) error('\"when\" is an object with \"languages\"');\n else if (when.languages !== undefined && (!Array.isArray(when.languages) || !when.languages.length || when.languages.length > 16\n || when.languages.some(tag => typeof tag !== 'string' || !TAG.test(tag)))) error('\"when.languages\" must be a list of 1 to 16 language tags');\n }\n if (input.rewrite !== undefined) {\n const rewrite = input.rewrite;\n const words = isRecord(rewrite) ? rewrite.words : undefined;\n if (!isRecord(rewrite) || Object.keys(rewrite).some(key => key !== 'words') || !isRecord(words) || !Object.keys(words).length || Object.keys(words).length > MAX_REWRITES\n || Object.entries(words).some(([from, to]) => !REWRITE_FROM.test(from) || typeof to !== 'string' || !REWRITE_TO.test(to))) {\n error(`\"rewrite\" is { \"words\": { \"Word\": \"Replacement\" } } with 1 to ${MAX_REWRITES} plain words`);\n }\n }\n for (const field of ['version', 'description'] as const) {\n const value = input[field];\n if (value !== undefined && (typeof value !== 'string' || value.length > 400 || CONTROL.test(value) || /[<>]/.test(value))) error(`\"${field}\" must be plain text`);\n }\n if (!isRecord(input.strings)) error('\"strings\" must be an object of key id -> text');\n else if (Object.keys(input.strings).length > STRING_PACK_LIMITS.strings) error(`\"strings\" has more than ${STRING_PACK_LIMITS.strings} entries`);\n const known = new Set(['$schema', 'format', 'site', 'catalog', 'language', 'base', 'when', 'rewrite', 'name', 'authors', 'version', 'description', 'strings']);\n for (const key of Object.keys(input)) if (!known.has(key)) issues.push({ level: 'warning', message: `unknown field \"${key}\" is ignored` });\n return issues;\n}\n\nconst TAG_TOKEN = /<\\/?([A-Za-z][A-Za-z0-9-]*)>/g;\n\n/** Tag rule: only the original's tag slots, each opened and closed; any other `<` or `>` is refused. */\nfunction checkTags(value: string, tags: readonly string[]): string | null {\n if (!value.includes('<') && !value.includes('>')) {\n return tags.length ? `the original's tags are missing: ${tags.map(tag => `<${tag}>`).join(' ')}` : null;\n }\n if (!tags.length) return 'markup is not allowed: a pack is text, < and > cannot be used';\n const open: string[] = [];\n const seen = new Set<string>();\n for (const match of value.matchAll(TAG_TOKEN)) {\n const name = match[1]!;\n if (!tags.includes(name)) return `<${name}> is not a tag of the original`;\n if (match[0].startsWith('</')) {\n if (open.pop() !== name) return `</${name}> does not close an open tag`;\n } else {\n open.push(name);\n seen.add(name);\n }\n }\n if (open.length) return `<${open[open.length - 1]}> is not closed`;\n if (/[<>]/.test(value.replace(TAG_TOKEN, ''))) return '< and > may only be used for the original\\'s tags';\n const missing = tags.filter(tag => !seen.has(tag));\n return missing.length ? `the original's tags are missing: ${missing.map(tag => `<${tag}>`).join(' ')}` : null;\n}\n\n/** Walks a parsed message against the key's shape; returns the first problem. */\nfunction checkParts(parts: Parts, shape: EntryShape): string | null {\n const params = shape.params ?? [];\n for (const part of parts) {\n if (typeof part === 'string' || part.kind === 'pound') continue;\n if (!params.includes(part.name)) {\n return params.length ? `{${part.name}} is not a parameter of the original (it has: ${params.join(', ')})` : `{${part.name}}: the original takes no parameters`;\n }\n if (part.kind === 'arg') {\n if (part.format) return `{${part.name}, ${part.format}} is not supported: only {name}, plural and select`;\n continue;\n }\n if (part.kind === 'plural') {\n if (part.ordinal) return `{${part.name}, selectordinal} is not supported: only {name}, plural and select`;\n if (part.offset) return `{${part.name}, plural, offset:…} is not supported`;\n if (!shape.plural?.includes(part.name)) return `{${part.name}} is not a plural of the original`;\n for (const selector of Object.keys(part.options)) {\n if (!CATEGORIES.has(selector) && !/^=\\d+$/.test(selector)) return `\"${selector}\" is not a plural form (zero, one, two, few, many, other, =N)`;\n }\n } else if (!shape.select?.includes(part.name)) {\n return `{${part.name}} is not a select of the original`;\n }\n for (const option of Object.values(part.options)) {\n const nested = checkParts(option, shape);\n if (nested) return nested;\n }\n }\n return null;\n}\n\n/**\n * Validates one pack value against the key's inventory entry. Returns the parsed message, or the\n * reason it is refused (the original then stays).\n */\nexport function validateString(shape: EntryShape, value: unknown): { parts: Parts } | { reason: string } {\n if (!translatable(shape)) return { reason: `not translatable yet (${shape.kind})` };\n if (typeof value !== 'string') return { reason: 'the value must be text' };\n if (!value) return { reason: 'the value is empty' };\n if (value.length > STRING_PACK_LIMITS.value) return { reason: `longer than ${STRING_PACK_LIMITS.value} characters` };\n if (CONTROL.test(value)) return { reason: 'control or bidi-override characters are not allowed' };\n const tags = checkTags(value, shape.tags ?? []);\n if (tags) return { reason: tags };\n let parts: Parts;\n try {\n parts = parseMessage(value);\n } catch (error) {\n return { reason: `invalid message syntax: ${error instanceof Error ? error.message : String(error)}` };\n }\n if (shape.kind === 'rich') {\n // Element slots: `{e0}` … `{e<slots-1>}`, each exactly once (the last may be left out); no plural, select or other parameter.\n const slots = Array.from({ length: shape.slots ?? 0 }, (_, index) => `e${index}`);\n const bad = checkParts(parts, { kind: 'message', params: slots });\n if (bad) return { reason: bad };\n const used = parts.flatMap(part => (typeof part !== 'string' && part.kind === 'arg' ? [part.name] : []));\n for (const name of slots) {\n const count = used.filter(item => item === name).length;\n // The element after the last piece is not always there: that one slot may be left out.\n if (count === 0 && name === slots[slots.length - 1] && slots.length > 0) continue;\n if (count !== 1) return { reason: count ? `{${name}} (the original's element) must appear once, not ${count} times` : `the original's element {${name}} is missing` };\n }\n return { parts };\n }\n const problem = checkParts(parts, shape.kind === 'message' ? shape : { kind: 'text' });\n return problem ? { reason: problem } : { parts };\n}\n\n// -------------------------------------------------------------------------------------------\n// Compiling a pack (validation against an inventory)\n\n/**\n * A replaced `rich` value in the shape X's own renderer reads: piece `n` is shown, then the site's\n * element `order[n]` (the last piece has no element after it).\n */\nexport type RichTemplate = { readonly pieces: readonly string[]; readonly order: readonly number[] };\n\nexport type CompiledValue = { text: string } | { parts: Parts } | { rich: RichTemplate };\n\nexport type PackReport = {\n /** Entries in the pack. */\n total: number;\n /** Entries that are valid for an inventory key. */\n valid: number;\n /** Ids the inventory does not have: never applied. */\n unknown: string[];\n /** Values that failed validation: not applied, the original stays. */\n rejected: { id: string; reason: string }[];\n};\n\nexport type CompiledPack = {\n name: string;\n language: string;\n base?: string;\n when?: PackCondition;\n /** The pack's word rewriting, ready to apply to a text. */\n rewrite?: (text: string) => string;\n site: string;\n catalog: string;\n values: ReadonlyMap<string, CompiledValue>;\n report: PackReport;\n};\n\n/** A message without arguments as its literal text (quotes resolved). */\nfunction literal(parts: Parts): string {\n return parts.map(part => (typeof part === 'string' ? part : '')).join('');\n}\n\n/** The word-for-word rewriting of a validated `rewrite` rule. */\nfunction compileRewrite(rule: PackRewrite): (text: string) => string {\n const words = new Map(Object.entries(rule.words));\n // Words are letters and digits only (checked), so they need no escaping.\n const alternatives = [...words.keys()].sort((a, b) => b.length - a.length).join('|');\n const pattern = new RegExp(String.raw`(?<![\\p{L}\\p{N}_])(?:${alternatives})(?![\\p{L}\\p{N}_])`, 'gu');\n return text => text.replace(pattern, word => words.get(word) ?? word);\n}\n\n/** A validated rich value as pieces and element order. */\nfunction richTemplate(parts: Parts): RichTemplate {\n const pieces: string[] = [];\n const order: number[] = [];\n let current = '';\n for (const part of parts) {\n if (typeof part === 'string') current += part;\n else if (part.kind === 'arg') { pieces.push(current); order.push(Number(part.name.slice(1))); current = ''; }\n }\n pieces.push(current);\n return Object.freeze({ pieces: Object.freeze(pieces), order: Object.freeze(order) });\n}\n\n/**\n * Validates a pack against an inventory. Throws on a malformed envelope or a pack for another\n * site/catalog; every other problem is per key and lands in `report`.\n */\nexport function compilePack(input: unknown, inventory: StringInventory | PageInventory): CompiledPack {\n const shapeErrors = checkPackShape(input).filter(issue => issue.level === 'error');\n if (shapeErrors.length) throw new Error(`invalid string pack: ${shapeErrors.map(issue => issue.message).join('; ')}`);\n const pack = input as StringPack;\n if (pack.site !== inventory.site || pack.catalog !== inventory.catalog) {\n throw new Error(`the pack is for ${pack.site}/${pack.catalog}, the inventory is ${inventory.site}/${inventory.catalog}`);\n }\n const lookup = inventoryLookup(inventory);\n const values = new Map<string, CompiledValue>();\n const report: PackReport = { total: 0, valid: 0, unknown: [], rejected: [] };\n for (const [id, value] of Object.entries(pack.strings)) {\n report.total += 1;\n const shape = lookup(id);\n if (!shape) { report.unknown.push(id); continue; }\n const result = validateString(shape, value);\n if ('reason' in result) { report.rejected.push({ id, reason: result.reason }); continue; }\n values.set(id, shape.kind === 'text' ? { text: literal(result.parts) } : shape.kind === 'rich' ? { rich: richTemplate(result.parts) } : { parts: result.parts });\n report.valid += 1;\n }\n return { name: pack.name, language: pack.language, base: pack.base, when: pack.when, rewrite: pack.rewrite ? compileRewrite(pack.rewrite) : undefined, site: pack.site, catalog: pack.catalog, values, report };\n}\n\n// -------------------------------------------------------------------------------------------\n// Interpreting a message (closures over the parsed parts; nothing is evaluated)\n\nconst rulesCache = new Map<string, Intl.PluralRules | null>();\n\n/** Plural rules of the first language the runtime knows; `null` = every number is `other`. */\nfunction rulesFor(languages: readonly (string | undefined)[]): Intl.PluralRules | null {\n const key = languages.join('|');\n let rules = rulesCache.get(key);\n if (rules !== undefined) return rules;\n rules = null;\n for (const language of languages) {\n if (!language) continue;\n const tag = language.split(/-x-/i)[0]!;\n try {\n if (Intl.PluralRules.supportedLocalesOf([tag]).length) { rules = new Intl.PluralRules(tag); break; }\n } catch {\n // Not a tag this runtime accepts: try the next.\n }\n }\n rulesCache.set(key, rules);\n return rules;\n}\n\n/**\n * Renders a validated message. A parameter is inserted the way string concatenation would\n * (`String(value)`, nothing for a missing one); `#` is the plural's own value.\n */\nexport function renderMessage(parts: Parts, params: Readonly<Record<string, unknown>>, languages: readonly (string | undefined)[], pound: unknown = undefined): string {\n let out = '';\n for (const part of parts) {\n if (typeof part === 'string') { out += part; continue; }\n // The parser only yields `#` inside a plural, so there is always a value it stands for.\n if (part.kind === 'pound') { out += pound === undefined || pound === null ? '' : String(pound); continue; }\n const value = params[part.name];\n if (part.kind === 'arg') { out += value === undefined || value === null ? '' : String(value); continue; }\n if (part.kind === 'select') {\n out += renderMessage(part.options[String(value)] ?? part.options.other!, params, languages, pound);\n continue;\n }\n const n = typeof value === 'number' ? value : Number(value);\n const option = Number.isFinite(n)\n ? part.options[`=${n}`] ?? part.options[rulesFor(languages)?.select(n) ?? 'other'] ?? part.options.other!\n : part.options.other!;\n out += renderMessage(option, params, languages, value);\n }\n return out;\n}\n\n/** The site's (or a pack's) value of one key with `rewrite` applied; a message keeps its parameters' values as they are. */\nfunction rewriteValue(shape: EntryShape, value: unknown, rewrite: (text: string) => string): unknown {\n if (typeof value === 'string') return rewrite(value);\n if (Array.isArray(value)) {\n const mapped = value.map(piece => (typeof piece === 'string' ? rewrite(piece) : piece));\n return mapped.some((piece, index) => piece !== value[index]) ? mapped : value;\n }\n if (typeof value === 'function') {\n const message = value as (this: unknown, params?: unknown) => unknown;\n const plural = new Set(shape.plural ?? []);\n return function (this: unknown, params?: unknown) {\n const input = isRecord(params) ? params : {};\n // The parameters go through as private markers, so only the site's own words are reworded.\n const forward: Record<string, unknown> = { ...input };\n const held: [string, unknown][] = [];\n for (const name of shape.params ?? []) {\n if (plural.has(name) || !(name in input)) continue;\n const marker = `\\uE000${held.length}\\uE001`;\n held.push([marker, input[name]]);\n forward[name] = marker;\n }\n try {\n const out = message.call(this, forward);\n if (typeof out !== 'string') return message.call(this, params);\n let text = rewrite(out);\n for (const [marker, original] of held) text = text.split(marker).join(String(original));\n return text;\n } catch {\n return message.call(this, params);\n }\n };\n }\n if (typeof value === 'object' && value !== null && 'pieces' in value) {\n const template = value as RichTemplate;\n return Object.freeze({ pieces: Object.freeze(template.pieces.map(rewrite)), order: template.order });\n }\n return value;\n}\n\n// -------------------------------------------------------------------------------------------\n// The ordered application engine\n\nexport type EngineStats = {\n /** Keys the site registered. */\n seen: number;\n /** Keys a pack value was used for. */\n applied: number;\n /** Keys the site registered that the inventory does not have (new keys: drift). */\n unlisted: string[];\n /** Keys whose live value does not have the inventory's kind: left untouched. */\n mismatched: string[];\n};\n\nexport type StringEngine = {\n /**\n * The value to use for `id`, given the site's own value: a pack's, or exactly `original`.\n * Feeding a value this engine produced back in returns the same value (idempotent).\n */\n resolve(id: string, original: unknown): unknown;\n /**\n * The language the site shows (what packs with a `when.languages` condition are checked\n * against). Set before the first `resolve`; until then conditional packs do not apply.\n */\n setLanguage(language: string): void;\n /** The site's own values of the keys a pack changed: what restoring needs. */\n originals(): ReadonlyMap<string, unknown>;\n stats(): EngineStats;\n};\n\nconst MAX_LISTED = 200;\n\n/** `packs` in application order: a later pack wins over an earlier one for the same key. */\nexport function createStringEngine(inventory: StringInventory | PageInventory | InventoryLookup, packs: readonly CompiledPack[]): StringEngine {\n const lookup = typeof inventory === 'function' ? inventory : inventoryLookup(inventory);\n // A slice only knows the packs' keys: what it lacks is not a new key of the site.\n const whole = typeof inventory === 'function' || !('partial' in inventory && inventory.partial);\n const originals = new Map<string, unknown>();\n const applied = new Map<string, unknown>();\n const produced = new WeakMap<object, unknown>();\n const seen = new Set<string>();\n const unlisted = new Set<string>();\n const mismatched = new Set<string>();\n let siteLanguage: string | undefined;\n\n const winner = (id: string): { pack: CompiledPack; value: CompiledValue; index: number } | null => {\n for (let index = packs.length - 1; index >= 0; index -= 1) {\n if (!conditionHolds(packs[index]!.when, siteLanguage)) continue;\n const value = packs[index]!.values.get(id);\n if (value) return { pack: packs[index]!, value, index };\n }\n return null;\n };\n\n const resolve = (id: string, incoming: unknown): unknown => {\n let original = incoming;\n // A value of ours coming back in (a second application): work from the site's own value again.\n if ((typeof incoming === 'function' || (typeof incoming === 'object' && incoming !== null)) && produced.has(incoming)) original = produced.get(incoming);\n else if (typeof incoming === 'string' && applied.has(id) && applied.get(id) === incoming) original = originals.get(id);\n seen.add(id);\n const found = winner(id);\n // Word rewriting of the packs after the one whose text won (all of them when none did).\n const rewrites = packs.flatMap((pack, index) => (index > (found?.index ?? -1) && pack.rewrite && conditionHolds(pack.when, siteLanguage) ? [pack.rewrite] : []));\n if (!found && !rewrites.length) {\n if (whole && unlisted.size < MAX_LISTED && !lookup(id)) unlisted.add(id);\n return original;\n }\n const shape = lookup(id);\n if (!shape || shape.kind === 'format' || (found && !translatable(shape))) return original;\n if (shape.kind === 'text' ? typeof original !== 'string' : shape.kind === 'rich' ? !Array.isArray(original) : typeof original !== 'function') {\n if (mismatched.size < MAX_LISTED) mismatched.add(id);\n return original;\n }\n if (originals.has(id) && originals.get(id) === original) return applied.get(id);\n let next: unknown = original;\n if (found) {\n if ('text' in found.value) {\n next = found.value.text;\n } else if ('rich' in found.value) {\n next = found.value.rich;\n } else {\n const parts = found.value.parts;\n const languages = [found.pack.language, found.pack.base];\n next = (params?: unknown): string => renderMessage(parts, isRecord(params) ? params : {}, languages);\n }\n }\n for (const rewrite of rewrites) next = rewriteValue(shape, next, rewrite);\n if (next === original) return original;\n if (typeof next === 'function' || typeof next === 'object') produced.set(next as object, original as object);\n originals.set(id, original);\n applied.set(id, next);\n return next;\n };\n\n return {\n resolve,\n setLanguage(language) { siteLanguage = language; },\n originals: () => originals,\n stats: () => ({ seen: seen.size, applied: applied.size, unlisted: [...unlisted], mismatched: [...mismatched] }),\n };\n}\n\n/**\n * The whole catalog at once: a new object with the packs applied; `catalog` itself is not\n * changed. `applyPacks(applyPacks(c, …), …)` with one engine equals `applyPacks(c, …)`.\n */\nexport function applyPacks(catalog: Readonly<Record<string, unknown>>, engine: StringEngine): Record<string, unknown> {\n const out: Record<string, unknown> = {};\n for (const id of Object.keys(catalog)) out[id] = engine.resolve(id, catalog[id]);\n return out;\n}\n\n/** The inverse: every value a pack changed is the site's own again; `catalog` is not changed. */\nexport function restoreCatalog(catalog: Readonly<Record<string, unknown>>, engine: StringEngine): Record<string, unknown> {\n const originals = engine.originals();\n const out: Record<string, unknown> = {};\n for (const id of Object.keys(catalog)) out[id] = originals.has(id) ? originals.get(id) : catalog[id];\n return out;\n}\n\n// -------------------------------------------------------------------------------------------\n// Coverage\n\nexport type Coverage = {\n /** Keys a pack can replace (text and messages). */\n translatable: number;\n /** Of those, keys the pack has a valid value for. */\n translated: number;\n /** Keys that exist but cannot be replaced by data yet (rich text, formatters). */\n closed: number;\n};\n\n/** Coverage of a compiled pack per group of the inventory, plus `all`. */\nexport function coverage(inventory: StringInventory, pack: Pick<CompiledPack, 'values'>): Record<string, Coverage> {\n const out: Record<string, Coverage> = { all: { translatable: 0, translated: 0, closed: 0 } };\n for (const [id, entry] of Object.entries(inventory.entries)) {\n const group = (out[entry.group ?? MAIN_GROUP] ??= { translatable: 0, translated: 0, closed: 0 });\n for (const bucket of [group, out.all!]) {\n if (!translatable(entry)) { bucket.closed += 1; continue; }\n bucket.translatable += 1;\n if (pack.values.has(id)) bucket.translated += 1;\n }\n }\n return out;\n}\n\n// -------------------------------------------------------------------------------------------\n// Drift (the site shipped a new build)\n\nexport type DriftReport = {\n /** Keys the site has that the inventory lacks. */\n added: string[];\n /** Keys whose base-language value changed (same shape). */\n reworded: string[];\n /** Keys whose kind or parameters changed: pack values for them have to be checked again. */\n reshaped: string[];\n /** Inventory keys the site no longer has. Only for groups whose base catalog was loaded. */\n vanished: string[];\n};\n\nconst sameList = (a: readonly string[] = [], b: readonly string[] = []) => a.length === b.length && [...a].sort().join('\\n') === [...b].sort().join('\\n');\n\n/**\n * Compares an inventory with what was observed now. `loaded` names the groups whose base catalog\n * was actually read: a key can only be called vanished when its group was (a lazily loaded group\n * that never arrived says nothing about its keys).\n */\nexport function driftReport(inventory: StringInventory, observed: Readonly<Record<string, InventoryEntry>>, loaded: readonly string[]): DriftReport {\n const report: DriftReport = { added: [], reworded: [], reshaped: [], vanished: [] };\n for (const [id, now] of Object.entries(observed)) {\n const before = Object.prototype.hasOwnProperty.call(inventory.entries, id) ? inventory.entries[id] : undefined;\n if (!before) { report.added.push(id); continue; }\n if (before.kind !== now.kind || before.slots !== now.slots || !sameList(before.params, now.params) || !sameList(before.plural, now.plural) || !sameList(before.select, now.select) || !sameList(before.tags, now.tags)) {\n report.reshaped.push(id);\n } else if (before.hash !== now.hash) {\n report.reworded.push(id);\n }\n }\n const groups = new Set(loaded);\n for (const [id, entry] of Object.entries(inventory.entries)) {\n if (!Object.prototype.hasOwnProperty.call(observed, id) && groups.has(entry.group ?? MAIN_GROUP)) report.vanished.push(id);\n }\n return report;\n}\n"]}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export type RootStyles = {
|
|
2
|
+
/** The live sheet (insertRule/deleteRule work on it), or null when nothing could be parsed. */
|
|
3
|
+
readonly sheet: CSSStyleSheet | null;
|
|
4
|
+
/** True when the sheet is adopted (CSP-proof); false for the `<style>` fallback. */
|
|
5
|
+
readonly adopted: boolean;
|
|
6
|
+
/** Replaces the rules. */
|
|
7
|
+
update(css: string): void;
|
|
8
|
+
/** Takes the rules off the root (idempotent). */
|
|
9
|
+
remove(): void;
|
|
10
|
+
};
|
|
11
|
+
/**
|
|
12
|
+
* Styles `root` with `css`. Adopted sheets come after the root's `<style>` elements in the cascade
|
|
13
|
+
* (like a `<style>` appended last), and several calls stack in call order.
|
|
14
|
+
*/
|
|
15
|
+
export declare function adoptStyles(root: ShadowRoot | Document, css: string): RootStyles;
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
// Styles for roots the runtime (or a plugin) creates: a constructable stylesheet adopted by the
|
|
2
|
+
// shadow root (or document) instead of a `<style>` element.
|
|
3
|
+
//
|
|
4
|
+
// Why: a site's Content-Security-Policy governs `<style>` elements (a `style-src` with a nonce or
|
|
5
|
+
// hash and no 'unsafe-inline' refuses them, in shadow roots too), but not constructed sheets
|
|
6
|
+
// (`new CSSStyleSheet()` + `replaceSync`), which are also parsed once instead of per element and
|
|
7
|
+
// stay adopted when their host is moved to another parent in the same document (a modal
|
|
8
|
+
// re-rendered by the site, a card lifted into the top layer). Engines without constructable
|
|
9
|
+
// sheets (or a root from another realm that refuses the sheet) get the `<style>` element.
|
|
10
|
+
const DOCUMENT_NODE = 9;
|
|
11
|
+
const isDocument = (root) => root.nodeType === DOCUMENT_NODE;
|
|
12
|
+
const documentOf = (root) => (isDocument(root) ? root : root.ownerDocument);
|
|
13
|
+
/** A sheet built in `root`'s own realm (a sheet from another document cannot be adopted). */
|
|
14
|
+
function construct(root, css) {
|
|
15
|
+
if (!root.adoptedStyleSheets)
|
|
16
|
+
return null;
|
|
17
|
+
const Sheet = documentOf(root).defaultView?.CSSStyleSheet;
|
|
18
|
+
if (typeof Sheet !== 'function' || typeof Sheet.prototype.replaceSync !== 'function')
|
|
19
|
+
return null;
|
|
20
|
+
try {
|
|
21
|
+
const sheet = new Sheet();
|
|
22
|
+
sheet.replaceSync(css);
|
|
23
|
+
return sheet;
|
|
24
|
+
}
|
|
25
|
+
catch {
|
|
26
|
+
return null;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Styles `root` with `css`. Adopted sheets come after the root's `<style>` elements in the cascade
|
|
31
|
+
* (like a `<style>` appended last), and several calls stack in call order.
|
|
32
|
+
*/
|
|
33
|
+
export function adoptStyles(root, css) {
|
|
34
|
+
const target = root;
|
|
35
|
+
const sheet = construct(target, css);
|
|
36
|
+
if (sheet) {
|
|
37
|
+
let on = false;
|
|
38
|
+
const attach = () => {
|
|
39
|
+
try {
|
|
40
|
+
target.adoptedStyleSheets = [...(target.adoptedStyleSheets ?? []), sheet];
|
|
41
|
+
on = true;
|
|
42
|
+
}
|
|
43
|
+
catch {
|
|
44
|
+
on = false;
|
|
45
|
+
}
|
|
46
|
+
};
|
|
47
|
+
attach();
|
|
48
|
+
if (on) {
|
|
49
|
+
return {
|
|
50
|
+
sheet,
|
|
51
|
+
adopted: true,
|
|
52
|
+
update(next) { try {
|
|
53
|
+
sheet.replaceSync(next);
|
|
54
|
+
}
|
|
55
|
+
catch { /* Keeps the last good rules. */ } },
|
|
56
|
+
remove() {
|
|
57
|
+
if (!on)
|
|
58
|
+
return;
|
|
59
|
+
on = false;
|
|
60
|
+
try {
|
|
61
|
+
target.adoptedStyleSheets = (target.adoptedStyleSheets ?? []).filter(item => item !== sheet);
|
|
62
|
+
}
|
|
63
|
+
catch { /* Root gone. */ }
|
|
64
|
+
},
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
// Fallback: a `<style>` element as the root's last child (a document: its <head>).
|
|
69
|
+
const doc = documentOf(target);
|
|
70
|
+
const style = doc.createElement('style');
|
|
71
|
+
style.textContent = css;
|
|
72
|
+
const parent = isDocument(target) ? (target.head ?? target.documentElement) : target;
|
|
73
|
+
parent.appendChild(style);
|
|
74
|
+
return {
|
|
75
|
+
get sheet() { return style.sheet; },
|
|
76
|
+
adopted: false,
|
|
77
|
+
update(next) { style.textContent = next; },
|
|
78
|
+
remove() { style.remove(); },
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
//# sourceMappingURL=styles.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"styles.js","sourceRoot":"","sources":["../../../runtime/src/styles.ts"],"names":[],"mappings":"AAAA,gGAAgG;AAChG,4DAA4D;AAC5D,EAAE;AACF,kGAAkG;AAClG,6FAA6F;AAC7F,iGAAiG;AACjG,wFAAwF;AACxF,4FAA4F;AAC5F,0FAA0F;AAe1F,MAAM,aAAa,GAAG,CAAC,CAAC;AACxB,MAAM,UAAU,GAAG,CAAC,IAAe,EAAgC,EAAE,CAAC,IAAI,CAAC,QAAQ,KAAK,aAAa,CAAC;AACtG,MAAM,UAAU,GAAG,CAAC,IAAe,EAAY,EAAE,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAE,IAAmB,CAAC,aAAa,CAAC,CAAC;AAEjH,6FAA6F;AAC7F,SAAS,SAAS,CAAC,IAAe,EAAE,GAAW;IAC7C,IAAI,CAAC,IAAI,CAAC,kBAAkB;QAAE,OAAO,IAAI,CAAC;IAC1C,MAAM,KAAK,GAAI,UAAU,CAAC,IAAI,CAAC,CAAC,WAAmD,EAAE,aAAa,CAAC;IACnG,IAAI,OAAO,KAAK,KAAK,UAAU,IAAI,OAAO,KAAK,CAAC,SAAS,CAAC,WAAW,KAAK,UAAU;QAAE,OAAO,IAAI,CAAC;IAClG,IAAI,CAAC;QACH,MAAM,KAAK,GAAG,IAAI,KAAK,EAAE,CAAC;QAC1B,KAAK,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;QACvB,OAAO,KAAK,CAAC;IACf,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,WAAW,CAAC,IAA2B,EAAE,GAAW;IAClE,MAAM,MAAM,GAAG,IAAiB,CAAC;IACjC,MAAM,KAAK,GAAG,SAAS,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IACrC,IAAI,KAAK,EAAE,CAAC;QACV,IAAI,EAAE,GAAG,KAAK,CAAC;QACf,MAAM,MAAM,GAAG,GAAG,EAAE;YAClB,IAAI,CAAC;gBACH,MAAM,CAAC,kBAAkB,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,kBAAkB,IAAI,EAAE,CAAC,EAAE,KAAK,CAAC,CAAC;gBAC1E,EAAE,GAAG,IAAI,CAAC;YACZ,CAAC;YAAC,MAAM,CAAC;gBAAC,EAAE,GAAG,KAAK,CAAC;YAAC,CAAC;QACzB,CAAC,CAAC;QACF,MAAM,EAAE,CAAC;QACT,IAAI,EAAE,EAAE,CAAC;YACP,OAAO;gBACL,KAAK;gBACL,OAAO,EAAE,IAAI;gBACb,MAAM,CAAC,IAAI,IAAI,IAAI,CAAC;oBAAC,KAAK,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;gBAAC,CAAC;gBAAC,MAAM,CAAC,CAAC,gCAAgC,CAAC,CAAC,CAAC,CAAC;gBAC5F,MAAM;oBACJ,IAAI,CAAC,EAAE;wBAAE,OAAO;oBAChB,EAAE,GAAG,KAAK,CAAC;oBACX,IAAI,CAAC;wBAAC,MAAM,CAAC,kBAAkB,GAAG,CAAC,MAAM,CAAC,kBAAkB,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,KAAK,KAAK,CAAC,CAAC;oBAAC,CAAC;oBAAC,MAAM,CAAC,CAAC,gBAAgB,CAAC,CAAC;gBAClI,CAAC;aACF,CAAC;QACJ,CAAC;IACH,CAAC;IACD,mFAAmF;IACnF,MAAM,GAAG,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC;IAC/B,MAAM,KAAK,GAAG,GAAG,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC;IACzC,KAAK,CAAC,WAAW,GAAG,GAAG,CAAC;IACxB,MAAM,MAAM,GAAS,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,IAAI,MAAM,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC;IAC3F,MAAM,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;IAC1B,OAAO;QACL,IAAI,KAAK,KAAK,OAAO,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC;QACnC,OAAO,EAAE,KAAK;QACd,MAAM,CAAC,IAAI,IAAI,KAAK,CAAC,WAAW,GAAG,IAAI,CAAC,CAAC,CAAC;QAC1C,MAAM,KAAK,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;KAC7B,CAAC;AACJ,CAAC","sourcesContent":["// Styles for roots the runtime (or a plugin) creates: a constructable stylesheet adopted by the\n// shadow root (or document) instead of a `<style>` element.\n//\n// Why: a site's Content-Security-Policy governs `<style>` elements (a `style-src` with a nonce or\n// hash and no 'unsafe-inline' refuses them, in shadow roots too), but not constructed sheets\n// (`new CSSStyleSheet()` + `replaceSync`), which are also parsed once instead of per element and\n// stay adopted when their host is moved to another parent in the same document (a modal\n// re-rendered by the site, a card lifted into the top layer). Engines without constructable\n// sheets (or a root from another realm that refuses the sheet) get the `<style>` element.\n\nexport type RootStyles = {\n /** The live sheet (insertRule/deleteRule work on it), or null when nothing could be parsed. */\n readonly sheet: CSSStyleSheet | null;\n /** True when the sheet is adopted (CSP-proof); false for the `<style>` fallback. */\n readonly adopted: boolean;\n /** Replaces the rules. */\n update(css: string): void;\n /** Takes the rules off the root (idempotent). */\n remove(): void;\n};\n\ntype StyleRoot = (ShadowRoot | Document) & { adoptedStyleSheets?: CSSStyleSheet[] };\n\nconst DOCUMENT_NODE = 9;\nconst isDocument = (root: StyleRoot): root is Document & StyleRoot => root.nodeType === DOCUMENT_NODE;\nconst documentOf = (root: StyleRoot): Document => (isDocument(root) ? root : (root as ShadowRoot).ownerDocument);\n\n/** A sheet built in `root`'s own realm (a sheet from another document cannot be adopted). */\nfunction construct(root: StyleRoot, css: string): CSSStyleSheet | null {\n if (!root.adoptedStyleSheets) return null;\n const Sheet = (documentOf(root).defaultView as (Window & typeof globalThis) | null)?.CSSStyleSheet;\n if (typeof Sheet !== 'function' || typeof Sheet.prototype.replaceSync !== 'function') return null;\n try {\n const sheet = new Sheet();\n sheet.replaceSync(css);\n return sheet;\n } catch {\n return null;\n }\n}\n\n/**\n * Styles `root` with `css`. Adopted sheets come after the root's `<style>` elements in the cascade\n * (like a `<style>` appended last), and several calls stack in call order.\n */\nexport function adoptStyles(root: ShadowRoot | Document, css: string): RootStyles {\n const target = root as StyleRoot;\n const sheet = construct(target, css);\n if (sheet) {\n let on = false;\n const attach = () => {\n try {\n target.adoptedStyleSheets = [...(target.adoptedStyleSheets ?? []), sheet];\n on = true;\n } catch { on = false; }\n };\n attach();\n if (on) {\n return {\n sheet,\n adopted: true,\n update(next) { try { sheet.replaceSync(next); } catch { /* Keeps the last good rules. */ } },\n remove() {\n if (!on) return;\n on = false;\n try { target.adoptedStyleSheets = (target.adoptedStyleSheets ?? []).filter(item => item !== sheet); } catch { /* Root gone. */ }\n },\n };\n }\n }\n // Fallback: a `<style>` element as the root's last child (a document: its <head>).\n const doc = documentOf(target);\n const style = doc.createElement('style');\n style.textContent = css;\n const parent: Node = isDocument(target) ? (target.head ?? target.documentElement) : target;\n parent.appendChild(style);\n return {\n get sheet() { return style.sheet; },\n adopted: false,\n update(next) { style.textContent = next; },\n remove() { style.remove(); },\n };\n}\n"]}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export type TextNetOptions = {
|
|
2
|
+
/** Exact original text -> replacement. A text that is not a key is left alone. */
|
|
3
|
+
map: ReadonlyMap<string, string>;
|
|
4
|
+
/** Attributes to cover (default `aria-label`, `placeholder`, `title`). */
|
|
5
|
+
attributes?: readonly string[];
|
|
6
|
+
/** Elements whose content is never touched (default: scripts, styles, editable text). */
|
|
7
|
+
skip?: string;
|
|
8
|
+
};
|
|
9
|
+
export type TextNetHandle = {
|
|
10
|
+
/** Text nodes and attributes currently replaced. */
|
|
11
|
+
count(): number;
|
|
12
|
+
/** Restores every node and attribute to the site's own value and stops observing. */
|
|
13
|
+
dispose(): void;
|
|
14
|
+
};
|
|
15
|
+
export declare function installTextNet(win: Window, options: TextNetOptions): TextNetHandle;
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
// A DOM safety net for strings a catalog hook cannot reach (published as
|
|
2
|
+
// `waybetter/runtime/textNet`): labels the server sends already worded, or text that is painted
|
|
3
|
+
// before the hook can act. It replaces exact texts in text nodes and in `aria-label`,
|
|
4
|
+
// `placeholder` and `title`, keeps the site's own value per node, and puts everything back when it
|
|
5
|
+
// is disposed. It is secondary to a catalog hook: it cannot see parameters or plural forms, and a
|
|
6
|
+
// rendered text only maps back to one key in a language without homonyms.
|
|
7
|
+
//
|
|
8
|
+
// Text is written through `nodeValue` / `setAttribute` (never `textContent` or HTML), so the site's
|
|
9
|
+
// framework keeps owning its nodes; when the site rewrites a node, the net looks at it again.
|
|
10
|
+
const DEFAULT_ATTRIBUTES = ['aria-label', 'placeholder', 'title'];
|
|
11
|
+
const DEFAULT_SKIP = 'script, style, noscript, textarea, [contenteditable=""], [contenteditable="true"]';
|
|
12
|
+
const TEXT_NODE = 3;
|
|
13
|
+
const ELEMENT_NODE = 1;
|
|
14
|
+
const SHOW_TEXT = 4;
|
|
15
|
+
export function installTextNet(win, options) {
|
|
16
|
+
const doc = win.document;
|
|
17
|
+
const attributes = options.attributes ?? DEFAULT_ATTRIBUTES;
|
|
18
|
+
const skip = options.skip ?? DEFAULT_SKIP;
|
|
19
|
+
const map = options.map;
|
|
20
|
+
/** The site's own value and ours, per text node. */
|
|
21
|
+
const texts = new WeakMap();
|
|
22
|
+
/** The same per element and attribute. */
|
|
23
|
+
const attrs = new WeakMap();
|
|
24
|
+
let count = 0;
|
|
25
|
+
let active = true;
|
|
26
|
+
const skipped = (element) => !!element && !!skip && !!element.closest(skip);
|
|
27
|
+
const text = (node) => {
|
|
28
|
+
const value = node.nodeValue ?? '';
|
|
29
|
+
const kept = texts.get(node);
|
|
30
|
+
if (kept) {
|
|
31
|
+
if (value === kept.applied)
|
|
32
|
+
return;
|
|
33
|
+
// The site wrote the node again: what it wrote is the new original.
|
|
34
|
+
texts.delete(node);
|
|
35
|
+
count -= 1;
|
|
36
|
+
}
|
|
37
|
+
const next = map.get(value);
|
|
38
|
+
if (next === undefined || next === value || skipped(node.parentElement))
|
|
39
|
+
return;
|
|
40
|
+
texts.set(node, { original: value, applied: next });
|
|
41
|
+
count += 1;
|
|
42
|
+
node.nodeValue = next;
|
|
43
|
+
};
|
|
44
|
+
const attribute = (element, name) => {
|
|
45
|
+
const value = element.getAttribute(name);
|
|
46
|
+
const kept = attrs.get(element)?.get(name);
|
|
47
|
+
if (kept) {
|
|
48
|
+
if (value === kept.applied)
|
|
49
|
+
return;
|
|
50
|
+
attrs.get(element).delete(name);
|
|
51
|
+
count -= 1;
|
|
52
|
+
}
|
|
53
|
+
if (value === null)
|
|
54
|
+
return;
|
|
55
|
+
const next = map.get(value);
|
|
56
|
+
if (next === undefined || next === value || skipped(element))
|
|
57
|
+
return;
|
|
58
|
+
let own = attrs.get(element);
|
|
59
|
+
if (!own)
|
|
60
|
+
attrs.set(element, own = new Map());
|
|
61
|
+
own.set(name, { original: value, applied: next });
|
|
62
|
+
count += 1;
|
|
63
|
+
element.setAttribute(name, next);
|
|
64
|
+
};
|
|
65
|
+
const sweep = (root) => {
|
|
66
|
+
if (root.nodeType === TEXT_NODE) {
|
|
67
|
+
text(root);
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
if (root.nodeType !== ELEMENT_NODE)
|
|
71
|
+
return;
|
|
72
|
+
const element = root;
|
|
73
|
+
const walker = doc.createTreeWalker(element, SHOW_TEXT);
|
|
74
|
+
while (walker.nextNode())
|
|
75
|
+
text(walker.currentNode);
|
|
76
|
+
for (const name of attributes) {
|
|
77
|
+
if (element.hasAttribute(name))
|
|
78
|
+
attribute(element, name);
|
|
79
|
+
for (const child of element.querySelectorAll(`[${name}]`))
|
|
80
|
+
attribute(child, name);
|
|
81
|
+
}
|
|
82
|
+
};
|
|
83
|
+
const observer = new win.MutationObserver(records => {
|
|
84
|
+
if (!active)
|
|
85
|
+
return;
|
|
86
|
+
for (const record of records) {
|
|
87
|
+
if (record.type === 'characterData')
|
|
88
|
+
text(record.target);
|
|
89
|
+
else if (record.type === 'attributes') {
|
|
90
|
+
if (record.attributeName)
|
|
91
|
+
attribute(record.target, record.attributeName);
|
|
92
|
+
}
|
|
93
|
+
else
|
|
94
|
+
for (const node of record.addedNodes)
|
|
95
|
+
sweep(node);
|
|
96
|
+
}
|
|
97
|
+
});
|
|
98
|
+
if (map.size) {
|
|
99
|
+
if (doc.documentElement)
|
|
100
|
+
sweep(doc.documentElement);
|
|
101
|
+
observer.observe(doc, { subtree: true, childList: true, characterData: true, attributes: true, attributeFilter: [...attributes] });
|
|
102
|
+
}
|
|
103
|
+
return {
|
|
104
|
+
count: () => count,
|
|
105
|
+
dispose() {
|
|
106
|
+
if (!active)
|
|
107
|
+
return;
|
|
108
|
+
active = false;
|
|
109
|
+
observer.disconnect();
|
|
110
|
+
if (!doc.documentElement)
|
|
111
|
+
return;
|
|
112
|
+
const walker = doc.createTreeWalker(doc.documentElement, SHOW_TEXT);
|
|
113
|
+
while (walker.nextNode()) {
|
|
114
|
+
const node = walker.currentNode;
|
|
115
|
+
const kept = texts.get(node);
|
|
116
|
+
if (kept && node.nodeValue === kept.applied)
|
|
117
|
+
node.nodeValue = kept.original;
|
|
118
|
+
texts.delete(node);
|
|
119
|
+
}
|
|
120
|
+
for (const name of attributes) {
|
|
121
|
+
for (const element of doc.querySelectorAll(`[${name}]`)) {
|
|
122
|
+
const kept = attrs.get(element)?.get(name);
|
|
123
|
+
if (kept && element.getAttribute(name) === kept.applied)
|
|
124
|
+
element.setAttribute(name, kept.original);
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
count = 0;
|
|
128
|
+
},
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
//# sourceMappingURL=textNet.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"textNet.js","sourceRoot":"","sources":["../../../runtime/src/textNet.ts"],"names":[],"mappings":"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","sourcesContent":["// A DOM safety net for strings a catalog hook cannot reach (published as\n// `waybetter/runtime/textNet`): labels the server sends already worded, or text that is painted\n// before the hook can act. It replaces exact texts in text nodes and in `aria-label`,\n// `placeholder` and `title`, keeps the site's own value per node, and puts everything back when it\n// is disposed. It is secondary to a catalog hook: it cannot see parameters or plural forms, and a\n// rendered text only maps back to one key in a language without homonyms.\n//\n// Text is written through `nodeValue` / `setAttribute` (never `textContent` or HTML), so the site's\n// framework keeps owning its nodes; when the site rewrites a node, the net looks at it again.\n\nexport type TextNetOptions = {\n /** Exact original text -> replacement. A text that is not a key is left alone. */\n map: ReadonlyMap<string, string>;\n /** Attributes to cover (default `aria-label`, `placeholder`, `title`). */\n attributes?: readonly string[];\n /** Elements whose content is never touched (default: scripts, styles, editable text). */\n skip?: string;\n};\n\nexport type TextNetHandle = {\n /** Text nodes and attributes currently replaced. */\n count(): number;\n /** Restores every node and attribute to the site's own value and stops observing. */\n dispose(): void;\n};\n\nconst DEFAULT_ATTRIBUTES = ['aria-label', 'placeholder', 'title'];\nconst DEFAULT_SKIP = 'script, style, noscript, textarea, [contenteditable=\"\"], [contenteditable=\"true\"]';\nconst TEXT_NODE = 3;\nconst ELEMENT_NODE = 1;\nconst SHOW_TEXT = 4;\n\nexport function installTextNet(win: Window, options: TextNetOptions): TextNetHandle {\n const doc = win.document;\n const attributes = options.attributes ?? DEFAULT_ATTRIBUTES;\n const skip = options.skip ?? DEFAULT_SKIP;\n const map = options.map;\n /** The site's own value and ours, per text node. */\n const texts = new WeakMap<Node, { original: string; applied: string }>();\n /** The same per element and attribute. */\n const attrs = new WeakMap<Element, Map<string, { original: string; applied: string }>>();\n let count = 0;\n let active = true;\n\n const skipped = (element: Element | null) => !!element && !!skip && !!element.closest(skip);\n\n const text = (node: Node) => {\n const value = node.nodeValue ?? '';\n const kept = texts.get(node);\n if (kept) {\n if (value === kept.applied) return;\n // The site wrote the node again: what it wrote is the new original.\n texts.delete(node);\n count -= 1;\n }\n const next = map.get(value);\n if (next === undefined || next === value || skipped(node.parentElement)) return;\n texts.set(node, { original: value, applied: next });\n count += 1;\n node.nodeValue = next;\n };\n\n const attribute = (element: Element, name: string) => {\n const value = element.getAttribute(name);\n const kept = attrs.get(element)?.get(name);\n if (kept) {\n if (value === kept.applied) return;\n attrs.get(element)!.delete(name);\n count -= 1;\n }\n if (value === null) return;\n const next = map.get(value);\n if (next === undefined || next === value || skipped(element)) return;\n let own = attrs.get(element);\n if (!own) attrs.set(element, own = new Map());\n own.set(name, { original: value, applied: next });\n count += 1;\n element.setAttribute(name, next);\n };\n\n const sweep = (root: Node) => {\n if (root.nodeType === TEXT_NODE) { text(root); return; }\n if (root.nodeType !== ELEMENT_NODE) return;\n const element = root as Element;\n const walker = doc.createTreeWalker(element, SHOW_TEXT);\n while (walker.nextNode()) text(walker.currentNode);\n for (const name of attributes) {\n if (element.hasAttribute(name)) attribute(element, name);\n for (const child of element.querySelectorAll(`[${name}]`)) attribute(child, name);\n }\n };\n\n const observer = new (win as unknown as { MutationObserver: typeof MutationObserver }).MutationObserver(records => {\n if (!active) return;\n for (const record of records) {\n if (record.type === 'characterData') text(record.target);\n else if (record.type === 'attributes') { if (record.attributeName) attribute(record.target as Element, record.attributeName); }\n else for (const node of record.addedNodes) sweep(node);\n }\n });\n if (map.size) {\n if (doc.documentElement) sweep(doc.documentElement);\n observer.observe(doc, { subtree: true, childList: true, characterData: true, attributes: true, attributeFilter: [...attributes] });\n }\n\n return {\n count: () => count,\n dispose() {\n if (!active) return;\n active = false;\n observer.disconnect();\n if (!doc.documentElement) return;\n const walker = doc.createTreeWalker(doc.documentElement, SHOW_TEXT);\n while (walker.nextNode()) {\n const node = walker.currentNode;\n const kept = texts.get(node);\n if (kept && node.nodeValue === kept.applied) node.nodeValue = kept.original;\n texts.delete(node);\n }\n for (const name of attributes) {\n for (const element of doc.querySelectorAll(`[${name}]`)) {\n const kept = attrs.get(element)?.get(name);\n if (kept && element.getAttribute(name) === kept.applied) element.setAttribute(name, kept.original);\n }\n }\n count = 0;\n },\n };\n}\n"]}
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
export type ThemeMode = 'light' | 'dark';
|
|
2
|
+
/** Every color role a theme has, resolved (derived roles filled in, legibility enforced). */
|
|
3
|
+
export type ResolvedColors = {
|
|
4
|
+
/** The main surface behind content (the site's column background). */
|
|
5
|
+
bg: string;
|
|
6
|
+
/** A raised surface (cards, inputs). */
|
|
7
|
+
surface: string;
|
|
8
|
+
/** Hover / selected surface, one step above `surface`. */
|
|
9
|
+
elevated: string;
|
|
10
|
+
border: string;
|
|
11
|
+
text: string;
|
|
12
|
+
/** Secondary text. */
|
|
13
|
+
muted: string;
|
|
14
|
+
accent: string;
|
|
15
|
+
/** Readable text on `accent`. */
|
|
16
|
+
onAccent: string;
|
|
17
|
+
/** The site's filled primary button and its label. */
|
|
18
|
+
inverse: string;
|
|
19
|
+
onInverse: string;
|
|
20
|
+
/** The canvas behind the columns (equals `bg` unless the theme paints a page). */
|
|
21
|
+
page: string;
|
|
22
|
+
};
|
|
23
|
+
export type ResolvedTheme = {
|
|
24
|
+
/** Theme id (`x` for the site's own look). */
|
|
25
|
+
id: string;
|
|
26
|
+
name: string;
|
|
27
|
+
mode: ThemeMode;
|
|
28
|
+
/** True when the site's own colors are shown (no theme colors). */
|
|
29
|
+
siteDefault: boolean;
|
|
30
|
+
colors: ResolvedColors;
|
|
31
|
+
/** Card / dialog corner radius in px. */
|
|
32
|
+
radius: number;
|
|
33
|
+
/** Button corner radius in px (9999 = pill). */
|
|
34
|
+
buttonRadius: number;
|
|
35
|
+
/** CSS `font-family` stack of the interface. */
|
|
36
|
+
font: string;
|
|
37
|
+
/**
|
|
38
|
+
* Which font goes where: every role resolved (a role that inherits carries the stack it inherits).
|
|
39
|
+
* Always present after `normalizeResolved`; adapters without font roles may leave it out.
|
|
40
|
+
*/
|
|
41
|
+
fonts?: ResolvedFonts;
|
|
42
|
+
};
|
|
43
|
+
/**
|
|
44
|
+
* Font roles: `interface` (the site's UI), `post` (main content text), `heading` (names and
|
|
45
|
+
* headings), `numbers` (counts), `mono` (code), `chrome` (the app's own window: tabs, address bar,
|
|
46
|
+
* panel) and `dialog` (plugin dialogs and toasts from the UI kit).
|
|
47
|
+
*/
|
|
48
|
+
export declare const FONT_ROLE_NAMES: readonly ["interface", "post", "heading", "numbers", "mono", "chrome", "dialog"];
|
|
49
|
+
export type FontRoleName = typeof FONT_ROLE_NAMES[number];
|
|
50
|
+
export type ResolvedFont = {
|
|
51
|
+
/** CSS `font-family` stack. */
|
|
52
|
+
stack: string;
|
|
53
|
+
/** Weight the role asks for, or null to keep the text's own. */
|
|
54
|
+
weight: number | null;
|
|
55
|
+
/** Size relative to the site's (1 = unchanged). */
|
|
56
|
+
size: number;
|
|
57
|
+
/** Letter spacing in em, or null to keep the text's own. */
|
|
58
|
+
tracking: number | null;
|
|
59
|
+
/** Tabular (fixed-width) figures. */
|
|
60
|
+
tabular: boolean;
|
|
61
|
+
/** True when the role inherits its family from another role or the site. */
|
|
62
|
+
inherited: boolean;
|
|
63
|
+
};
|
|
64
|
+
export type ResolvedFonts = Record<FontRoleName, ResolvedFont>;
|
|
65
|
+
/** Monospaced families, in order: what a `mono` role that inherits (or a source without fonts) gets. */
|
|
66
|
+
export declare const MONO_FAMILIES: string[];
|
|
67
|
+
export declare const MONO_FONT: string;
|
|
68
|
+
/** What a site adapter provides: the current resolved theme and change notifications. */
|
|
69
|
+
export type ThemeSource = {
|
|
70
|
+
current(): ResolvedTheme | null;
|
|
71
|
+
onChange(listener: () => void): () => void;
|
|
72
|
+
};
|
|
73
|
+
export type ThemeApi = {
|
|
74
|
+
/** The active theme, resolved. A frozen snapshot: call again after `onChange`. */
|
|
75
|
+
current(): ResolvedTheme;
|
|
76
|
+
/** Calls `listener(theme)` after the theme (or the site's light/dark mode) changes. Returns a dispose. */
|
|
77
|
+
onChange(listener: (theme: ResolvedTheme) => void): () => void;
|
|
78
|
+
};
|
|
79
|
+
/** Where the theme file JSON Schema is published with the `waybetter` npm package (`"$schema"` in theme files). */
|
|
80
|
+
export declare const THEME_SCHEMA_URL = "https://unpkg.com/waybetter/theme.schema.json";
|
|
81
|
+
export declare const FALLBACK_FONT = "system-ui, -apple-system, \"Segoe UI\", Roboto, Helvetica, Arial, sans-serif";
|
|
82
|
+
/** `#rrggbb` → [r, g, b]. */
|
|
83
|
+
export declare function hexToRgb(hex: string): [number, number, number];
|
|
84
|
+
/** WCAG relative luminance of `#rrggbb`. */
|
|
85
|
+
export declare function relativeLuminance(hex: string): number;
|
|
86
|
+
/** WCAG contrast ratio of two `#rrggbb` colors (1–21). */
|
|
87
|
+
export declare function contrastRatio(a: string, b: string): number;
|
|
88
|
+
/** White when it reaches 4.5:1 on `hex`, otherwise whichever of black and white reads better. */
|
|
89
|
+
export declare function readableOn(hex: string): string;
|
|
90
|
+
/** `rgb(…)` / `rgba(…)` / `#rgb` / `#rrggbb` to `#rrggbb`; null when it is transparent or unparsable. */
|
|
91
|
+
export declare function toHex(value: string | null | undefined): string | null;
|
|
92
|
+
/** `a` moved toward `b` by `t` (0–1), per channel. */
|
|
93
|
+
export declare function mix(a: string, b: string, t: number): string;
|
|
94
|
+
/**
|
|
95
|
+
* A complete resolved theme from a few page colors (background, text, accent), for sites or moments
|
|
96
|
+
* without a theme engine. Surfaces, border and muted text sit between background and text.
|
|
97
|
+
*/
|
|
98
|
+
export declare function themeFromColors(bg: string, text: string, accent: string, extra?: Partial<Omit<ResolvedTheme, 'colors'>>): ResolvedTheme;
|
|
99
|
+
/** The page's own colors (computed body background and text), used when no theme source exists. */
|
|
100
|
+
export declare function readPageTheme(win: Window, accent?: string): ResolvedTheme;
|
|
101
|
+
/** Fills in any role a source left out and freezes the result. */
|
|
102
|
+
export declare function normalizeResolved(theme: ResolvedTheme): ResolvedTheme;
|
|
103
|
+
/** Every role filled in: missing roles inherit the interface font (`mono` a monospaced stack). */
|
|
104
|
+
export declare function normalizeFonts(fonts: Partial<Record<FontRoleName, Partial<ResolvedFont>>> | undefined, font: string): ResolvedFonts;
|
|
105
|
+
/**
|
|
106
|
+
* The theme as CSS custom properties: `--wb-bg`, `--wb-surface`, `--wb-elevated`, `--wb-border`,
|
|
107
|
+
* `--wb-text`, `--wb-muted`, `--wb-accent`, `--wb-on-accent`, `--wb-inverse`, `--wb-on-inverse`,
|
|
108
|
+
* `--wb-page`, `--wb-radius`, `--wb-button-radius`, `--wb-font`, `--wb-mode` (`light`/`dark`), and
|
|
109
|
+
* one stack per font role: `--wb-font-interface`, `--wb-font-post`, `--wb-font-heading`,
|
|
110
|
+
* `--wb-font-numbers`, `--wb-font-mono`, `--wb-font-chrome`, `--wb-font-dialog`.
|
|
111
|
+
*/
|
|
112
|
+
export declare function themeVars(theme: ResolvedTheme): Record<string, string>;
|
|
113
|
+
/** `:root{--wb-…}` for a `<style>` element (values come from a resolved theme, never raw input). */
|
|
114
|
+
export declare function themeVarsCss(theme: ResolvedTheme, selector?: string): string;
|
|
115
|
+
/** A stable key: equal keys mean nothing visible changed. */
|
|
116
|
+
export declare const themeKey: (theme: ResolvedTheme) => string;
|
|
117
|
+
/**
|
|
118
|
+
* `api.theme`. With a site `source` it reports the site's resolved theme (falling back to the page's
|
|
119
|
+
* computed colors while the source has none); without one, only the page's colors.
|
|
120
|
+
*/
|
|
121
|
+
export declare function createThemeApi(win: Window, source?: ThemeSource, fallbackAccent?: string): ThemeApi;
|