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,267 @@
|
|
|
1
|
+
// Translate mode for string packs (published as `waybetter/runtime/stringPackTranslate`): the site's
|
|
2
|
+
// strings carry an invisible marker naming their key, so clicking a word on the page tells which
|
|
3
|
+
// key it is. The author types a replacement (checked with the pack rules right there), the edits
|
|
4
|
+
// collect in the tab as a draft pack that applies on the next reload, and Export copies the pack
|
|
5
|
+
// file. Nothing leaves the page; the draft lives in the tab's session storage.
|
|
6
|
+
//
|
|
7
|
+
// The markers change the site's text (invisible characters at the end of each string), so exact
|
|
8
|
+
// comparisons in the site's own code may notice: translate mode is for authors, never on by default,
|
|
9
|
+
// and leaving it reloads the page without markers.
|
|
10
|
+
import { compilePack, inventoryLookup, validateString } from "./stringPacks.js";
|
|
11
|
+
const START = '';
|
|
12
|
+
const DIGITS = ['', '', '', ''];
|
|
13
|
+
const MARKED = /([]+)/g;
|
|
14
|
+
export function createMarker() {
|
|
15
|
+
const ids = [];
|
|
16
|
+
const index = new Map();
|
|
17
|
+
const code = (id) => {
|
|
18
|
+
let n = index.get(id);
|
|
19
|
+
if (n === undefined) {
|
|
20
|
+
n = ids.length;
|
|
21
|
+
ids.push(id);
|
|
22
|
+
index.set(id, n);
|
|
23
|
+
}
|
|
24
|
+
let digits = '';
|
|
25
|
+
do {
|
|
26
|
+
digits = DIGITS[n % 4] + digits;
|
|
27
|
+
n = Math.floor(n / 4);
|
|
28
|
+
} while (n);
|
|
29
|
+
return START + digits + START;
|
|
30
|
+
};
|
|
31
|
+
return {
|
|
32
|
+
mark(id, value) {
|
|
33
|
+
if (typeof value === 'string')
|
|
34
|
+
return value + code(id);
|
|
35
|
+
if (typeof value === 'function') {
|
|
36
|
+
const original = value;
|
|
37
|
+
return function (...args) {
|
|
38
|
+
const out = original.apply(this, args);
|
|
39
|
+
return typeof out === 'string' ? out + code(id) : out;
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
return value;
|
|
43
|
+
},
|
|
44
|
+
ids(text) {
|
|
45
|
+
const out = [];
|
|
46
|
+
for (const match of text.matchAll(MARKED)) {
|
|
47
|
+
let n = 0;
|
|
48
|
+
for (const ch of match[1])
|
|
49
|
+
n = n * 4 + DIGITS.indexOf(ch);
|
|
50
|
+
const id = ids[n];
|
|
51
|
+
if (id && !out.includes(id))
|
|
52
|
+
out.push(id);
|
|
53
|
+
}
|
|
54
|
+
return out;
|
|
55
|
+
},
|
|
56
|
+
strip: text => text.replace(MARKED, ''),
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
export const DRAFT_KEY = 'wayBetter.translateDraft';
|
|
60
|
+
export function readDraft(storage) {
|
|
61
|
+
try {
|
|
62
|
+
const value = JSON.parse(storage.getItem(DRAFT_KEY) ?? 'null');
|
|
63
|
+
return value && typeof value === 'object' && typeof value.strings === 'object' && value.strings !== null ? value : null;
|
|
64
|
+
}
|
|
65
|
+
catch {
|
|
66
|
+
return null;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
/** The draft as a pack document for `site`/`catalog`. */
|
|
70
|
+
export function draftPack(draft, site, catalog) {
|
|
71
|
+
return {
|
|
72
|
+
format: 1, site, catalog, language: draft.language || 'en-x-draft', name: draft.name || 'My strings', authors: ['Me'],
|
|
73
|
+
version: '0.1.0', strings: { ...draft.strings },
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
/** Checks one edit against the key's shape; `null` when it can be used. */
|
|
77
|
+
export function checkEdit(lookup, id, value) {
|
|
78
|
+
const shape = lookup(id);
|
|
79
|
+
if (!shape)
|
|
80
|
+
return 'this key is not in the inventory';
|
|
81
|
+
const result = validateString(shape, value);
|
|
82
|
+
return 'reason' in result ? result.reason : null;
|
|
83
|
+
}
|
|
84
|
+
/** English defaults (the app passes its own words). */
|
|
85
|
+
export const TRANSLATE_WORDS = {
|
|
86
|
+
bar: 'Translate mode', hint: 'Click a word to change it.', edits: count => `${count} ${count === 1 ? 'edit' : 'edits'}`,
|
|
87
|
+
exportPack: 'Copy pack file', copied: 'Pack file copied', exit: 'Leave', reload: 'Reload to see it',
|
|
88
|
+
key: 'Key', original: 'Now', parameters: 'Parameters', plural: 'plural', save: 'Save', cancel: 'Cancel', remove: 'Remove edit',
|
|
89
|
+
notTranslatable: 'This string cannot be changed by a pack yet.', choose: 'Which one?',
|
|
90
|
+
};
|
|
91
|
+
const CSS = `
|
|
92
|
+
:host { all: initial; }
|
|
93
|
+
.bar { position: fixed; left: 50%; bottom: 16px; transform: translateX(-50%); z-index: 2147483646; display: flex; gap: 10px; align-items: center;
|
|
94
|
+
padding: 8px 12px; border-radius: 12px; background: #111827; color: #f9fafb; font: 13px/1.3 system-ui, sans-serif; box-shadow: 0 8px 24px rgba(0,0,0,.35); }
|
|
95
|
+
.bar b { font-weight: 600; } .bar span { color: #cbd5e1; }
|
|
96
|
+
button { font: inherit; border: 0; border-radius: 8px; padding: 6px 10px; cursor: pointer; background: #334155; color: #f9fafb; }
|
|
97
|
+
button.primary { background: #2563eb; }
|
|
98
|
+
.pop { position: fixed; z-index: 2147483647; width: 360px; max-width: calc(100vw - 24px); padding: 12px; border-radius: 12px; background: #fff; color: #111827;
|
|
99
|
+
font: 13px/1.4 system-ui, sans-serif; box-shadow: 0 12px 32px rgba(0,0,0,.3); display: grid; gap: 8px; }
|
|
100
|
+
.pop small { color: #475569; } .pop code { font-size: 12px; color: #334155; }
|
|
101
|
+
.pop textarea { width: 100%; box-sizing: border-box; min-height: 64px; font: inherit; padding: 6px; border: 1px solid #cbd5e1; border-radius: 8px; }
|
|
102
|
+
.pop .row { display: flex; gap: 8px; justify-content: flex-end; } .pop .err { color: #b91c1c; }
|
|
103
|
+
.pop .pick { display: grid; gap: 4px; } .pop .pick button { text-align: left; background: #e2e8f0; color: #111827; }
|
|
104
|
+
`;
|
|
105
|
+
/**
|
|
106
|
+
* The page part of translate mode: a bar (edits, copy the pack file, leave) and an editor for the
|
|
107
|
+
* string under a click. Clicks on marked text are the editor's while the mode is on.
|
|
108
|
+
*/
|
|
109
|
+
export function installTranslateUi(win, options) {
|
|
110
|
+
const doc = win.document;
|
|
111
|
+
const currentWords = () => ({ ...TRANSLATE_WORDS, ...(typeof options.words === 'function' ? options.words() : options.words) });
|
|
112
|
+
const lookup = inventoryLookup(options.inventory);
|
|
113
|
+
const storage = win.sessionStorage;
|
|
114
|
+
const draft = () => readDraft(storage) ?? { language: '', name: '', strings: {} };
|
|
115
|
+
const save = (next) => { try {
|
|
116
|
+
storage.setItem(DRAFT_KEY, JSON.stringify(next));
|
|
117
|
+
}
|
|
118
|
+
catch { /* storage full or blocked */ } };
|
|
119
|
+
const host = doc.createElement('wb-translate');
|
|
120
|
+
const root = host.attachShadow({ mode: 'open' });
|
|
121
|
+
const style = doc.createElement('style');
|
|
122
|
+
style.textContent = CSS;
|
|
123
|
+
root.append(style);
|
|
124
|
+
const bar = doc.createElement('div');
|
|
125
|
+
bar.className = 'bar';
|
|
126
|
+
root.append(bar);
|
|
127
|
+
let pop = null;
|
|
128
|
+
let changed = false;
|
|
129
|
+
const button = (label, onClick, primary = false) => {
|
|
130
|
+
const el = doc.createElement('button');
|
|
131
|
+
el.textContent = label;
|
|
132
|
+
if (primary)
|
|
133
|
+
el.className = 'primary';
|
|
134
|
+
el.addEventListener('click', event => { event.preventDefault(); event.stopPropagation(); onClick(); });
|
|
135
|
+
return el;
|
|
136
|
+
};
|
|
137
|
+
const renderBar = () => {
|
|
138
|
+
const words = currentWords();
|
|
139
|
+
bar.replaceChildren();
|
|
140
|
+
const title = doc.createElement('b');
|
|
141
|
+
title.textContent = words.bar;
|
|
142
|
+
const hint = doc.createElement('span');
|
|
143
|
+
hint.textContent = `${words.hint} · ${words.edits(Object.keys(draft().strings).length)}`;
|
|
144
|
+
bar.append(title, hint);
|
|
145
|
+
if (changed)
|
|
146
|
+
bar.append(button(words.reload, () => win.location.reload(), true));
|
|
147
|
+
bar.append(button(words.exportPack, () => {
|
|
148
|
+
const text = JSON.stringify(draftPack(draft(), options.site, options.catalog), null, 2);
|
|
149
|
+
void win.navigator.clipboard?.writeText(text).then(() => { hint.textContent = words.copied; }).catch(() => { });
|
|
150
|
+
}));
|
|
151
|
+
bar.append(button(words.exit, options.exit));
|
|
152
|
+
};
|
|
153
|
+
const closePop = () => { pop?.remove(); pop = null; };
|
|
154
|
+
const edit = (id, x, y, now) => {
|
|
155
|
+
const words = currentWords();
|
|
156
|
+
closePop();
|
|
157
|
+
pop = doc.createElement('div');
|
|
158
|
+
pop.className = 'pop';
|
|
159
|
+
pop.style.left = `${Math.max(12, Math.min(x, win.innerWidth - 372))}px`;
|
|
160
|
+
pop.style.top = `${Math.max(12, Math.min(y + 12, win.innerHeight - 260))}px`;
|
|
161
|
+
const shape = lookup(id);
|
|
162
|
+
const head = doc.createElement('small');
|
|
163
|
+
head.textContent = `${words.key}: `;
|
|
164
|
+
const code = doc.createElement('code');
|
|
165
|
+
code.textContent = id;
|
|
166
|
+
head.append(code);
|
|
167
|
+
const current = doc.createElement('div');
|
|
168
|
+
current.textContent = `${words.original}: ${now}`;
|
|
169
|
+
pop.append(head, current);
|
|
170
|
+
if (!shape || (shape.kind !== 'text' && shape.kind !== 'message')) {
|
|
171
|
+
const note = doc.createElement('div');
|
|
172
|
+
note.textContent = words.notTranslatable;
|
|
173
|
+
pop.append(note, button(words.cancel, closePop));
|
|
174
|
+
root.append(pop);
|
|
175
|
+
return;
|
|
176
|
+
}
|
|
177
|
+
if (shape.params?.length) {
|
|
178
|
+
const params = doc.createElement('small');
|
|
179
|
+
params.textContent = `${words.parameters}: ${shape.params.map(name => `{${name}}${shape.plural?.includes(name) ? ` (${words.plural})` : ''}`).join(', ')}`;
|
|
180
|
+
pop.append(params);
|
|
181
|
+
}
|
|
182
|
+
const input = doc.createElement('textarea');
|
|
183
|
+
input.value = draft().strings[id] ?? now;
|
|
184
|
+
const error = doc.createElement('div');
|
|
185
|
+
error.className = 'err';
|
|
186
|
+
const row = doc.createElement('div');
|
|
187
|
+
row.className = 'row';
|
|
188
|
+
if (draft().strings[id] !== undefined) {
|
|
189
|
+
row.append(button(words.remove, () => { const next = draft(); delete next.strings[id]; save(next); changed = true; closePop(); renderBar(); }));
|
|
190
|
+
}
|
|
191
|
+
row.append(button(words.cancel, closePop), button(words.save, () => {
|
|
192
|
+
const value = input.value.trim();
|
|
193
|
+
const problem = checkEdit(lookup, id, value);
|
|
194
|
+
if (problem) {
|
|
195
|
+
error.textContent = problem;
|
|
196
|
+
return;
|
|
197
|
+
}
|
|
198
|
+
const next = draft();
|
|
199
|
+
next.strings[id] = value;
|
|
200
|
+
save(next);
|
|
201
|
+
changed = true;
|
|
202
|
+
closePop();
|
|
203
|
+
renderBar();
|
|
204
|
+
}, true));
|
|
205
|
+
pop.append(input, error, row);
|
|
206
|
+
root.append(pop);
|
|
207
|
+
input.focus();
|
|
208
|
+
};
|
|
209
|
+
/** The marked keys at a click: the element's own text and labels, then up to three parents. */
|
|
210
|
+
const keysAt = (target) => {
|
|
211
|
+
for (let el = target, depth = 0; el && depth < 4; el = el.parentElement, depth += 1) {
|
|
212
|
+
const texts = [el.textContent ?? '', el.getAttribute('aria-label') ?? '', el.getAttribute('placeholder') ?? '', el.getAttribute('title') ?? ''];
|
|
213
|
+
const found = texts.flatMap(text => options.marker.ids(text).map(id => ({ id, text: options.marker.strip(text) })));
|
|
214
|
+
if (found.length)
|
|
215
|
+
return found.filter((item, i) => found.findIndex(other => other.id === item.id) === i).slice(0, 8);
|
|
216
|
+
}
|
|
217
|
+
return [];
|
|
218
|
+
};
|
|
219
|
+
const onClick = (event) => {
|
|
220
|
+
const words = currentWords();
|
|
221
|
+
if (event.composedPath().includes(host))
|
|
222
|
+
return;
|
|
223
|
+
const found = keysAt(event.target);
|
|
224
|
+
if (!found.length)
|
|
225
|
+
return;
|
|
226
|
+
event.preventDefault();
|
|
227
|
+
event.stopPropagation();
|
|
228
|
+
if (found.length === 1) {
|
|
229
|
+
edit(found[0].id, event.clientX, event.clientY, found[0].text);
|
|
230
|
+
return;
|
|
231
|
+
}
|
|
232
|
+
closePop();
|
|
233
|
+
pop = doc.createElement('div');
|
|
234
|
+
pop.className = 'pop';
|
|
235
|
+
pop.style.left = `${Math.max(12, Math.min(event.clientX, win.innerWidth - 372))}px`;
|
|
236
|
+
pop.style.top = `${Math.max(12, Math.min(event.clientY + 12, win.innerHeight - 260))}px`;
|
|
237
|
+
const pick = doc.createElement('div');
|
|
238
|
+
pick.className = 'pick';
|
|
239
|
+
const label = doc.createElement('small');
|
|
240
|
+
label.textContent = words.choose;
|
|
241
|
+
pick.append(label, ...found.map(item => button(`${item.text.slice(0, 60)} · ${item.id}`, () => edit(item.id, event.clientX, event.clientY, item.text))));
|
|
242
|
+
pop.append(pick, button(words.cancel, closePop));
|
|
243
|
+
root.append(pop);
|
|
244
|
+
};
|
|
245
|
+
const mount = () => { (doc.body ?? doc.documentElement).append(host); renderBar(); };
|
|
246
|
+
if (doc.body)
|
|
247
|
+
mount();
|
|
248
|
+
else
|
|
249
|
+
doc.addEventListener('DOMContentLoaded', mount, { once: true });
|
|
250
|
+
win.addEventListener('click', onClick, true);
|
|
251
|
+
return { dispose() { win.removeEventListener('click', onClick, true); host.remove(); } };
|
|
252
|
+
}
|
|
253
|
+
/** The draft as the last pack of a delivery (it applies over the others), when it has any string. */
|
|
254
|
+
export function withDraft(packs, storage, site, catalog, inventory) {
|
|
255
|
+
const draft = readDraft(storage);
|
|
256
|
+
if (!draft || !Object.keys(draft.strings).length)
|
|
257
|
+
return [...packs];
|
|
258
|
+
const pack = draftPack(draft, site, catalog);
|
|
259
|
+
try {
|
|
260
|
+
compilePack(pack, inventory);
|
|
261
|
+
}
|
|
262
|
+
catch {
|
|
263
|
+
return [...packs];
|
|
264
|
+
}
|
|
265
|
+
return [...packs, pack];
|
|
266
|
+
}
|
|
267
|
+
//# sourceMappingURL=stringPackTranslate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stringPackTranslate.js","sourceRoot":"","sources":["../../../runtime/src/stringPackTranslate.ts"],"names":[],"mappings":"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","sourcesContent":["// Translate mode for string packs (published as `waybetter/runtime/stringPackTranslate`): the site's\n// strings carry an invisible marker naming their key, so clicking a word on the page tells which\n// key it is. The author types a replacement (checked with the pack rules right there), the edits\n// collect in the tab as a draft pack that applies on the next reload, and Export copies the pack\n// file. Nothing leaves the page; the draft lives in the tab's session storage.\n//\n// The markers change the site's text (invisible characters at the end of each string), so exact\n// comparisons in the site's own code may notice: translate mode is for authors, never on by default,\n// and leaving it reloads the page without markers.\nimport { compilePack, inventoryLookup, validateString, type InventoryLookup, type PageInventory, type StringPack } from './stringPacks.ts';\n\nconst START = '';\nconst DIGITS = ['', '', '', ''];\nconst MARKED = /([]+)/g;\n\nexport type Marker = {\n /** The value with its key's marker (strings, and functions whose result is a string). */\n mark(id: string, value: unknown): unknown;\n /** The keys marked in a text, in order. */\n ids(text: string): string[];\n /** The text without markers. */\n strip(text: string): string;\n};\n\nexport function createMarker(): Marker {\n const ids: string[] = [];\n const index = new Map<string, number>();\n const code = (id: string) => {\n let n = index.get(id);\n if (n === undefined) { n = ids.length; ids.push(id); index.set(id, n); }\n let digits = '';\n do { digits = DIGITS[n % 4] + digits; n = Math.floor(n / 4); } while (n);\n return START + digits + START;\n };\n return {\n mark(id, value) {\n if (typeof value === 'string') return value + code(id);\n if (typeof value === 'function') {\n const original = value as (...args: unknown[]) => unknown;\n return function (this: unknown, ...args: unknown[]) {\n const out = original.apply(this, args);\n return typeof out === 'string' ? out + code(id) : out;\n };\n }\n return value;\n },\n ids(text) {\n const out: string[] = [];\n for (const match of text.matchAll(MARKED)) {\n let n = 0;\n for (const ch of match[1]!) n = n * 4 + DIGITS.indexOf(ch);\n const id = ids[n];\n if (id && !out.includes(id)) out.push(id);\n }\n return out;\n },\n strip: text => text.replace(MARKED, ''),\n };\n}\n\n/** The author's edits in this tab. */\nexport type TranslateDraft = { language: string; name: string; strings: Record<string, string> };\n\nexport const DRAFT_KEY = 'wayBetter.translateDraft';\n\nexport function readDraft(storage: Pick<Storage, 'getItem'>): TranslateDraft | null {\n try {\n const value = JSON.parse(storage.getItem(DRAFT_KEY) ?? 'null') as TranslateDraft | null;\n return value && typeof value === 'object' && typeof value.strings === 'object' && value.strings !== null ? value : null;\n } catch {\n return null;\n }\n}\n\n/** The draft as a pack document for `site`/`catalog`. */\nexport function draftPack(draft: TranslateDraft, site: string, catalog: string): StringPack {\n return {\n format: 1, site, catalog, language: draft.language || 'en-x-draft', name: draft.name || 'My strings', authors: ['Me'],\n version: '0.1.0', strings: { ...draft.strings },\n };\n}\n\n/** Checks one edit against the key's shape; `null` when it can be used. */\nexport function checkEdit(lookup: InventoryLookup, id: string, value: string): string | null {\n const shape = lookup(id);\n if (!shape) return 'this key is not in the inventory';\n const result = validateString(shape, value);\n return 'reason' in result ? result.reason : null;\n}\n\nexport type TranslateWords = {\n bar: string; hint: string; edits(count: number): string; exportPack: string; copied: string; exit: string; reload: string;\n key: string; original: string; parameters: string; plural: string; save: string; cancel: string; remove: string; notTranslatable: string; choose: string;\n};\n\n/** English defaults (the app passes its own words). */\nexport const TRANSLATE_WORDS: TranslateWords = {\n bar: 'Translate mode', hint: 'Click a word to change it.', edits: count => `${count} ${count === 1 ? 'edit' : 'edits'}`,\n exportPack: 'Copy pack file', copied: 'Pack file copied', exit: 'Leave', reload: 'Reload to see it',\n key: 'Key', original: 'Now', parameters: 'Parameters', plural: 'plural', save: 'Save', cancel: 'Cancel', remove: 'Remove edit',\n notTranslatable: 'This string cannot be changed by a pack yet.', choose: 'Which one?',\n};\n\nexport type TranslateUiOptions = {\n inventory: PageInventory;\n marker: Marker;\n site: string;\n catalog: string;\n /** The bar's and the editor's words; a function is asked again each time they are drawn (the app's language may change). */\n words?: Partial<TranslateWords> | (() => Partial<TranslateWords>);\n /** Leaves translate mode (the app drops the flag and reloads). */\n exit(): void;\n};\n\nconst CSS = `\n:host { all: initial; }\n.bar { position: fixed; left: 50%; bottom: 16px; transform: translateX(-50%); z-index: 2147483646; display: flex; gap: 10px; align-items: center;\n padding: 8px 12px; border-radius: 12px; background: #111827; color: #f9fafb; font: 13px/1.3 system-ui, sans-serif; box-shadow: 0 8px 24px rgba(0,0,0,.35); }\n.bar b { font-weight: 600; } .bar span { color: #cbd5e1; }\nbutton { font: inherit; border: 0; border-radius: 8px; padding: 6px 10px; cursor: pointer; background: #334155; color: #f9fafb; }\nbutton.primary { background: #2563eb; }\n.pop { position: fixed; z-index: 2147483647; width: 360px; max-width: calc(100vw - 24px); padding: 12px; border-radius: 12px; background: #fff; color: #111827;\n font: 13px/1.4 system-ui, sans-serif; box-shadow: 0 12px 32px rgba(0,0,0,.3); display: grid; gap: 8px; }\n.pop small { color: #475569; } .pop code { font-size: 12px; color: #334155; }\n.pop textarea { width: 100%; box-sizing: border-box; min-height: 64px; font: inherit; padding: 6px; border: 1px solid #cbd5e1; border-radius: 8px; }\n.pop .row { display: flex; gap: 8px; justify-content: flex-end; } .pop .err { color: #b91c1c; }\n.pop .pick { display: grid; gap: 4px; } .pop .pick button { text-align: left; background: #e2e8f0; color: #111827; }\n`;\n\n/**\n * The page part of translate mode: a bar (edits, copy the pack file, leave) and an editor for the\n * string under a click. Clicks on marked text are the editor's while the mode is on.\n */\nexport function installTranslateUi(win: Window, options: TranslateUiOptions): { dispose(): void } {\n const doc = win.document;\n const currentWords = (): TranslateWords => ({ ...TRANSLATE_WORDS, ...(typeof options.words === 'function' ? options.words() : options.words) });\n const lookup = inventoryLookup(options.inventory);\n const storage = win.sessionStorage;\n const draft = (): TranslateDraft => readDraft(storage) ?? { language: '', name: '', strings: {} };\n const save = (next: TranslateDraft) => { try { storage.setItem(DRAFT_KEY, JSON.stringify(next)); } catch { /* storage full or blocked */ } };\n\n const host = doc.createElement('wb-translate');\n const root = host.attachShadow({ mode: 'open' });\n const style = doc.createElement('style');\n style.textContent = CSS;\n root.append(style);\n const bar = doc.createElement('div');\n bar.className = 'bar';\n root.append(bar);\n let pop: HTMLElement | null = null;\n let changed = false;\n\n const button = (label: string, onClick: () => void, primary = false) => {\n const el = doc.createElement('button');\n el.textContent = label;\n if (primary) el.className = 'primary';\n el.addEventListener('click', event => { event.preventDefault(); event.stopPropagation(); onClick(); });\n return el;\n };\n const renderBar = () => {\n const words = currentWords();\n bar.replaceChildren();\n const title = doc.createElement('b');\n title.textContent = words.bar;\n const hint = doc.createElement('span');\n hint.textContent = `${words.hint} · ${words.edits(Object.keys(draft().strings).length)}`;\n bar.append(title, hint);\n if (changed) bar.append(button(words.reload, () => win.location.reload(), true));\n bar.append(button(words.exportPack, () => {\n const text = JSON.stringify(draftPack(draft(), options.site, options.catalog), null, 2);\n void win.navigator.clipboard?.writeText(text).then(() => { hint.textContent = words.copied; }).catch(() => {});\n }));\n bar.append(button(words.exit, options.exit));\n };\n const closePop = () => { pop?.remove(); pop = null; };\n\n const edit = (id: string, x: number, y: number, now: string) => {\n const words = currentWords();\n closePop();\n pop = doc.createElement('div');\n pop.className = 'pop';\n pop.style.left = `${Math.max(12, Math.min(x, win.innerWidth - 372))}px`;\n pop.style.top = `${Math.max(12, Math.min(y + 12, win.innerHeight - 260))}px`;\n const shape = lookup(id);\n const head = doc.createElement('small');\n head.textContent = `${words.key}: `;\n const code = doc.createElement('code');\n code.textContent = id;\n head.append(code);\n const current = doc.createElement('div');\n current.textContent = `${words.original}: ${now}`;\n pop.append(head, current);\n if (!shape || (shape.kind !== 'text' && shape.kind !== 'message')) {\n const note = doc.createElement('div');\n note.textContent = words.notTranslatable;\n pop.append(note, button(words.cancel, closePop));\n root.append(pop);\n return;\n }\n if (shape.params?.length) {\n const params = doc.createElement('small');\n params.textContent = `${words.parameters}: ${shape.params.map(name => `{${name}}${shape.plural?.includes(name) ? ` (${words.plural})` : ''}`).join(', ')}`;\n pop.append(params);\n }\n const input = doc.createElement('textarea');\n input.value = draft().strings[id] ?? now;\n const error = doc.createElement('div');\n error.className = 'err';\n const row = doc.createElement('div');\n row.className = 'row';\n if (draft().strings[id] !== undefined) {\n row.append(button(words.remove, () => { const next = draft(); delete next.strings[id]; save(next); changed = true; closePop(); renderBar(); }));\n }\n row.append(button(words.cancel, closePop), button(words.save, () => {\n const value = input.value.trim();\n const problem = checkEdit(lookup, id, value);\n if (problem) { error.textContent = problem; return; }\n const next = draft();\n next.strings[id] = value;\n save(next);\n changed = true;\n closePop();\n renderBar();\n }, true));\n pop.append(input, error, row);\n root.append(pop);\n input.focus();\n };\n\n /** The marked keys at a click: the element's own text and labels, then up to three parents. */\n const keysAt = (target: Element | null) => {\n for (let el = target, depth = 0; el && depth < 4; el = el.parentElement, depth += 1) {\n const texts = [el.textContent ?? '', el.getAttribute('aria-label') ?? '', el.getAttribute('placeholder') ?? '', el.getAttribute('title') ?? ''];\n const found = texts.flatMap(text => options.marker.ids(text).map(id => ({ id, text: options.marker.strip(text) })));\n if (found.length) return found.filter((item, i) => found.findIndex(other => other.id === item.id) === i).slice(0, 8);\n }\n return [];\n };\n const onClick = (event: MouseEvent) => {\n const words = currentWords();\n if (event.composedPath().includes(host)) return;\n const found = keysAt(event.target as Element | null);\n if (!found.length) return;\n event.preventDefault();\n event.stopPropagation();\n if (found.length === 1) { edit(found[0]!.id, event.clientX, event.clientY, found[0]!.text); return; }\n closePop();\n pop = doc.createElement('div');\n pop.className = 'pop';\n pop.style.left = `${Math.max(12, Math.min(event.clientX, win.innerWidth - 372))}px`;\n pop.style.top = `${Math.max(12, Math.min(event.clientY + 12, win.innerHeight - 260))}px`;\n const pick = doc.createElement('div');\n pick.className = 'pick';\n const label = doc.createElement('small');\n label.textContent = words.choose;\n pick.append(label, ...found.map(item => button(`${item.text.slice(0, 60)} · ${item.id}`, () => edit(item.id, event.clientX, event.clientY, item.text))));\n pop.append(pick, button(words.cancel, closePop));\n root.append(pop);\n };\n\n const mount = () => { (doc.body ?? doc.documentElement).append(host); renderBar(); };\n if (doc.body) mount(); else doc.addEventListener('DOMContentLoaded', mount, { once: true });\n win.addEventListener('click', onClick, true);\n return { dispose() { win.removeEventListener('click', onClick, true); host.remove(); } };\n}\n\n/** The draft as the last pack of a delivery (it applies over the others), when it has any string. */\nexport function withDraft(packs: readonly unknown[], storage: Pick<Storage, 'getItem'>, site: string, catalog: string, inventory: PageInventory): unknown[] {\n const draft = readDraft(storage);\n if (!draft || !Object.keys(draft.strings).length) return [...packs];\n const pack = draftPack(draft, site, catalog);\n try { compilePack(pack, inventory); } catch { return [...packs]; }\n return [...packs, pack];\n}\n"]}
|
|
@@ -0,0 +1,248 @@
|
|
|
1
|
+
import { parseMessage } from './i18n.ts';
|
|
2
|
+
type Parts = ReturnType<typeof parseMessage>;
|
|
3
|
+
/**
|
|
4
|
+
* What the site's value for a key is:
|
|
5
|
+
* - `text`: a plain string;
|
|
6
|
+
* - `message`: a function of a parameter object that returns a string;
|
|
7
|
+
* - `rich`: text with element slots (a link or a button inside a sentence). It can be replaced when
|
|
8
|
+
* the inventory knows its slot count (`slots`): the pack value then places the site's own
|
|
9
|
+
* elements with `{e0}`, `{e1}`, …, each exactly once (the last may be left out); the value itself is still plain text;
|
|
10
|
+
* - `format`: a compiled number/date/currency formatter (not text).
|
|
11
|
+
* Only `text`, `message` and `rich` with known `slots` can be replaced by a pack.
|
|
12
|
+
*/
|
|
13
|
+
export type StringKind = 'text' | 'message' | 'rich' | 'format';
|
|
14
|
+
export type InventoryEntry = {
|
|
15
|
+
kind: StringKind;
|
|
16
|
+
/** Parameter names the site's value takes (`message`). */
|
|
17
|
+
params?: string[];
|
|
18
|
+
/** Parameters the site's value pluralizes: known to be numbers, so a pack may pluralize them. */
|
|
19
|
+
plural?: string[];
|
|
20
|
+
/** Parameters the site's value selects on. */
|
|
21
|
+
select?: string[];
|
|
22
|
+
/** 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. */
|
|
23
|
+
slots?: number;
|
|
24
|
+
/** Tag slot names, for catalogs whose values carry `<tag>…</tag>` slots. */
|
|
25
|
+
tags?: string[];
|
|
26
|
+
/** Hash of the base-language value (`hashText`): drift detection; never the text itself. */
|
|
27
|
+
hash: string;
|
|
28
|
+
/** Part of the catalog the key arrives with (default `main`), e.g. a lazily loaded `emoji` group. */
|
|
29
|
+
group?: string;
|
|
30
|
+
};
|
|
31
|
+
/** The known keys of one catalog of one site. It carries ids and shapes, never the site's text. */
|
|
32
|
+
export type StringInventory = {
|
|
33
|
+
format: 1;
|
|
34
|
+
site: string;
|
|
35
|
+
catalog: string;
|
|
36
|
+
/** Language the hashes were taken from. */
|
|
37
|
+
base: string;
|
|
38
|
+
/** The site build the inventory was read from. */
|
|
39
|
+
build?: string;
|
|
40
|
+
entries: Record<string, InventoryEntry>;
|
|
41
|
+
};
|
|
42
|
+
/**
|
|
43
|
+
* When a pack applies. Without a condition it always does. `languages`: only while the site shows
|
|
44
|
+
* one of these languages (a tag matches itself and its regional forms: `en` matches `en-GB`), for
|
|
45
|
+
* example a rewording of English that must not touch a Turkish page.
|
|
46
|
+
*/
|
|
47
|
+
export type PackCondition = {
|
|
48
|
+
languages?: string[];
|
|
49
|
+
};
|
|
50
|
+
/**
|
|
51
|
+
* A pack's rewording rule: whole words replaced inside the site's own text, wherever it appears
|
|
52
|
+
* (`{ "Post": "Tweet", "posts": "tweets" }`). It carries none of the site's sentences, so it keeps
|
|
53
|
+
* working when the site words a string differently, and it applies to a value of the site (or of an
|
|
54
|
+
* earlier pack) that no later pack replaced. Words are matched exactly (case as written), never
|
|
55
|
+
* inside a longer word, and never in a parameter's value (a user named "Post" stays "Post").
|
|
56
|
+
*/
|
|
57
|
+
export type PackRewrite = {
|
|
58
|
+
words: Record<string, string>;
|
|
59
|
+
};
|
|
60
|
+
/** A string pack document: metadata and `key id -> text`. */
|
|
61
|
+
export type StringPack = {
|
|
62
|
+
format: 1;
|
|
63
|
+
site: string;
|
|
64
|
+
catalog: string;
|
|
65
|
+
/** BCP 47 tag of the pack's language (private-use tags are fine: `en-x-pirate`). */
|
|
66
|
+
language: string;
|
|
67
|
+
name: string;
|
|
68
|
+
authors: string[];
|
|
69
|
+
/** A language whose plural rules the pack follows when the runtime does not know `language`. */
|
|
70
|
+
base?: string;
|
|
71
|
+
/** The pack applies only when this holds (default: always). */
|
|
72
|
+
when?: PackCondition;
|
|
73
|
+
/** Rewords the site's text instead of (or besides) replacing keys. */
|
|
74
|
+
rewrite?: PackRewrite;
|
|
75
|
+
version?: string;
|
|
76
|
+
description?: string;
|
|
77
|
+
strings: Record<string, string>;
|
|
78
|
+
};
|
|
79
|
+
export declare const STRING_PACK_LIMITS: Readonly<{
|
|
80
|
+
strings: 40000;
|
|
81
|
+
value: 2000;
|
|
82
|
+
name: 80;
|
|
83
|
+
authors: 16;
|
|
84
|
+
}>;
|
|
85
|
+
export declare const MAIN_GROUP = "main";
|
|
86
|
+
/** Whether a pack can replace a value of this kind (a `rich` one only with known `slots`: pass the shape). */
|
|
87
|
+
export declare function translatable(kind: StringKind | Pick<EntryShape, 'kind' | 'slots'>): boolean;
|
|
88
|
+
/** Whether `language` (the site's) satisfies a pack's `when`. */
|
|
89
|
+
export declare function conditionHolds(when: PackCondition | undefined, language: string | undefined): boolean;
|
|
90
|
+
/** 53-bit hash of a text as 11 base-36 characters. Same result in every runtime. */
|
|
91
|
+
export declare function hashText(text: string): string;
|
|
92
|
+
/** The facts the validator and the engine need about one key. */
|
|
93
|
+
export type EntryShape = Pick<InventoryEntry, 'kind' | 'params' | 'plural' | 'select' | 'tags' | 'slots'>;
|
|
94
|
+
export type InventoryLookup = (id: string) => EntryShape | undefined;
|
|
95
|
+
/**
|
|
96
|
+
* The inventory as it ships inside a page runtime: ids and shapes only, no hashes, a fraction of
|
|
97
|
+
* the size. `text` and `closed` are space-separated ids; a message is `name name*` (`*` = plural,
|
|
98
|
+
* `?` = select).
|
|
99
|
+
*/
|
|
100
|
+
export type PageInventory = {
|
|
101
|
+
site: string;
|
|
102
|
+
catalog: string;
|
|
103
|
+
text: string;
|
|
104
|
+
message: Record<string, string>;
|
|
105
|
+
closed: string;
|
|
106
|
+
/** Rich entries a pack can replace: id -> slot count. */
|
|
107
|
+
rich?: Record<string, number>;
|
|
108
|
+
/** A slice: only the keys some pack names. A key missing from a slice is not a new key of the site. */
|
|
109
|
+
partial?: boolean;
|
|
110
|
+
};
|
|
111
|
+
export declare function packInventory(inventory: StringInventory): PageInventory;
|
|
112
|
+
/**
|
|
113
|
+
* The part of an inventory that the given keys need: what travels to a page together with the
|
|
114
|
+
* packs it should apply (a page never needs the rest). Keys the inventory does not have are left
|
|
115
|
+
* out, so they stay unknown there too.
|
|
116
|
+
*/
|
|
117
|
+
export declare function sliceInventory(inventory: StringInventory | PageInventory, ids: Iterable<string>): PageInventory;
|
|
118
|
+
/** Whether untrusted data has the shape of a page inventory (ids and parameter names only). */
|
|
119
|
+
export declare function isPageInventory(input: unknown): input is PageInventory;
|
|
120
|
+
/** A lookup over either form. The page form is decoded on first use. */
|
|
121
|
+
export declare function inventoryLookup(inventory: StringInventory | PageInventory): InventoryLookup;
|
|
122
|
+
export type PackIssue = {
|
|
123
|
+
level: 'error' | 'warning';
|
|
124
|
+
key?: string;
|
|
125
|
+
message: string;
|
|
126
|
+
};
|
|
127
|
+
/** Checks the document envelope. Errors mean the pack is not applied at all. */
|
|
128
|
+
export declare function checkPackShape(input: unknown): PackIssue[];
|
|
129
|
+
/**
|
|
130
|
+
* Validates one pack value against the key's inventory entry. Returns the parsed message, or the
|
|
131
|
+
* reason it is refused (the original then stays).
|
|
132
|
+
*/
|
|
133
|
+
export declare function validateString(shape: EntryShape, value: unknown): {
|
|
134
|
+
parts: Parts;
|
|
135
|
+
} | {
|
|
136
|
+
reason: string;
|
|
137
|
+
};
|
|
138
|
+
/**
|
|
139
|
+
* A replaced `rich` value in the shape X's own renderer reads: piece `n` is shown, then the site's
|
|
140
|
+
* element `order[n]` (the last piece has no element after it).
|
|
141
|
+
*/
|
|
142
|
+
export type RichTemplate = {
|
|
143
|
+
readonly pieces: readonly string[];
|
|
144
|
+
readonly order: readonly number[];
|
|
145
|
+
};
|
|
146
|
+
export type CompiledValue = {
|
|
147
|
+
text: string;
|
|
148
|
+
} | {
|
|
149
|
+
parts: Parts;
|
|
150
|
+
} | {
|
|
151
|
+
rich: RichTemplate;
|
|
152
|
+
};
|
|
153
|
+
export type PackReport = {
|
|
154
|
+
/** Entries in the pack. */
|
|
155
|
+
total: number;
|
|
156
|
+
/** Entries that are valid for an inventory key. */
|
|
157
|
+
valid: number;
|
|
158
|
+
/** Ids the inventory does not have: never applied. */
|
|
159
|
+
unknown: string[];
|
|
160
|
+
/** Values that failed validation: not applied, the original stays. */
|
|
161
|
+
rejected: {
|
|
162
|
+
id: string;
|
|
163
|
+
reason: string;
|
|
164
|
+
}[];
|
|
165
|
+
};
|
|
166
|
+
export type CompiledPack = {
|
|
167
|
+
name: string;
|
|
168
|
+
language: string;
|
|
169
|
+
base?: string;
|
|
170
|
+
when?: PackCondition;
|
|
171
|
+
/** The pack's word rewriting, ready to apply to a text. */
|
|
172
|
+
rewrite?: (text: string) => string;
|
|
173
|
+
site: string;
|
|
174
|
+
catalog: string;
|
|
175
|
+
values: ReadonlyMap<string, CompiledValue>;
|
|
176
|
+
report: PackReport;
|
|
177
|
+
};
|
|
178
|
+
/**
|
|
179
|
+
* Validates a pack against an inventory. Throws on a malformed envelope or a pack for another
|
|
180
|
+
* site/catalog; every other problem is per key and lands in `report`.
|
|
181
|
+
*/
|
|
182
|
+
export declare function compilePack(input: unknown, inventory: StringInventory | PageInventory): CompiledPack;
|
|
183
|
+
/**
|
|
184
|
+
* Renders a validated message. A parameter is inserted the way string concatenation would
|
|
185
|
+
* (`String(value)`, nothing for a missing one); `#` is the plural's own value.
|
|
186
|
+
*/
|
|
187
|
+
export declare function renderMessage(parts: Parts, params: Readonly<Record<string, unknown>>, languages: readonly (string | undefined)[], pound?: unknown): string;
|
|
188
|
+
export type EngineStats = {
|
|
189
|
+
/** Keys the site registered. */
|
|
190
|
+
seen: number;
|
|
191
|
+
/** Keys a pack value was used for. */
|
|
192
|
+
applied: number;
|
|
193
|
+
/** Keys the site registered that the inventory does not have (new keys: drift). */
|
|
194
|
+
unlisted: string[];
|
|
195
|
+
/** Keys whose live value does not have the inventory's kind: left untouched. */
|
|
196
|
+
mismatched: string[];
|
|
197
|
+
};
|
|
198
|
+
export type StringEngine = {
|
|
199
|
+
/**
|
|
200
|
+
* The value to use for `id`, given the site's own value: a pack's, or exactly `original`.
|
|
201
|
+
* Feeding a value this engine produced back in returns the same value (idempotent).
|
|
202
|
+
*/
|
|
203
|
+
resolve(id: string, original: unknown): unknown;
|
|
204
|
+
/**
|
|
205
|
+
* The language the site shows (what packs with a `when.languages` condition are checked
|
|
206
|
+
* against). Set before the first `resolve`; until then conditional packs do not apply.
|
|
207
|
+
*/
|
|
208
|
+
setLanguage(language: string): void;
|
|
209
|
+
/** The site's own values of the keys a pack changed: what restoring needs. */
|
|
210
|
+
originals(): ReadonlyMap<string, unknown>;
|
|
211
|
+
stats(): EngineStats;
|
|
212
|
+
};
|
|
213
|
+
/** `packs` in application order: a later pack wins over an earlier one for the same key. */
|
|
214
|
+
export declare function createStringEngine(inventory: StringInventory | PageInventory | InventoryLookup, packs: readonly CompiledPack[]): StringEngine;
|
|
215
|
+
/**
|
|
216
|
+
* The whole catalog at once: a new object with the packs applied; `catalog` itself is not
|
|
217
|
+
* changed. `applyPacks(applyPacks(c, …), …)` with one engine equals `applyPacks(c, …)`.
|
|
218
|
+
*/
|
|
219
|
+
export declare function applyPacks(catalog: Readonly<Record<string, unknown>>, engine: StringEngine): Record<string, unknown>;
|
|
220
|
+
/** The inverse: every value a pack changed is the site's own again; `catalog` is not changed. */
|
|
221
|
+
export declare function restoreCatalog(catalog: Readonly<Record<string, unknown>>, engine: StringEngine): Record<string, unknown>;
|
|
222
|
+
export type Coverage = {
|
|
223
|
+
/** Keys a pack can replace (text and messages). */
|
|
224
|
+
translatable: number;
|
|
225
|
+
/** Of those, keys the pack has a valid value for. */
|
|
226
|
+
translated: number;
|
|
227
|
+
/** Keys that exist but cannot be replaced by data yet (rich text, formatters). */
|
|
228
|
+
closed: number;
|
|
229
|
+
};
|
|
230
|
+
/** Coverage of a compiled pack per group of the inventory, plus `all`. */
|
|
231
|
+
export declare function coverage(inventory: StringInventory, pack: Pick<CompiledPack, 'values'>): Record<string, Coverage>;
|
|
232
|
+
export type DriftReport = {
|
|
233
|
+
/** Keys the site has that the inventory lacks. */
|
|
234
|
+
added: string[];
|
|
235
|
+
/** Keys whose base-language value changed (same shape). */
|
|
236
|
+
reworded: string[];
|
|
237
|
+
/** Keys whose kind or parameters changed: pack values for them have to be checked again. */
|
|
238
|
+
reshaped: string[];
|
|
239
|
+
/** Inventory keys the site no longer has. Only for groups whose base catalog was loaded. */
|
|
240
|
+
vanished: string[];
|
|
241
|
+
};
|
|
242
|
+
/**
|
|
243
|
+
* Compares an inventory with what was observed now. `loaded` names the groups whose base catalog
|
|
244
|
+
* was actually read: a key can only be called vanished when its group was (a lazily loaded group
|
|
245
|
+
* that never arrived says nothing about its keys).
|
|
246
|
+
*/
|
|
247
|
+
export declare function driftReport(inventory: StringInventory, observed: Readonly<Record<string, InventoryEntry>>, loaded: readonly string[]): DriftReport;
|
|
248
|
+
export {};
|