waybetter 0.1.1 → 0.6.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.
Files changed (515) hide show
  1. package/README.md +140 -6
  2. package/bin/waybetter.mjs +46 -0
  3. package/build/runtime.mjs +105 -0
  4. package/cli/buildenv.mjs +130 -0
  5. package/cli/dev.mjs +97 -0
  6. package/cli/i18n.mjs +382 -0
  7. package/cli/manifests.mjs +383 -0
  8. package/cli/privacy.mjs +768 -0
  9. package/cli/release.mjs +444 -0
  10. package/cli/remote.mjs +260 -0
  11. package/cli/store.mjs +326 -0
  12. package/cli/strings.mjs +121 -0
  13. package/dist/runtime/column.d.ts +93 -0
  14. package/dist/runtime/column.js +451 -0
  15. package/dist/runtime/column.js.map +1 -0
  16. package/dist/runtime/commandReport.d.ts +19 -0
  17. package/dist/runtime/commandReport.js +47 -0
  18. package/dist/runtime/commandReport.js.map +1 -0
  19. package/dist/runtime/commands.d.ts +72 -0
  20. package/dist/runtime/commands.js +214 -0
  21. package/dist/runtime/commands.js.map +1 -0
  22. package/dist/runtime/devErrors.d.ts +16 -0
  23. package/dist/runtime/devErrors.js +30 -0
  24. package/dist/runtime/devErrors.js.map +1 -0
  25. package/dist/runtime/domHub.d.ts +21 -0
  26. package/dist/runtime/domHub.js +139 -4
  27. package/dist/runtime/domHub.js.map +1 -1
  28. package/dist/runtime/featureModules.d.ts +157 -0
  29. package/dist/runtime/featureModules.js +484 -0
  30. package/dist/runtime/featureModules.js.map +1 -0
  31. package/dist/runtime/featureTable.d.ts +144 -0
  32. package/dist/runtime/featureTable.js +223 -0
  33. package/dist/runtime/featureTable.js.map +1 -0
  34. package/dist/runtime/fonts.d.ts +22 -0
  35. package/dist/runtime/fonts.js +72 -0
  36. package/dist/runtime/fonts.js.map +1 -0
  37. package/dist/runtime/i18n.d.ts +138 -0
  38. package/dist/runtime/i18n.js +614 -0
  39. package/dist/runtime/i18n.js.map +1 -0
  40. package/dist/runtime/i18nCheck.d.ts +30 -0
  41. package/dist/runtime/i18nCheck.js +224 -0
  42. package/dist/runtime/i18nCheck.js.map +1 -0
  43. package/dist/runtime/pageLang.d.ts +8 -0
  44. package/dist/runtime/pageLang.js +64 -0
  45. package/dist/runtime/pageLang.js.map +1 -0
  46. package/dist/runtime/pageStrings.d.ts +35 -0
  47. package/dist/runtime/pageStrings.js +76 -0
  48. package/dist/runtime/pageStrings.js.map +1 -0
  49. package/dist/runtime/panelButton.d.ts +33 -0
  50. package/dist/runtime/panelButton.js +83 -0
  51. package/dist/runtime/panelButton.js.map +1 -0
  52. package/dist/runtime/permissions.d.ts +47 -0
  53. package/dist/runtime/permissions.js +141 -0
  54. package/dist/runtime/permissions.js.map +1 -0
  55. package/dist/runtime/pluginApi.d.ts +51 -2
  56. package/dist/runtime/pluginApi.js +137 -22
  57. package/dist/runtime/pluginApi.js.map +1 -1
  58. package/dist/runtime/pluginI18n.d.ts +29 -0
  59. package/dist/runtime/pluginI18n.js +119 -0
  60. package/dist/runtime/pluginI18n.js.map +1 -0
  61. package/dist/runtime/settingsForm.d.ts +66 -0
  62. package/dist/runtime/settingsForm.js +114 -0
  63. package/dist/runtime/settingsForm.js.map +1 -0
  64. package/dist/runtime/site.d.ts +5 -0
  65. package/dist/runtime/site.js +1 -1
  66. package/dist/runtime/site.js.map +1 -1
  67. package/dist/runtime/siteRuntime.d.ts +144 -0
  68. package/dist/runtime/siteRuntime.js +175 -0
  69. package/dist/runtime/siteRuntime.js.map +1 -0
  70. package/dist/runtime/stringPackHook.d.ts +84 -0
  71. package/dist/runtime/stringPackHook.js +220 -0
  72. package/dist/runtime/stringPackHook.js.map +1 -0
  73. package/dist/runtime/stringPackTranslate.d.ts +59 -0
  74. package/dist/runtime/stringPackTranslate.js +264 -0
  75. package/dist/runtime/stringPackTranslate.js.map +1 -0
  76. package/dist/runtime/stringPacks.d.ts +200 -0
  77. package/dist/runtime/stringPacks.js +474 -0
  78. package/dist/runtime/stringPacks.js.map +1 -0
  79. package/dist/runtime/styles.d.ts +15 -0
  80. package/dist/runtime/styles.js +81 -0
  81. package/dist/runtime/styles.js.map +1 -0
  82. package/dist/runtime/textNet.d.ts +15 -0
  83. package/dist/runtime/textNet.js +131 -0
  84. package/dist/runtime/textNet.js.map +1 -0
  85. package/dist/runtime/themeApi.d.ts +121 -0
  86. package/dist/runtime/themeApi.js +220 -0
  87. package/dist/runtime/themeApi.js.map +1 -0
  88. package/dist/runtime/themeChoice.d.ts +52 -0
  89. package/dist/runtime/themeChoice.js +69 -0
  90. package/dist/runtime/themeChoice.js.map +1 -0
  91. package/dist/runtime/themeComponents.d.ts +435 -0
  92. package/dist/runtime/themeComponents.js +463 -0
  93. package/dist/runtime/themeComponents.js.map +1 -0
  94. package/dist/runtime/themeDecor.d.ts +73 -0
  95. package/dist/runtime/themeDecor.js +131 -0
  96. package/dist/runtime/themeDecor.js.map +1 -0
  97. package/dist/runtime/themeDoctor.d.ts +11 -0
  98. package/dist/runtime/themeDoctor.js +51 -0
  99. package/dist/runtime/themeDoctor.js.map +1 -0
  100. package/dist/runtime/themeIcons.d.ts +130 -0
  101. package/dist/runtime/themeIcons.js +263 -0
  102. package/dist/runtime/themeIcons.js.map +1 -0
  103. package/dist/runtime/themeRuntime.d.ts +100 -0
  104. package/dist/runtime/themeRuntime.js +497 -0
  105. package/dist/runtime/themeRuntime.js.map +1 -0
  106. package/dist/runtime/themeSchema.d.ts +10 -0
  107. package/dist/runtime/themeSchema.js +150 -0
  108. package/dist/runtime/themeSchema.js.map +1 -0
  109. package/dist/runtime/themeSpec.d.ts +259 -0
  110. package/dist/runtime/themeSpec.js +439 -0
  111. package/dist/runtime/themeSpec.js.map +1 -0
  112. package/dist/runtime/themeTokens.d.ts +12 -0
  113. package/dist/runtime/themeTokens.js +14 -6
  114. package/dist/runtime/themeTokens.js.map +1 -1
  115. package/dist/runtime/themeVariants.d.ts +30 -0
  116. package/dist/runtime/themeVariants.js +53 -0
  117. package/dist/runtime/themeVariants.js.map +1 -0
  118. package/dist/runtime/ui.d.ts +192 -0
  119. package/dist/runtime/ui.js +926 -0
  120. package/dist/runtime/ui.js.map +1 -0
  121. package/dist/shell/InstallDialog.d.ts +40 -0
  122. package/dist/shell/InstallDialog.js +170 -0
  123. package/dist/shell/InstallDialog.js.map +1 -0
  124. package/dist/shell/StoreView.d.ts +66 -0
  125. package/dist/shell/StoreView.js +103 -0
  126. package/dist/shell/StoreView.js.map +1 -0
  127. package/dist/shell/addressModel.js.map +1 -1
  128. package/dist/shell/chrome.js.map +1 -1
  129. package/dist/shell/deckModel.d.ts +117 -0
  130. package/dist/shell/deckModel.js +267 -0
  131. package/dist/shell/deckModel.js.map +1 -0
  132. package/dist/shell/frame/AccountSwitcher.d.ts +42 -0
  133. package/dist/shell/frame/AccountSwitcher.js +243 -0
  134. package/dist/shell/frame/AccountSwitcher.js.map +1 -0
  135. package/dist/shell/frame/AddColumnDialog.d.ts +8 -0
  136. package/dist/shell/frame/AddColumnDialog.js +81 -0
  137. package/dist/shell/frame/AddColumnDialog.js.map +1 -0
  138. package/dist/shell/frame/AppMenu.d.ts +21 -0
  139. package/dist/shell/frame/AppMenu.js +642 -0
  140. package/dist/shell/frame/AppMenu.js.map +1 -0
  141. package/dist/shell/frame/CommandPalette.d.ts +7 -0
  142. package/dist/shell/frame/CommandPalette.js +118 -0
  143. package/dist/shell/frame/CommandPalette.js.map +1 -0
  144. package/dist/shell/frame/DeckView.d.ts +13 -0
  145. package/dist/shell/frame/DeckView.js +287 -0
  146. package/dist/shell/frame/DeckView.js.map +1 -0
  147. package/dist/shell/frame/FindBar.d.ts +10 -0
  148. package/dist/shell/frame/FindBar.js +108 -0
  149. package/dist/shell/frame/FindBar.js.map +1 -0
  150. package/dist/shell/frame/MediaPanel.d.ts +8 -0
  151. package/dist/shell/frame/MediaPanel.js +76 -0
  152. package/dist/shell/frame/MediaPanel.js.map +1 -0
  153. package/dist/shell/frame/NewTabPage.d.ts +9 -0
  154. package/dist/shell/frame/NewTabPage.js +71 -0
  155. package/dist/shell/frame/NewTabPage.js.map +1 -0
  156. package/dist/shell/frame/PaneTheme.d.ts +16 -0
  157. package/dist/shell/frame/PaneTheme.js +67 -0
  158. package/dist/shell/frame/PaneTheme.js.map +1 -0
  159. package/dist/shell/frame/ReportDialog.d.ts +3 -0
  160. package/dist/shell/frame/ReportDialog.js +95 -0
  161. package/dist/shell/frame/ReportDialog.js.map +1 -0
  162. package/dist/shell/frame/Shell.d.ts +8 -0
  163. package/dist/shell/frame/Shell.js +1131 -0
  164. package/dist/shell/frame/Shell.js.map +1 -0
  165. package/dist/shell/frame/Titlebar.d.ts +16 -0
  166. package/dist/shell/frame/Titlebar.js +77 -0
  167. package/dist/shell/frame/Titlebar.js.map +1 -0
  168. package/dist/shell/frame/TitlebarExtras.d.ts +4 -0
  169. package/dist/shell/frame/TitlebarExtras.js +202 -0
  170. package/dist/shell/frame/TitlebarExtras.js.map +1 -0
  171. package/dist/shell/frame/WebPanel.d.ts +4 -0
  172. package/dist/shell/frame/WebPanel.js +182 -0
  173. package/dist/shell/frame/WebPanel.js.map +1 -0
  174. package/dist/shell/frame/accountModel.d.ts +49 -0
  175. package/dist/shell/frame/accountModel.js +67 -0
  176. package/dist/shell/frame/accountModel.js.map +1 -0
  177. package/dist/shell/frame/accountSwitcher.css +91 -0
  178. package/dist/shell/frame/appI18n.d.ts +44 -0
  179. package/dist/shell/frame/appI18n.js +64 -0
  180. package/dist/shell/frame/appI18n.js.map +1 -0
  181. package/dist/shell/frame/appMenu.css +121 -0
  182. package/dist/shell/frame/backupModel.d.ts +38 -0
  183. package/dist/shell/frame/backupModel.js +192 -0
  184. package/dist/shell/frame/backupModel.js.map +1 -0
  185. package/dist/shell/frame/boot.d.ts +8 -0
  186. package/dist/shell/frame/boot.js +35 -0
  187. package/dist/shell/frame/boot.js.map +1 -0
  188. package/dist/shell/frame/brand.d.ts +1 -0
  189. package/dist/shell/frame/brand.js +4 -0
  190. package/dist/shell/frame/brand.js.map +1 -0
  191. package/dist/shell/frame/bridge.d.ts +35 -0
  192. package/dist/shell/frame/bridge.js +70 -0
  193. package/dist/shell/frame/bridge.js.map +1 -0
  194. package/dist/shell/frame/chromeTheme.d.ts +29 -0
  195. package/dist/shell/frame/chromeTheme.js +81 -0
  196. package/dist/shell/frame/chromeTheme.js.map +1 -0
  197. package/dist/shell/frame/deck.css +209 -0
  198. package/dist/shell/frame/deckStore.d.ts +89 -0
  199. package/dist/shell/frame/deckStore.js +239 -0
  200. package/dist/shell/frame/deckStore.js.map +1 -0
  201. package/dist/shell/frame/devHost.d.ts +35 -0
  202. package/dist/shell/frame/devHost.js +80 -0
  203. package/dist/shell/frame/devHost.js.map +1 -0
  204. package/dist/shell/frame/devModel.d.ts +7 -0
  205. package/dist/shell/frame/devModel.js +17 -0
  206. package/dist/shell/frame/devModel.js.map +1 -0
  207. package/dist/shell/frame/diag.d.ts +7 -0
  208. package/dist/shell/frame/diag.js +39 -0
  209. package/dist/shell/frame/diag.js.map +1 -0
  210. package/dist/shell/frame/findBar.css +14 -0
  211. package/dist/shell/frame/frameMessages.d.ts +248 -0
  212. package/dist/shell/frame/frameMessages.js +252 -0
  213. package/dist/shell/frame/frameMessages.js.map +1 -0
  214. package/dist/shell/frame/hooks.d.ts +39 -0
  215. package/dist/shell/frame/hooks.js +97 -0
  216. package/dist/shell/frame/hooks.js.map +1 -0
  217. package/dist/shell/frame/i18n.d.ts +27 -0
  218. package/dist/shell/frame/i18n.js +66 -0
  219. package/dist/shell/frame/i18n.js.map +1 -0
  220. package/dist/shell/frame/iconPack.d.ts +11 -0
  221. package/dist/shell/frame/iconPack.js +45 -0
  222. package/dist/shell/frame/iconPack.js.map +1 -0
  223. package/dist/shell/frame/icons.d.ts +71 -0
  224. package/dist/shell/frame/icons.js +75 -0
  225. package/dist/shell/frame/icons.js.map +1 -0
  226. package/dist/shell/frame/index.d.ts +34 -0
  227. package/dist/shell/frame/index.js +43 -0
  228. package/dist/shell/frame/index.js.map +1 -0
  229. package/dist/shell/frame/language.d.ts +58 -0
  230. package/dist/shell/frame/language.js +165 -0
  231. package/dist/shell/frame/language.js.map +1 -0
  232. package/dist/shell/frame/mediaModel.d.ts +34 -0
  233. package/dist/shell/frame/mediaModel.js +53 -0
  234. package/dist/shell/frame/mediaModel.js.map +1 -0
  235. package/dist/shell/frame/menuMessages.en.json +54 -0
  236. package/dist/shell/frame/menuModel.d.ts +277 -0
  237. package/dist/shell/frame/menuModel.js +293 -0
  238. package/dist/shell/frame/menuModel.js.map +1 -0
  239. package/dist/shell/frame/paletteModel.d.ts +139 -0
  240. package/dist/shell/frame/paletteModel.js +112 -0
  241. package/dist/shell/frame/paletteModel.js.map +1 -0
  242. package/dist/shell/frame/paneTheme.css +9 -0
  243. package/dist/shell/frame/pluginCommandStore.d.ts +23 -0
  244. package/dist/shell/frame/pluginCommandStore.js +70 -0
  245. package/dist/shell/frame/pluginCommandStore.js.map +1 -0
  246. package/dist/shell/frame/reportModel.d.ts +52 -0
  247. package/dist/shell/frame/reportModel.js +105 -0
  248. package/dist/shell/frame/reportModel.js.map +1 -0
  249. package/dist/shell/frame/safeStore.d.ts +7 -0
  250. package/dist/shell/frame/safeStore.js +40 -0
  251. package/dist/shell/frame/safeStore.js.map +1 -0
  252. package/dist/shell/frame/searchInput.d.ts +2 -0
  253. package/dist/shell/frame/searchInput.js +11 -0
  254. package/dist/shell/frame/searchInput.js.map +1 -0
  255. package/dist/shell/frame/shell.css +629 -0
  256. package/dist/shell/frame/site.d.ts +206 -0
  257. package/dist/shell/frame/site.js +22 -0
  258. package/dist/shell/frame/site.js.map +1 -0
  259. package/dist/shell/frame/state.d.ts +99 -0
  260. package/dist/shell/frame/state.js +284 -0
  261. package/dist/shell/frame/state.js.map +1 -0
  262. package/dist/shell/frame/syncGate.d.ts +10 -0
  263. package/dist/shell/frame/syncGate.js +36 -0
  264. package/dist/shell/frame/syncGate.js.map +1 -0
  265. package/dist/shell/frame/syncHost.d.ts +35 -0
  266. package/dist/shell/frame/syncHost.js +85 -0
  267. package/dist/shell/frame/syncHost.js.map +1 -0
  268. package/dist/shell/frame/tabStill.d.ts +2 -0
  269. package/dist/shell/frame/tabStill.js +62 -0
  270. package/dist/shell/frame/tabStill.js.map +1 -0
  271. package/dist/shell/frame/themeScopes.d.ts +29 -0
  272. package/dist/shell/frame/themeScopes.js +61 -0
  273. package/dist/shell/frame/themeScopes.js.map +1 -0
  274. package/dist/shell/frame/themeStore.d.ts +99 -0
  275. package/dist/shell/frame/themeStore.js +252 -0
  276. package/dist/shell/frame/themeStore.js.map +1 -0
  277. package/dist/shell/frame/windowBinding.d.ts +2 -0
  278. package/dist/shell/frame/windowBinding.js +7 -0
  279. package/dist/shell/frame/windowBinding.js.map +1 -0
  280. package/dist/shell/frame/workspaceModel.d.ts +82 -0
  281. package/dist/shell/frame/workspaceModel.js +250 -0
  282. package/dist/shell/frame/workspaceModel.js.map +1 -0
  283. package/dist/shell/frame/workspaces.css +84 -0
  284. package/dist/shell/frame/workspaces.d.ts +22 -0
  285. package/dist/shell/frame/workspaces.js +125 -0
  286. package/dist/shell/frame/workspaces.js.map +1 -0
  287. package/dist/shell/frame/zoomStore.d.ts +10 -0
  288. package/dist/shell/frame/zoomStore.js +65 -0
  289. package/dist/shell/frame/zoomStore.js.map +1 -0
  290. package/dist/shell/installController.d.ts +122 -0
  291. package/dist/shell/installController.js +146 -0
  292. package/dist/shell/installController.js.map +1 -0
  293. package/dist/shell/installerMessages.d.ts +30 -0
  294. package/dist/shell/installerMessages.js +36 -0
  295. package/dist/shell/installerMessages.js.map +1 -0
  296. package/dist/shell/linkDrop.js.map +1 -1
  297. package/dist/shell/messages.d.ts +16 -0
  298. package/dist/shell/messages.js +27 -0
  299. package/dist/shell/messages.js.map +1 -0
  300. package/dist/shell/palette.js.map +1 -1
  301. package/dist/shell/paneModel.d.ts +22 -0
  302. package/dist/shell/paneModel.js +24 -1
  303. package/dist/shell/paneModel.js.map +1 -1
  304. package/dist/shell/panel/Appearance.d.ts +8 -0
  305. package/dist/shell/panel/Appearance.js +256 -0
  306. package/dist/shell/panel/Appearance.js.map +1 -0
  307. package/dist/shell/panel/BackupPanel.d.ts +5 -0
  308. package/dist/shell/panel/BackupPanel.js +198 -0
  309. package/dist/shell/panel/BackupPanel.js.map +1 -0
  310. package/dist/shell/panel/DeveloperPanel.d.ts +4 -0
  311. package/dist/shell/panel/DeveloperPanel.js +51 -0
  312. package/dist/shell/panel/DeveloperPanel.js.map +1 -0
  313. package/dist/shell/panel/FeatureToggles.d.ts +13 -0
  314. package/dist/shell/panel/FeatureToggles.js +42 -0
  315. package/dist/shell/panel/FeatureToggles.js.map +1 -0
  316. package/dist/shell/panel/Home.d.ts +3 -0
  317. package/dist/shell/panel/Home.js +23 -0
  318. package/dist/shell/panel/Home.js.map +1 -0
  319. package/dist/shell/panel/IconPackInstall.d.ts +15 -0
  320. package/dist/shell/panel/IconPackInstall.js +41 -0
  321. package/dist/shell/panel/IconPackInstall.js.map +1 -0
  322. package/dist/shell/panel/LanguageSettings.d.ts +1 -0
  323. package/dist/shell/panel/LanguageSettings.js +54 -0
  324. package/dist/shell/panel/LanguageSettings.js.map +1 -0
  325. package/dist/shell/panel/MakePanel.d.ts +3 -0
  326. package/dist/shell/panel/MakePanel.js +237 -0
  327. package/dist/shell/panel/MakePanel.js.map +1 -0
  328. package/dist/shell/panel/MarkdownDoc.d.ts +6 -0
  329. package/dist/shell/panel/MarkdownDoc.js +35 -0
  330. package/dist/shell/panel/MarkdownDoc.js.map +1 -0
  331. package/dist/shell/panel/Modes.d.ts +40 -0
  332. package/dist/shell/panel/Modes.js +270 -0
  333. package/dist/shell/panel/Modes.js.map +1 -0
  334. package/dist/shell/panel/NavIcon.d.ts +4 -0
  335. package/dist/shell/panel/NavIcon.js +6 -0
  336. package/dist/shell/panel/NavIcon.js.map +1 -0
  337. package/dist/shell/panel/Panel.d.ts +7 -0
  338. package/dist/shell/panel/Panel.js +139 -0
  339. package/dist/shell/panel/Panel.js.map +1 -0
  340. package/dist/shell/panel/PluginFeatures.d.ts +24 -0
  341. package/dist/shell/panel/PluginFeatures.js +165 -0
  342. package/dist/shell/panel/PluginFeatures.js.map +1 -0
  343. package/dist/shell/panel/Plugins.d.ts +33 -0
  344. package/dist/shell/panel/Plugins.js +112 -0
  345. package/dist/shell/panel/Plugins.js.map +1 -0
  346. package/dist/shell/panel/PowerSettings.d.ts +4 -0
  347. package/dist/shell/panel/PowerSettings.js +52 -0
  348. package/dist/shell/panel/PowerSettings.js.map +1 -0
  349. package/dist/shell/panel/Settings.d.ts +23 -0
  350. package/dist/shell/panel/Settings.js +116 -0
  351. package/dist/shell/panel/Settings.js.map +1 -0
  352. package/dist/shell/panel/ShareSetup.d.ts +8 -0
  353. package/dist/shell/panel/ShareSetup.js +130 -0
  354. package/dist/shell/panel/ShareSetup.js.map +1 -0
  355. package/dist/shell/panel/StoreSection.d.ts +6 -0
  356. package/dist/shell/panel/StoreSection.js +48 -0
  357. package/dist/shell/panel/StoreSection.js.map +1 -0
  358. package/dist/shell/panel/StringPacks.d.ts +11 -0
  359. package/dist/shell/panel/StringPacks.js +106 -0
  360. package/dist/shell/panel/StringPacks.js.map +1 -0
  361. package/dist/shell/panel/ThemeBuilder.d.ts +5 -0
  362. package/dist/shell/panel/ThemeBuilder.js +205 -0
  363. package/dist/shell/panel/ThemeBuilder.js.map +1 -0
  364. package/dist/shell/panel/backup.css +34 -0
  365. package/dist/shell/panel/builder.css +232 -0
  366. package/dist/shell/panel/builderModel.d.ts +55 -0
  367. package/dist/shell/panel/builderModel.js +95 -0
  368. package/dist/shell/panel/builderModel.js.map +1 -0
  369. package/dist/shell/panel/compare.d.ts +10 -0
  370. package/dist/shell/panel/compare.js +51 -0
  371. package/dist/shell/panel/compare.js.map +1 -0
  372. package/dist/shell/panel/controls.d.ts +135 -0
  373. package/dist/shell/panel/controls.js +213 -0
  374. package/dist/shell/panel/controls.js.map +1 -0
  375. package/dist/shell/panel/featureModel.d.ts +69 -0
  376. package/dist/shell/panel/featureModel.js +79 -0
  377. package/dist/shell/panel/featureModel.js.map +1 -0
  378. package/dist/shell/panel/fonts/FontBrowser.d.ts +10 -0
  379. package/dist/shell/panel/fonts/FontBrowser.js +189 -0
  380. package/dist/shell/panel/fonts/FontBrowser.js.map +1 -0
  381. package/dist/shell/panel/fonts/FontRoles.d.ts +20 -0
  382. package/dist/shell/panel/fonts/FontRoles.js +77 -0
  383. package/dist/shell/panel/fonts/FontRoles.js.map +1 -0
  384. package/dist/shell/panel/fonts/catalog.d.ts +37 -0
  385. package/dist/shell/panel/fonts/catalog.js +68 -0
  386. package/dist/shell/panel/fonts/catalog.js.map +1 -0
  387. package/dist/shell/panel/fonts/googleFontsCatalog.json +1 -0
  388. package/dist/shell/panel/index.d.ts +20 -0
  389. package/dist/shell/panel/index.js +34 -0
  390. package/dist/shell/panel/index.js.map +1 -0
  391. package/dist/shell/panel/languageModel.d.ts +5 -0
  392. package/dist/shell/panel/languageModel.js +7 -0
  393. package/dist/shell/panel/languageModel.js.map +1 -0
  394. package/dist/shell/panel/make.css +72 -0
  395. package/dist/shell/panel/makeModel.d.ts +32 -0
  396. package/dist/shell/panel/makeModel.js +84 -0
  397. package/dist/shell/panel/makeModel.js.map +1 -0
  398. package/dist/shell/panel/markdown.d.ts +46 -0
  399. package/dist/shell/panel/markdown.js +100 -0
  400. package/dist/shell/panel/markdown.js.map +1 -0
  401. package/dist/shell/panel/nav.d.ts +12 -0
  402. package/dist/shell/panel/nav.js +50 -0
  403. package/dist/shell/panel/nav.js.map +1 -0
  404. package/dist/shell/panel/panel.css +401 -0
  405. package/dist/shell/panel/panelMessages.d.ts +763 -0
  406. package/dist/shell/panel/panelMessages.js +767 -0
  407. package/dist/shell/panel/panelMessages.js.map +1 -0
  408. package/dist/shell/panel/plugins.css +59 -0
  409. package/dist/shell/panel/setupModel.d.ts +87 -0
  410. package/dist/shell/panel/setupModel.js +152 -0
  411. package/dist/shell/panel/setupModel.js.map +1 -0
  412. package/dist/shell/panel/site.d.ts +259 -0
  413. package/dist/shell/panel/site.js +25 -0
  414. package/dist/shell/panel/site.js.map +1 -0
  415. package/dist/shell/panel/strings.css +7 -0
  416. package/dist/shell/panel/themes.d.ts +10 -0
  417. package/dist/shell/panel/themes.js +8 -0
  418. package/dist/shell/panel/themes.js.map +1 -0
  419. package/dist/shell/profileModel.d.ts +3 -2
  420. package/dist/shell/profileModel.js +7 -5
  421. package/dist/shell/profileModel.js.map +1 -1
  422. package/dist/shell/store.css +230 -0
  423. package/dist/shell/storeMessages.d.ts +169 -0
  424. package/dist/shell/storeMessages.js +172 -0
  425. package/dist/shell/storeMessages.js.map +1 -0
  426. package/dist/shell/storeModel.d.ts +181 -0
  427. package/dist/shell/storeModel.js +133 -0
  428. package/dist/shell/storeModel.js.map +1 -0
  429. package/dist/shell/stringPacksModel.d.ts +44 -0
  430. package/dist/shell/stringPacksModel.js +94 -0
  431. package/dist/shell/stringPacksModel.js.map +1 -0
  432. package/dist/shell/updateModel.d.ts +2 -1
  433. package/dist/shell/updateModel.js +5 -4
  434. package/dist/shell/updateModel.js.map +1 -1
  435. package/dist/shell/windowControls.d.ts +4 -0
  436. package/dist/shell/windowControls.js +5 -0
  437. package/dist/shell/windowControls.js.map +1 -1
  438. package/i18n-config.schema.json +29 -0
  439. package/i18n-meta.schema.json +26 -0
  440. package/i18n.schema.json +42 -0
  441. package/icons.schema.json +646 -0
  442. package/languages.schema.json +23 -0
  443. package/locales/ar-x-fm.json +11 -0
  444. package/locales/ar.json +1281 -0
  445. package/locales/bg.json +1280 -0
  446. package/locales/bn.json +1280 -0
  447. package/locales/ca.json +1280 -0
  448. package/locales/cs.json +1280 -0
  449. package/locales/da.json +1280 -0
  450. package/locales/de.json +1280 -0
  451. package/locales/el.json +1280 -0
  452. package/locales/en-GB.json +27 -0
  453. package/locales/en.json +1280 -0
  454. package/locales/en.meta.json +51 -0
  455. package/locales/es.json +1280 -0
  456. package/locales/eu.json +1280 -0
  457. package/locales/fa.json +1281 -0
  458. package/locales/fi.json +1280 -0
  459. package/locales/fil.json +1280 -0
  460. package/locales/fr.json +1280 -0
  461. package/locales/ga.json +1280 -0
  462. package/locales/gl.json +1280 -0
  463. package/locales/gu.json +1280 -0
  464. package/locales/ha.json +1280 -0
  465. package/locales/he.json +1281 -0
  466. package/locales/hi.json +1280 -0
  467. package/locales/hr.json +1280 -0
  468. package/locales/hu.json +1279 -0
  469. package/locales/id.json +1280 -0
  470. package/locales/ig.json +1280 -0
  471. package/locales/it.json +1280 -0
  472. package/locales/ja.json +1280 -0
  473. package/locales/kn.json +1280 -0
  474. package/locales/ko.json +1280 -0
  475. package/locales/mr.json +1280 -0
  476. package/locales/ms.json +1280 -0
  477. package/locales/nb.json +1280 -0
  478. package/locales/nl.json +1280 -0
  479. package/locales/pl.json +1280 -0
  480. package/locales/pt.json +1280 -0
  481. package/locales/ro.json +1280 -0
  482. package/locales/ru.json +1280 -0
  483. package/locales/sk.json +1280 -0
  484. package/locales/sr.json +1280 -0
  485. package/locales/sv.json +1280 -0
  486. package/locales/ta.json +1280 -0
  487. package/locales/th.json +1280 -0
  488. package/locales/tr.json +1280 -0
  489. package/locales/uk.json +1280 -0
  490. package/locales/ur.json +1281 -0
  491. package/locales/vi.json +1280 -0
  492. package/locales/yo.json +1280 -0
  493. package/locales/zh-Hans.json +1280 -0
  494. package/locales/zh-Hant.json +1280 -0
  495. package/package.json +139 -5
  496. package/store-catalog.schema.json +65 -0
  497. package/theme.schema.json +4659 -0
  498. package/windows/installer.nsi +926 -0
  499. package/windows/languages/Basque.nsh +28 -0
  500. package/windows/languages/Catalan.nsh +28 -0
  501. package/windows/languages/Croatian.nsh +28 -0
  502. package/windows/languages/Czech.nsh +28 -0
  503. package/windows/languages/Danish.nsh +28 -0
  504. package/windows/languages/Finnish.nsh +28 -0
  505. package/windows/languages/Galician.nsh +28 -0
  506. package/windows/languages/Greek.nsh +28 -0
  507. package/windows/languages/Hungarian.nsh +28 -0
  508. package/windows/languages/Indonesian.nsh +28 -0
  509. package/windows/languages/Irish.nsh +28 -0
  510. package/windows/languages/Malay.nsh +28 -0
  511. package/windows/languages/Polish.nsh +28 -0
  512. package/windows/languages/Romanian.nsh +28 -0
  513. package/windows/languages/Serbian.nsh +28 -0
  514. package/windows/languages/Slovak.nsh +28 -0
  515. package/windows/languages/Thai.nsh +28 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"column.js","sourceRoot":"","sources":["../../../runtime/src/column.ts"],"names":[],"mappings":"AAAA,mGAAmG;AACnG,kGAAkG;AAClG,+FAA+F;AAC/F,kGAAkG;AAClG,mGAAmG;AACnG,kGAAkG;AAClG,iGAAiG;AACjG,mEAAmE;AAEnE,OAAO,EAAE,QAAQ,EAAuB,MAAM,aAAa,CAAC;AA2D5D,MAAM,SAAS,GAAG,EAAE,CAAC;AACrB,MAAM,cAAc,GAAG,GAAG,CAAC;AAC3B,MAAM,OAAO,GAAG,IAAI,CAAC;AAErB,gGAAgG;AAChG,4BAA4B;AAE5B,MAAM,UAAU,qBAAqB,CAAC,KAAc;IAClD,IAAI,CAAC,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAO,IAAI,CAAC;IACrD,MAAM,GAAG,GAAG,KAAgC,CAAC;IAC7C,IAAI,OAAO,GAAG,CAAC,GAAG,KAAK,QAAQ,IAAI,GAAG,CAAC,GAAG,CAAC,MAAM,GAAG,IAAI;QAAE,OAAO,IAAI,CAAC;IACtE,MAAM,OAAO,GAAG,CAAC,GAAG,CAAC,OAAO,IAAI,OAAO,GAAG,CAAC,OAAO,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAA4B,CAAC;IAC/G,MAAM,KAAK,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;SAC9D,MAAM,CAAC,CAAC,IAAI,EAAkB,EAAE,CAAC,OAAO,IAAI,KAAK,QAAQ,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC,IAAI,IAAI,CAAC,MAAM,IAAI,cAAc,CAAC;SACrH,KAAK,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC;IACvB,MAAM,GAAG,GAAG,CAAC,CAAU,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,KAAK,QAAQ,IAAI,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACxG,OAAO;QACL,GAAG,EAAE,GAAG,CAAC,GAAG;QACZ,OAAO,EAAE,GAAG,CAAC,OAAO,KAAK,aAAa,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,SAAS;QAClE,OAAO,EAAE,EAAE,KAAK,EAAE,WAAW,EAAE,OAAO,CAAC,WAAW,KAAK,IAAI,EAAE,WAAW,EAAE,OAAO,CAAC,WAAW,KAAK,IAAI,EAAE,SAAS,EAAE,OAAO,CAAC,SAAS,KAAK,IAAI,EAAE;QAC/I,MAAM,EAAE,GAAG,CAAC,MAAM,KAAK,KAAK;QAC5B,OAAO,EAAE,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC;QACzB,OAAO,EAAE,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC;QACzB,IAAI,EAAE,OAAO,GAAG,CAAC,IAAI,KAAK,QAAQ,IAAI,GAAG,CAAC,IAAI,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE;KAC5E,CAAC;AACJ,CAAC;AAED,2GAA2G;AAC3G,MAAM,UAAU,SAAS,CAAC,IAAY;IACpC,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;IACzB,IAAI,CAAC,IAAI;QAAE,OAAO,IAAI,CAAC;IACvB,MAAM,KAAK,GAAG,qBAAqB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC/C,IAAI,CAAC,KAAK;QAAE,OAAO,IAAI,CAAC,WAAW,EAAE,CAAC;IACtC,IAAI,CAAC;QACH,OAAO,IAAI,MAAM,CAAC,KAAK,CAAC,CAAC,CAAE,EAAE,KAAK,CAAC,CAAC,CAAE,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;IACpF,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAID,+EAA+E;AAC/E,MAAM,UAAU,cAAc,CAAC,OAA4B;IACzD,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,EAA2B,EAAE,CAAC,IAAI,KAAK,IAAI,CAAC,CAAC;IACpG,MAAM,MAAM,GAAG,KAAK,CAAC,MAAM,GAAG,CAAC,IAAI,OAAO,CAAC,WAAW,IAAI,OAAO,CAAC,WAAW,IAAI,OAAO,CAAC,SAAS,CAAC;IACnG,IAAI,CAAC,MAAM;QAAE,OAAO,GAAG,EAAE,CAAC,KAAK,CAAC;IAChC,OAAO,IAAI,CAAC,EAAE;QACZ,IAAI,OAAO,CAAC,WAAW,IAAI,IAAI,CAAC,KAAK;YAAE,OAAO,IAAI,CAAC;QACnD,IAAI,OAAO,CAAC,WAAW,IAAI,IAAI,CAAC,MAAM;YAAE,OAAO,IAAI,CAAC;QACpD,IAAI,OAAO,CAAC,SAAS,IAAI,CAAC,IAAI,CAAC,KAAK;YAAE,OAAO,IAAI,CAAC;QAClD,IAAI,CAAC,KAAK,CAAC,MAAM;YAAE,OAAO,KAAK,CAAC;QAChC,MAAM,KAAK,GAAG,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC;QACtC,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YACzB,IAAI,OAAO,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC;gBAAE,OAAO,IAAI,CAAC;QAC1F,CAAC;QACD,OAAO,KAAK,CAAC;IACf,CAAC,CAAC;AACJ,CAAC;AAED,kEAAkE;AAClE,MAAM,UAAU,YAAY,CAAC,IAAY,EAAE,MAAc;IACvD,IAAI,CAAC;QACH,MAAM,CAAC,GAAG,IAAI,GAAG,CAAC,IAAI,CAAC,CAAC;QACxB,MAAM,CAAC,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,CAAC;QAC1B,MAAM,IAAI,GAAG,CAAC,GAAQ,EAAE,EAAE,CAAC,GAAG,CAAC,QAAQ,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,IAAI,GAAG,CAAC;QACnE,OAAO,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC,MAAM,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC,MAAM,CAAC;IAC/E,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAsBD,MAAM,UAAU,mBAAmB;IACjC,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;IAC/B,MAAM,MAAM,GAAG,IAAI,GAAG,EAAU,CAAC;IACjC,IAAI,QAAQ,GAAG,KAAK,CAAC;IACrB,MAAM,QAAQ,GAAG,CAAC,GAAgB,EAAE,EAAU,EAAE,EAAE;QAChD,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QACZ,IAAI,GAAG,CAAC,IAAI,GAAG,OAAO;YAAE,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,KAAe,CAAC,CAAC;IAC1E,CAAC,CAAC;IACF,OAAO;QACL,OAAO,CAAC,OAAO,EAAE,QAAQ;YACvB,IAAI,CAAC,OAAO,CAAC,MAAM;gBAAE,OAAO;YAC5B,IAAI,CAAC,QAAQ,EAAE,CAAC;gBACd,QAAQ,GAAG,IAAI,CAAC;gBAChB,KAAK,MAAM,EAAE,IAAI,OAAO;oBAAE,QAAQ,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;gBAC7C,OAAO;YACT,CAAC;YACD,MAAM,OAAO,GAAG,OAAO,CAAC,SAAS,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC;YACtD,MAAM,QAAQ,GAAG,OAAO,CAAC,SAAS,CAAC,EAAE,CAAC,EAAE,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC;YAC3D,MAAM,KAAK,GAAG,QAAQ,IAAI,CAAC,IAAI,OAAO,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC;YACpF,OAAO,CAAC,OAAO,CAAC,CAAC,EAAE,EAAE,KAAK,EAAE,EAAE;gBAC5B,IAAI,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC;oBACnC,IAAI,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC;wBAAE,QAAQ,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;oBAC9D,OAAO;gBACT,CAAC;gBACD,IAAI,KAAK,IAAI,CAAC,IAAI,KAAK,GAAG,KAAK,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;oBAAE,QAAQ,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;;oBACtE,QAAQ,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;YAC1B,CAAC,CAAC,CAAC;QACL,CAAC;QACD,IAAI,CAAC,EAAE;YACL,IAAI,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC;gBAAE,QAAQ,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;QAC5C,CAAC;QACD,QAAQ;YACN,KAAK,MAAM,EAAE,IAAI,MAAM;gBAAE,QAAQ,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;YAC5C,MAAM,CAAC,KAAK,EAAE,CAAC;QACjB,CAAC;QACD,KAAK,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,IAAI;QACxB,UAAU,CAAC,OAAO;YAChB,KAAK,IAAI,CAAC,GAAG,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE;gBAAE,IAAI,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAE,CAAC;oBAAE,OAAO,OAAO,CAAC,CAAC,CAAE,CAAC;YAC9F,OAAO,IAAI,CAAC;QACd,CAAC;QACD,QAAQ,EAAE,EAAE,CAAC,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC;KAC/B,CAAC;AACJ,CAAC;AAED,gGAAgG;AAChG,kBAAkB;AAElB,MAAM,KAAK,GAAG,CAAC,IAAgB,EAAE,EAAE,CAAC,CAAC;IACnC,KAAK,EAAE,GAAG,IAAI,CAAC,MAAM,aAAa;IAClC,MAAM,EAAE,QAAQ,IAAI,CAAC,MAAM,SAAS;IACpC,IAAI,EAAE,QAAQ,IAAI,CAAC,MAAM,cAAc;IACvC,OAAO,EAAE,QAAQ,IAAI,CAAC,MAAM,UAAU;IACtC,QAAQ,EAAE,QAAQ,IAAI,CAAC,MAAM,WAAW;IACxC,MAAM,EAAE,QAAQ,IAAI,CAAC,MAAM,SAAS;CACrC,CAAC,CAAC;AAEH,6FAA6F;AAC7F,MAAM,UAAU,cAAc,CAAC,IAAgB,EAAE,OAAsB;IACrE,MAAM,CAAC,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC;IACtB,MAAM,IAAI,GAAG,QAAQ,CAAC,CAAC,MAAM,GAAG,CAAC;IACjC,MAAM,KAAK,GAAG;QACZ,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,IAAI,QAAQ,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,iCAAiC,CAAC,CAAC,CAAC,EAAE;QAC5F,IAAI,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC,CAAC,GAAG,IAAI,IAAI,CAAC,CAAC,IAAI,SAAS,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,iCAAiC,CAAC,CAAC,CAAC,EAAE;QACpH,GAAG,IAAI,IAAI,IAAI,CAAC,IAAI,8GAA8G;QAClI,GAAG,IAAI,KAAK,CAAC,CAAC,QAAQ,iCAAiC;QACvD,iGAAiG;QACjG,GAAG,IAAI,6BAA6B;QACpC,IAAI,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,IAAI,EAAE;KAC1B,CAAC;IACF,OAAO,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1C,CAAC;AAOD,MAAM,UAAU,iBAAiB,CAAC,GAAiB,EAAE,IAAgB,EAAE,UAAyB,EAAE;IAChG,MAAM,GAAG,GAAG,GAAG,CAAC,QAAQ,CAAC;IACzB,MAAM,CAAC,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC;IACtB,MAAM,IAAI,GAAG,GAAG,EAAE,CAAC,GAAG,CAAC,eAAqC,CAAC;IAC7D,IAAI,MAAM,GAAwB,IAAI,CAAC;IACvC,IAAI,OAAO,GAAmC,GAAG,EAAE,CAAC,KAAK,CAAC;IAC1D,IAAI,OAAO,GAAG,mBAAmB,EAAE,CAAC;IACpC,IAAI,KAAK,GAA0B,IAAI,CAAC;IACxC,IAAI,QAAQ,GAAgC,IAAI,CAAC;IACjD,MAAM,QAAQ,GAAG,IAAI,OAAO,EAAW,CAAC;IACxC,MAAM,GAAG,GAAG,IAAI,OAAO,EAAmB,CAAC;IAC3C,IAAI,QAAQ,GAAG,KAAK,CAAC;IACrB,IAAI,YAAY,GAAG,CAAC,CAAC,CAAC;IACtB,IAAI,WAAW,GAAG,CAAC,CAAC;IACpB,IAAI,OAAO,GAAG,EAAE,CAAC;IACjB,IAAI,OAAO,GAAG,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC;IAErC,MAAM,QAAQ,GAAG,GAAG,EAAE,CAAC,CAAC,CAAC,MAAM,IAAI,YAAY,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC;IAE/E,MAAM,WAAW,GAAG,GAAG,EAAE;QACvB,IAAI,CAAC,MAAM;YAAE,OAAO;QACpB,IAAI,KAAK,GAAG,GAAG,CAAC,cAAc,CAAC,CAAC,CAAC,KAAK,CAA4B,CAAC;QACnE,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,MAAM,MAAM,GAAG,GAAG,CAAC,IAAI,IAAI,IAAI,EAAE,CAAC;YAClC,IAAI,CAAC,MAAM;gBAAE,OAAO;YACpB,KAAK,GAAG,GAAG,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC;YACnC,KAAK,CAAC,EAAE,GAAG,CAAC,CAAC,KAAK,CAAC;YACnB,MAAM,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;QAC5B,CAAC;QACD,MAAM,GAAG,GAAG,cAAc,CAAC,IAAI,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC;QACjD,IAAI,KAAK,CAAC,WAAW,KAAK,GAAG;YAAE,KAAK,CAAC,WAAW,GAAG,GAAG,CAAC;IACzD,CAAC,CAAC;IAEF,MAAM,MAAM,GAAG,CAAC,IAAa,EAAY,EAAE,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC;IACnH,MAAM,MAAM,GAAG,CAAC,IAAa,EAAE,EAAE,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,WAAW,IAAI,EAAE,CAAC;IAElF;oFACgF;IAChF,MAAM,KAAK,GAAG,GAAG,EAAE,CAAC,GAAG,CAAC,eAAe,KAAK,QAAQ,IAAI,GAAG,CAAC,UAAU,GAAG,EAAE,IAAI,GAAG,CAAC,WAAW,GAAG,EAAE,CAAC;IACpG,MAAM,QAAQ,GAAG,CAAC,IAAa,EAAE,EAAE;QACjC,IAAI,CAAC,KAAK,EAAE;YAAE,OAAO,KAAK,CAAC;QAC3B,MAAM,GAAG,GAAG,IAAI,CAAC,qBAAqB,EAAE,CAAC;QACzC,MAAM,MAAM,GAAG,GAAG,CAAC,WAAW,IAAI,GAAG,CAAC,eAAe,CAAC,YAAY,CAAC;QACnE,qFAAqF;QACrF,OAAO,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,GAAG,CAAC,GAAG,GAAG,MAAM,IAAI,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,CAAC,IAAI,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IAC/H,CAAC,CAAC;IAEF,MAAM,OAAO,GAAG,GAAG,EAAE;QACnB,IAAI,CAAC;YAAC,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,YAAY,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAAC,CAAC;QAAC,MAAM,CAAC;YAAC,OAAO,CAAC,CAAC;QAAC,CAAC;IAC5F,CAAC,CAAC;IAEF,MAAM,MAAM,GAAG,GAAG,EAAE;QAClB,IAAI,CAAC,OAAO,CAAC,QAAQ;YAAE,OAAO;QAC9B,MAAM,KAAK,GAAG,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,OAAO,CAAC,KAAK,EAAE,GAAG,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAC9E,IAAI,KAAK,KAAK,YAAY;YAAE,OAAO;QACnC,IAAI,WAAW;YAAE,OAAO;QACxB,WAAW,GAAG,GAAG,CAAC,UAAU,CAAC,GAAG,EAAE;YAChC,WAAW,GAAG,CAAC,CAAC;YAChB,MAAM,GAAG,GAAG,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,OAAO,CAAC,KAAK,EAAE,GAAG,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;YAC5E,IAAI,GAAG,KAAK,YAAY;gBAAE,OAAO;YACjC,YAAY,GAAG,GAAG,CAAC;YACnB,IAAI,CAAC;gBAAC,OAAO,CAAC,QAAQ,EAAE,CAAC,GAAG,CAAC,CAAC;YAAC,CAAC;YAAC,MAAM,CAAC,CAAC,8BAA8B,CAAC,CAAC;QAC3E,CAAC,EAAE,GAAG,CAAC,CAAC;IACV,CAAC,CAAC;IAEF,MAAM,cAAc,GAAG,GAAG,EAAE;QAC1B,IAAI,QAAQ,IAAI,OAAO,GAAG,CAAC,oBAAoB,KAAK,UAAU;YAAE,OAAO;QACvE,QAAQ,GAAG,IAAI,GAAG,CAAC,oBAAoB,CAAC,OAAO,CAAC,EAAE;YAChD,IAAI,CAAC,KAAK,EAAE;gBAAE,OAAO;YACrB,IAAI,OAAO,GAAG,KAAK,CAAC;YACpB,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;gBAC5B,IAAI,CAAC,KAAK,CAAC,cAAc;oBAAE,SAAS;gBACpC,MAAM,EAAE,GAAG,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;gBACjC,IAAI,EAAE,IAAI,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC,EAAE,CAAC;oBAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;oBAAC,OAAO,GAAG,IAAI,CAAC;gBAAC,CAAC;gBACrE,IAAI,EAAE;oBAAE,KAAK,CAAC,MAAM,CAAC,eAAe,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;YACjD,CAAC;YACD,IAAI,OAAO;gBAAE,MAAM,EAAE,CAAC;QACxB,CAAC,EAAE,EAAE,SAAS,EAAE,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC;IACjC,CAAC,CAAC;IAEF,MAAM,KAAK,GAAG,GAAc,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,gBAAgB,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC;IAEnF,MAAM,IAAI,GAAG,GAAG,EAAE;QAChB,IAAI,CAAC,MAAM;YAAE,OAAO;QACpB,MAAM,IAAI,GAAG,IAAI,EAAE,CAAC;QACpB,IAAI,CAAC,IAAI;YAAE,OAAO;QAClB,qFAAqF;QACrF,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC,MAAM,CAAC;YAAE,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;QAClE,IAAI,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,MAAM,CAAC,OAAO;YAAE,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC,OAAO,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC;QAClG,WAAW,EAAE,CAAC;QACd,MAAM,MAAM,GAAG,QAAQ,EAAE,CAAC;QAC1B,IAAI,MAAM;YAAE,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;;YACrC,IAAI,CAAC,eAAe,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;QAClC,IAAI,GAAG,CAAC,QAAQ,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;YAAC,OAAO,GAAG,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC;YAAC,QAAQ,GAAG,KAAK,CAAC;QAAC,CAAC;QACrF,IAAI,MAAM,IAAI,CAAC,QAAQ,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;YACxC,IAAI,CAAC;gBAAC,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;YAAC,CAAC;YAAC,MAAM,CAAC;gBAAC,QAAQ,GAAG,IAAI,CAAC;YAAC,CAAC;QAC1E,CAAC;QACD,MAAM,IAAI,GAAG,KAAK,EAAE,CAAC;QACrB,MAAM,OAAO,GAAa,EAAE,CAAC;QAC7B,MAAM,OAAO,GAAG,IAAI,GAAG,EAAU,CAAC;QAClC,KAAK,MAAM,IAAI,IAAI,IAAI,EAAE,CAAC;YACxB,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,EAAE,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC;YACjD,IAAI,MAAM,GAAG,KAAK,CAAC;YACnB,IAAI,MAAM,EAAE,CAAC;gBACX,IAAI,CAAC;oBAAC,MAAM,GAAG,OAAO,CAAC,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,CAAC,EAAE,GAAG,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;gBAAC,CAAC;gBAAC,MAAM,CAAC;oBAAC,MAAM,GAAG,KAAK,CAAC;gBAAC,CAAC;YAC9F,CAAC;YACD,IAAI,MAAM;gBAAE,SAAS,CAAC,YAAY,CAAC,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;iBAC9C,IAAI,SAAS,CAAC,YAAY,CAAC,CAAC,CAAC,QAAQ,CAAC;gBAAE,SAAS,CAAC,eAAe,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC;YACnF,IAAI,CAAC,MAAM,IAAI,CAAC,MAAM,CAAC,MAAM,IAAI,MAAM;gBAAE,SAAS;YAClD,IAAI,EAAE,GAAkB,IAAI,CAAC;YAC7B,IAAI,CAAC;gBAAC,EAAE,GAAG,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;YAAC,CAAC;YAAC,MAAM,CAAC;gBAAC,EAAE,GAAG,IAAI,CAAC;YAAC,CAAC;YACpD,IAAI,CAAC,EAAE,IAAI,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC;gBAAE,SAAS;YAC1C,GAAG,CAAC,GAAG,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;YAClB,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YACjB,IAAI,QAAQ,CAAC,IAAI,CAAC;gBAAE,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;YACpC,cAAc,EAAE,CAAC;YACjB,IAAI,QAAQ,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;gBAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;gBAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;YAAC,CAAC;QACtF,CAAC;QACD,IAAI,MAAM,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC;YAC5B,OAAO,CAAC,OAAO,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;YAClC,KAAK,MAAM,IAAI,IAAI,IAAI,EAAE,CAAC;gBACxB,MAAM,EAAE,GAAG,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;gBACzB,IAAI,CAAC,EAAE;oBAAE,SAAS;gBAClB,IAAI,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC;oBAAE,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;qBACrD,IAAI,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC,MAAM,CAAC;oBAAE,IAAI,CAAC,eAAe,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;YACvE,CAAC;QACH,CAAC;QACD,MAAM,EAAE,CAAC;IACX,CAAC,CAAC;IAEF,MAAM,KAAK,GAAG,CAAC,KAAoB,EAAE,EAAE;QACrC,IAAI,CAAC,MAAM,IAAI,CAAC,KAAK,CAAC,MAAM,IAAI,KAAK,CAAC,OAAO,IAAI,KAAK,CAAC,OAAO,IAAI,KAAK,CAAC,QAAQ;YAAE,OAAO;QACzF,MAAM,GAAG,GAAG,KAAK,CAAC,GAAG,CAAC,WAAW,EAAE,CAAC;QACpC,IAAI,GAAG,KAAK,GAAG,IAAI,GAAG,KAAK,GAAG;YAAE,OAAO;QACvC,KAAK,CAAC,cAAc,EAAE,CAAC;QACvB,KAAK,CAAC,wBAAwB,EAAE,CAAC;QACjC,IAAI,GAAG,KAAK,GAAG;YAAE,MAAM,CAAC,QAAQ,EAAE,CAAC;;YAC9B,MAAM,CAAC,YAAY,EAAE,CAAC;IAC7B,CAAC,CAAC;IAEF,MAAM,YAAY,GAAG,GAAG,EAAE,GAAG,IAAI,KAAK,EAAE;QAAE,KAAK,EAAE,QAAQ,EAAE,CAAC,CAAC,CAAC,CAAC;IAE/D,MAAM,KAAK,GAAG,GAAG,EAAE;QACjB,IAAI,KAAK;YAAE,OAAO;QAClB,KAAK,GAAG,QAAQ,CAAC,GAAG,EAAE,IAAI,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,CAAC;QAChD,GAAG,CAAC,gBAAgB,CAAC,SAAS,EAAE,KAAK,EAAE,IAAI,CAAC,CAAC;QAC7C,GAAG,CAAC,gBAAgB,CAAC,kBAAkB,EAAE,YAAY,CAAC,CAAC;QACvD,GAAG,CAAC,gBAAgB,CAAC,QAAQ,EAAE,YAAY,CAAC,CAAC;QAC7C,GAAG,CAAC,gBAAgB,CAAC,QAAQ,EAAE,QAAQ,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;IAC9D,CAAC,CAAC;IAEF,IAAI,WAAW,GAAG,CAAC,CAAC;IACpB,MAAM,QAAQ,GAAG,GAAG,EAAE;QACpB,IAAI,WAAW;YAAE,OAAO;QACxB,WAAW,GAAG,GAAG,CAAC,qBAAqB,CAAC,GAAG,EAAE,GAAG,WAAW,GAAG,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;IAChF,CAAC,CAAC;IAEF,MAAM,IAAI,GAAG,GAAG,EAAE;QAChB,KAAK,EAAE,OAAO,EAAE,CAAC;QACjB,KAAK,GAAG,IAAI,CAAC;QACb,QAAQ,EAAE,UAAU,EAAE,CAAC;QACvB,QAAQ,GAAG,IAAI,CAAC;QAChB,GAAG,CAAC,mBAAmB,CAAC,SAAS,EAAE,KAAK,EAAE,IAAI,CAAC,CAAC;QAChD,GAAG,CAAC,mBAAmB,CAAC,kBAAkB,EAAE,YAAY,CAAC,CAAC;QAC1D,GAAG,CAAC,mBAAmB,CAAC,QAAQ,EAAE,YAAY,CAAC,CAAC;QAChD,GAAG,CAAC,mBAAmB,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;QAC5C,IAAI,WAAW,EAAE,CAAC;YAAC,GAAG,CAAC,YAAY,CAAC,WAAW,CAAC,CAAC;YAAC,WAAW,GAAG,CAAC,CAAC;QAAC,CAAC;QACpE,MAAM,IAAI,GAAG,IAAI,EAAE,CAAC;QACpB,IAAI,EAAE,eAAe,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;QAChC,IAAI,EAAE,eAAe,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;QAC9B,IAAI,EAAE,eAAe,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;QACjC,GAAG,CAAC,cAAc,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;QACtC,KAAK,MAAM,EAAE,IAAI,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,gBAAgB,CAAC,IAAI,CAAC,CAAC,QAAQ,OAAO,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,EAAE,CAAC;YACpF,EAAE,CAAC,eAAe,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC;YAC/B,EAAE,CAAC,eAAe,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;QAC/B,CAAC;IACH,CAAC,CAAC;IAEF,MAAM,MAAM,GAAiB;QAC3B,GAAG,CAAC,KAAK;YACP,MAAM,IAAI,GAAG,qBAAqB,CAAC,KAAK,CAAC,CAAC;YAC1C,IAAI,CAAC,IAAI,EAAE,CAAC;gBACV,IAAI,MAAM,EAAE,CAAC;oBAAC,MAAM,GAAG,IAAI,CAAC;oBAAC,IAAI,EAAE,CAAC;oBAAC,YAAY,GAAG,CAAC,CAAC,CAAC;oBAAC,OAAO,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,CAAC;gBAAC,CAAC;gBAChF,OAAO;YACT,CAAC;YACD,MAAM,KAAK,GAAG,CAAC,MAAM,CAAC;YACtB,MAAM,aAAa,GAAG,CAAC,CAAC,MAAM,IAAI,MAAM,CAAC,GAAG,KAAK,IAAI,CAAC,GAAG,CAAC;YAC1D,MAAM,GAAG,IAAI,CAAC;YACd,OAAO,GAAG,cAAc,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YACvC,IAAI,KAAK,IAAI,aAAa,EAAE,CAAC;gBAAC,OAAO,GAAG,mBAAmB,EAAE,CAAC;gBAAC,QAAQ,GAAG,KAAK,CAAC;YAAC,CAAC;YAClF,MAAM,IAAI,GAAG,IAAI,EAAE,CAAC;YACpB,IAAI,EAAE,YAAY,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;YACjC,IAAI,EAAE,YAAY,CAAC,CAAC,CAAC,OAAO,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC;YAC5C,IAAI,CAAC,KAAK,IAAI,OAAO,CAAC,IAAI,IAAI,CAAC,IAAI,IAAI,CAAC,OAAO,KAAK,OAAO,CAAC,IAAI;gBAAE,MAAM,CAAC,QAAQ,EAAE,CAAC;YACpF,IAAI,CAAC,KAAK,IAAI,OAAO,CAAC,IAAI,IAAI,CAAC,IAAI,IAAI,CAAC,OAAO,KAAK,OAAO,CAAC,IAAI;gBAAE,MAAM,CAAC,YAAY,EAAE,CAAC;YACxF,OAAO,GAAG,EAAE,IAAI,EAAE,IAAI,CAAC,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,OAAO,EAAE,CAAC;YACrD,WAAW,EAAE,CAAC;YACd,KAAK,EAAE,CAAC;YACR,KAAK,EAAE,QAAQ,EAAE,CAAC;YAClB,IAAI,CAAC,IAAI,CAAC,MAAM;gBAAE,MAAM,EAAE,CAAC;QAC7B,CAAC;QACD,QAAQ;YACN,OAAO,CAAC,QAAQ,EAAE,CAAC;YACnB,KAAK,MAAM,EAAE,IAAI,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,gBAAgB,CAAC,IAAI,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC;gBAAE,EAAE,CAAC,eAAe,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;YACjG,MAAM,EAAE,CAAC;QACX,CAAC;QACD,YAAY;YACV,MAAM,IAAI,GAAG,KAAK,EAAE,CAAC;YACrB,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,EAAgB,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;YACnF,MAAM,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC;YAC3C,MAAM,OAAO,GAAG,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;YAC5E,IAAI,OAAO;gBAAE,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC,OAAO,CAAC,IAAI,OAAO,CAAC,CAAC,cAAc,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,CAAC;iBAClF,IAAI,OAAO,EAAE,GAAG,CAAC;gBAAE,GAAG,CAAC,QAAQ,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,CAAC,CAAC;QACnD,CAAC;QACD,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,OAAO,CAAC,KAAK,EAAE,GAAG,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAC/E,OAAO,KAAK,MAAM,GAAG,IAAI,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;KACrC,CAAC;IACF,OAAO,MAAM,CAAC;AAChB,CAAC","sourcesContent":["// Power User Mode, page side: a site tab that is a deck column (see shell/deckModel.ts). The shell\n// lays the column out; native code hands this module the column's config. Here the page hides the\n// site's chrome (rail, side column, floating buttons), lets the content column fill the width,\n// applies the column's density and filters, and tracks unread items. It never makes a request and\n// never clicks anything on its own except what the adapter's `prepare` does (navigation only, e.g.\n// selecting one of the site's own timeline tabs). Unread items are counted from what the site has\n// rendered: new item ids above the ones already seen, not yet scrolled into view. Only the count\n// leaves the page (the adapter reports it through its own bridge).\n\nimport { watchDom, type DomWatchHandle } from './domHub.ts';\n\nexport type ColumnDensity = 'compact' | 'comfortable';\n\nexport type ColumnFiltersConfig = { terms: string[]; hideReplies: boolean; hideReposts: boolean; mediaOnly: boolean };\n\n/** What native code delivers for one column (validated there too; see waybetter-host `ColumnConfig`). */\nexport type ColumnConfig = {\n /** The column's own page (its source); chrome that only makes sense elsewhere hides only here. */\n url: string;\n density: ColumnDensity;\n filters: ColumnFiltersConfig;\n /** Count unread items and report them. */\n unread: boolean;\n /** Increments when the shell asks to mark everything read / jump to the first unread item. */\n readSeq: number;\n jumpSeq: number;\n /** Source kind (adapter-defined), for `prepare`. */\n kind: string;\n};\n\nexport type ItemKind = { reply: boolean; repost: boolean; media: boolean };\n\nexport type ColumnSite = {\n /** Prefix of the attributes/ids this module owns (`data-<prefix>-column`, `<prefix>-column-css`). */\n prefix: string;\n /** The site's content column; it fills the column width. */\n keep: string;\n /** Always hidden in a column. */\n hide: readonly string[];\n /** Hidden only on the column's own page (e.g. a page title the column header repeats). */\n sourceHide?: readonly string[];\n /** Items for filters and the unread tracker. */\n itemSelector: string;\n /** The element hidden for a filtered item (default: the item itself). */\n container?(item: Element): Element;\n /** A stable id for an item (e.g. a post id), or null to ignore it. */\n itemId(item: Element): string | null;\n itemKind?(item: Element): ItemKind;\n itemText?(item: Element): string;\n /** Items the site announces but has not rendered yet (e.g. a \"Show 12 posts\" button); 0 = none. */\n pendingCount?(doc: Document): number;\n /** Site CSS for the column (density-aware); every rule should be scoped to `html[data-<prefix>-column]`. */\n css?(density: ColumnDensity): string;\n /** Navigation-only setup on the source page (e.g. select a timeline tab); true once done. */\n prepare?(doc: Document, config: ColumnConfig): boolean;\n};\n\nexport type ColumnHandle = {\n set(config: unknown): void;\n markRead(): void;\n jumpToUnread(): void;\n /** Current unread count (tracked + pending), 0 when off. */\n unread(): number;\n dispose(): void;\n};\n\nexport type ColumnWindow = Window & typeof globalThis;\n\nconst MAX_TERMS = 32;\nconst MAX_TERM_CHARS = 200;\nconst MAX_IDS = 2000;\n\n// ---------------------------------------------------------------------------------------------\n// Config and filters (pure)\n\nexport function normalizeColumnConfig(value: unknown): ColumnConfig | null {\n if (!value || typeof value !== 'object') return null;\n const raw = value as Record<string, unknown>;\n if (typeof raw.url !== 'string' || raw.url.length > 2048) return null;\n const filters = (raw.filters && typeof raw.filters === 'object' ? raw.filters : {}) as Record<string, unknown>;\n const terms = (Array.isArray(filters.terms) ? filters.terms : [])\n .filter((term): term is string => typeof term === 'string' && term.trim().length > 0 && term.length <= MAX_TERM_CHARS)\n .slice(0, MAX_TERMS);\n const seq = (n: unknown) => (typeof n === 'number' && Number.isFinite(n) && n >= 0 ? Math.floor(n) : 0);\n return {\n url: raw.url,\n density: raw.density === 'comfortable' ? 'comfortable' : 'compact',\n filters: { terms, hideReplies: filters.hideReplies === true, hideReposts: filters.hideReposts === true, mediaOnly: filters.mediaOnly === true },\n unread: raw.unread !== false,\n readSeq: seq(raw.readSeq),\n jumpSeq: seq(raw.jumpSeq),\n kind: typeof raw.kind === 'string' && raw.kind.length <= 24 ? raw.kind : '',\n };\n}\n\n/** `/pattern/flags` → RegExp (flags i, m, s, u only); anything else is a plain keyword. Invalid → null. */\nexport function parseTerm(term: string): RegExp | string | null {\n const text = term.trim();\n if (!text) return null;\n const match = /^\\/(.+)\\/([imsu]*)$/.exec(text);\n if (!match) return text.toLowerCase();\n try {\n return new RegExp(match[1]!, match[2]!.includes('i') ? match[2] : `${match[2]}i`);\n } catch {\n return null;\n }\n}\n\nexport type FilterInput = { text: string } & ItemKind;\n\n/** A predicate that says whether an item is hidden by the column's filters. */\nexport function compileFilters(filters: ColumnFiltersConfig): (item: FilterInput) => boolean {\n const terms = filters.terms.map(parseTerm).filter((term): term is RegExp | string => term !== null);\n const active = terms.length > 0 || filters.hideReplies || filters.hideReposts || filters.mediaOnly;\n if (!active) return () => false;\n return item => {\n if (filters.hideReplies && item.reply) return true;\n if (filters.hideReposts && item.repost) return true;\n if (filters.mediaOnly && !item.media) return true;\n if (!terms.length) return false;\n const lower = item.text.toLowerCase();\n for (const term of terms) {\n if (typeof term === 'string' ? lower.includes(term) : term.test(item.text)) return true;\n }\n return false;\n };\n}\n\n/** Same page: origin, path (trailing slash ignored) and query. */\nexport function isSourcePage(href: string, source: string): boolean {\n try {\n const a = new URL(href);\n const b = new URL(source);\n const path = (url: URL) => url.pathname.replace(/\\/+$/, '') || '/';\n return a.origin === b.origin && path(a) === path(b) && a.search === b.search;\n } catch {\n return false;\n }\n}\n\n// ---------------------------------------------------------------------------------------------\n// Unread tracking (pure: fed with the rendered items in document order)\n\nexport type UnreadTracker = {\n /**\n * The rendered items, top to bottom, and which of them are on screen right now. The first\n * non-empty observation is the baseline (read). Later, an id rendered above both the topmost\n * read id and the topmost item on screen is unread (new, not seen yet); ids below are older\n * items (read).\n */\n observe(ordered: readonly string[], onScreen: ReadonlySet<string>): void;\n /** An item came on screen. */\n seen(id: string): void;\n markRead(): void;\n count(): number;\n /** The unread item closest to the read ones (the next one to read, scrolling up), if rendered. */\n nextUnread(ordered: readonly string[]): string | null;\n isUnread(id: string): boolean;\n};\n\nexport function createUnreadTracker(): UnreadTracker {\n const read = new Set<string>();\n const unread = new Set<string>();\n let baseline = false;\n const remember = (set: Set<string>, id: string) => {\n set.add(id);\n if (set.size > MAX_IDS) set.delete(set.values().next().value as string);\n };\n return {\n observe(ordered, onScreen) {\n if (!ordered.length) return;\n if (!baseline) {\n baseline = true;\n for (const id of ordered) remember(read, id);\n return;\n }\n const topRead = ordered.findIndex(id => read.has(id));\n const topShown = ordered.findIndex(id => onScreen.has(id));\n const limit = topShown >= 0 && topRead >= 0 ? Math.min(topRead, topShown) : topRead;\n ordered.forEach((id, index) => {\n if (read.has(id) || unread.has(id)) {\n if (onScreen.has(id) && unread.delete(id)) remember(read, id);\n return;\n }\n if (limit >= 0 && index < limit && !onScreen.has(id)) remember(unread, id);\n else remember(read, id);\n });\n },\n seen(id) {\n if (unread.delete(id)) remember(read, id);\n },\n markRead() {\n for (const id of unread) remember(read, id);\n unread.clear();\n },\n count: () => unread.size,\n nextUnread(ordered) {\n for (let i = ordered.length - 1; i >= 0; i--) if (unread.has(ordered[i]!)) return ordered[i]!;\n return null;\n },\n isUnread: id => unread.has(id),\n };\n}\n\n// ---------------------------------------------------------------------------------------------\n// The page module\n\nconst names = (site: ColumnSite) => ({\n style: `${site.prefix}-column-css`,\n column: `data-${site.prefix}-column`,\n home: `data-${site.prefix}-column-home`,\n density: `data-${site.prefix}-density`,\n filtered: `data-${site.prefix}-filtered`,\n unread: `data-${site.prefix}-unread`,\n});\n\n/** Pure: the module's stylesheet. Every rule is scoped to the column attribute on <html>. */\nexport function buildColumnCss(site: ColumnSite, density: ColumnDensity): string {\n const n = names(site);\n const root = `html[${n.column}]`;\n const rules = [\n site.hide.length ? `${root} :is(${site.hide.join(', ')}) { display: none !important; }` : '',\n site.sourceHide?.length ? `${root}[${n.home}] :is(${site.sourceHide.join(', ')}) { display: none !important; }` : '',\n `${root} ${site.keep} { width: 100% !important; max-width: none !important; min-width: 0 !important; flex: 1 1 auto !important; }`,\n `${root} [${n.filtered}] { display: none !important; }`,\n // Narrow columns scroll without a scrollbar (the deck header shows where you are: unread count).\n `${root} { scrollbar-width: none; }`,\n site.css?.(density) ?? '',\n ];\n return rules.filter(Boolean).join('\\n');\n}\n\nexport type ColumnOptions = {\n /** Called with the unread count (tracked + pending) whenever it changes, at most every 250 ms. */\n onUnread?(count: number): void;\n};\n\nexport function installColumnMode(win: ColumnWindow, site: ColumnSite, options: ColumnOptions = {}): ColumnHandle {\n const doc = win.document;\n const n = names(site);\n const root = () => doc.documentElement as HTMLElement | null;\n let config: ColumnConfig | null = null;\n let matcher: (item: FilterInput) => boolean = () => false;\n let tracker = createUnreadTracker();\n let watch: DomWatchHandle | null = null;\n let observer: IntersectionObserver | null = null;\n const observed = new WeakSet<Element>();\n const ids = new WeakMap<Element, string>();\n let prepared = false;\n let lastReported = -1;\n let reportTimer = 0;\n let lastUrl = '';\n let lastSeq = { read: -1, jump: -1 };\n\n const onSource = () => !!config && isSourcePage(win.location.href, config.url);\n\n const ensureStyle = () => {\n if (!config) return;\n let style = doc.getElementById(n.style) as HTMLStyleElement | null;\n if (!style) {\n const parent = doc.head || root();\n if (!parent) return;\n style = doc.createElement('style');\n style.id = n.style;\n parent.appendChild(style);\n }\n const css = buildColumnCss(site, config.density);\n if (style.textContent !== css) style.textContent = css;\n };\n\n const kindOf = (item: Element): ItemKind => site.itemKind?.(item) ?? { reply: false, repost: false, media: false };\n const textOf = (item: Element) => site.itemText?.(item) ?? item.textContent ?? '';\n\n /** The column is on screen: the page is visible and the webview has a real size (hosts shrink a\n * hidden tab webview to a pixel, and not every engine reports it as hidden). */\n const shown = () => doc.visibilityState !== 'hidden' && win.innerWidth > 40 && win.innerHeight > 40;\n const onScreen = (item: Element) => {\n if (!shown()) return false;\n const box = item.getBoundingClientRect();\n const height = win.innerHeight || doc.documentElement.clientHeight;\n // Mostly in view: its top is on screen and at least 40 px (or all of it) is visible.\n return box.bottom > 0 && box.top < height && Math.min(box.bottom, height) - Math.max(box.top, 0) >= Math.min(40, box.height);\n };\n\n const pending = () => {\n try { return Math.max(0, Math.floor(site.pendingCount?.(doc) ?? 0)); } catch { return 0; }\n };\n\n const report = () => {\n if (!options.onUnread) return;\n const count = config?.unread ? Math.min(999, tracker.count() + pending()) : 0;\n if (count === lastReported) return;\n if (reportTimer) return;\n reportTimer = win.setTimeout(() => {\n reportTimer = 0;\n const now = config?.unread ? Math.min(999, tracker.count() + pending()) : 0;\n if (now === lastReported) return;\n lastReported = now;\n try { options.onUnread?.(now); } catch { /* reporting is best effort */ }\n }, 250);\n };\n\n const ensureObserver = () => {\n if (observer || typeof win.IntersectionObserver !== 'function') return;\n observer = new win.IntersectionObserver(entries => {\n if (!shown()) return;\n let changed = false;\n for (const entry of entries) {\n if (!entry.isIntersecting) continue;\n const id = ids.get(entry.target);\n if (id && tracker.isUnread(id)) { tracker.seen(id); changed = true; }\n if (id) entry.target.removeAttribute(n.unread);\n }\n if (changed) report();\n }, { threshold: [0, 0.5, 1] });\n };\n\n const items = (): Element[] => Array.from(doc.querySelectorAll(site.itemSelector));\n\n const scan = () => {\n if (!config) return;\n const html = root();\n if (!html) return;\n // A config delivered at document start arrives before the parser has created <html>.\n if (!html.hasAttribute(n.column)) html.setAttribute(n.column, '');\n if (html.getAttribute(n.density) !== config.density) html.setAttribute(n.density, config.density);\n ensureStyle();\n const source = onSource();\n if (source) html.setAttribute(n.home, '');\n else html.removeAttribute(n.home);\n if (win.location.href !== lastUrl) { lastUrl = win.location.href; prepared = false; }\n if (source && !prepared && site.prepare) {\n try { prepared = site.prepare(doc, config); } catch { prepared = true; }\n }\n const list = items();\n const ordered: string[] = [];\n const visible = new Set<string>();\n for (const item of list) {\n const container = site.container?.(item) ?? item;\n let hidden = false;\n if (source) {\n try { hidden = matcher({ text: textOf(item), ...kindOf(item) }); } catch { hidden = false; }\n }\n if (hidden) container.setAttribute(n.filtered, '');\n else if (container.hasAttribute(n.filtered)) container.removeAttribute(n.filtered);\n if (!source || !config.unread || hidden) continue;\n let id: string | null = null;\n try { id = site.itemId(item); } catch { id = null; }\n if (!id || ordered.includes(id)) continue;\n ids.set(item, id);\n ordered.push(id);\n if (onScreen(item)) visible.add(id);\n ensureObserver();\n if (observer && !observed.has(item)) { observed.add(item); observer.observe(item); }\n }\n if (source && config.unread) {\n tracker.observe(ordered, visible);\n for (const item of list) {\n const id = ids.get(item);\n if (!id) continue;\n if (tracker.isUnread(id)) item.setAttribute(n.unread, '');\n else if (item.hasAttribute(n.unread)) item.removeAttribute(n.unread);\n }\n }\n report();\n };\n\n const onKey = (event: KeyboardEvent) => {\n if (!config || !event.altKey || event.ctrlKey || event.metaKey || event.shiftKey) return;\n const key = event.key.toLowerCase();\n if (key !== 'r' && key !== 'u') return;\n event.preventDefault();\n event.stopImmediatePropagation();\n if (key === 'r') handle.markRead();\n else handle.jumpToUnread();\n };\n\n const onVisibility = () => { if (shown()) watch?.schedule(); };\n\n const start = () => {\n if (watch) return;\n watch = watchDom(win, scan, { phase: 'write' });\n win.addEventListener('keydown', onKey, true);\n doc.addEventListener('visibilitychange', onVisibility);\n win.addEventListener('resize', onVisibility);\n win.addEventListener('scroll', onScroll, { passive: true });\n };\n\n let scrollFrame = 0;\n const onScroll = () => {\n if (scrollFrame) return;\n scrollFrame = win.requestAnimationFrame(() => { scrollFrame = 0; report(); });\n };\n\n const stop = () => {\n watch?.dispose();\n watch = null;\n observer?.disconnect();\n observer = null;\n win.removeEventListener('keydown', onKey, true);\n doc.removeEventListener('visibilitychange', onVisibility);\n win.removeEventListener('resize', onVisibility);\n win.removeEventListener('scroll', onScroll);\n if (reportTimer) { win.clearTimeout(reportTimer); reportTimer = 0; }\n const html = root();\n html?.removeAttribute(n.column);\n html?.removeAttribute(n.home);\n html?.removeAttribute(n.density);\n doc.getElementById(n.style)?.remove();\n for (const el of Array.from(doc.querySelectorAll(`[${n.filtered}], [${n.unread}]`))) {\n el.removeAttribute(n.filtered);\n el.removeAttribute(n.unread);\n }\n };\n\n const handle: ColumnHandle = {\n set(value) {\n const next = normalizeColumnConfig(value);\n if (!next) {\n if (config) { config = null; stop(); lastReported = -1; options.onUnread?.(0); }\n return;\n }\n const first = !config;\n const sourceChanged = !!config && config.url !== next.url;\n config = next;\n matcher = compileFilters(next.filters);\n if (first || sourceChanged) { tracker = createUnreadTracker(); prepared = false; }\n const html = root();\n html?.setAttribute(n.column, '');\n html?.setAttribute(n.density, next.density);\n if (!first && lastSeq.read >= 0 && next.readSeq !== lastSeq.read) handle.markRead();\n if (!first && lastSeq.jump >= 0 && next.jumpSeq !== lastSeq.jump) handle.jumpToUnread();\n lastSeq = { read: next.readSeq, jump: next.jumpSeq };\n ensureStyle();\n start();\n watch?.schedule();\n if (!next.unread) report();\n },\n markRead() {\n tracker.markRead();\n for (const el of Array.from(doc.querySelectorAll(`[${n.unread}]`))) el.removeAttribute(n.unread);\n report();\n },\n jumpToUnread() {\n const list = items();\n const ordered = list.map(item => ids.get(item)).filter((id): id is string => !!id);\n const target = tracker.nextUnread(ordered);\n const element = target ? list.find(item => ids.get(item) === target) : null;\n if (element) (site.container?.(element) ?? element).scrollIntoView({ block: 'start' });\n else if (pending() > 0) win.scrollTo({ top: 0 });\n },\n unread: () => (config?.unread ? Math.min(999, tracker.count() + pending()) : 0),\n dispose() { config = null; stop(); },\n };\n return handle;\n}\n"]}
@@ -0,0 +1,19 @@
1
+ import type { CommandInfo } from './commands.ts';
2
+ export type Invoke = (command: string, args: Record<string, unknown>) => Promise<unknown>;
3
+ type Commands = {
4
+ list(): CommandInfo[];
5
+ onChange(callback: (list: CommandInfo[]) => void): () => void;
6
+ };
7
+ /** Reports the command list after it changes (batched, only real changes). Returns the disposer. */
8
+ export declare function installCommandReport(commands: Commands, invoke: Invoke | undefined, delay?: number): () => void;
9
+ type Toast = (message: string, options: {
10
+ tone: 'danger';
11
+ duration: number;
12
+ }) => void;
13
+ /**
14
+ * Developer mode (live reload): a plugin whose start failed shows `file:line — message` as a toast
15
+ * in this page. The host evaluates reloaded plugins with a `sourceURL`, so the line is the file's.
16
+ * `text` wraps the location in the app's words ("Plugin failed: {error}").
17
+ */
18
+ export declare function devErrorReporter(toast: () => Toast | undefined, text: (error: string) => string): (file: unknown, error: unknown) => void;
19
+ export {};
@@ -0,0 +1,47 @@
1
+ // Plugin palette commands: a site tab tells the shell which commands its plugins registered, so the
2
+ // command palette can list them under each plugin's name. Only `{ id, title, keywords }` strings
3
+ // travel (capped in the registry and again natively, waybetter-host `plugins::commands`), only
4
+ // about this tab, only when the list changes (`tab_report.commands`). Running one is the shell
5
+ // asking native code to call `api.commands.run(id)` in this page; `run` never leaves it.
6
+ //
7
+ // Developer mode's start failures are reported here too: a toast in the page with file and line.
8
+ import { devErrorLocation, formatDevError } from "./devErrors.js";
9
+ /** Reports the command list after it changes (batched, only real changes). Returns the disposer. */
10
+ export function installCommandReport(commands, invoke, delay = 80) {
11
+ if (!invoke)
12
+ return () => { };
13
+ let last = '[]';
14
+ let timer;
15
+ const send = () => {
16
+ timer = undefined;
17
+ const list = commands.list();
18
+ const json = JSON.stringify(list);
19
+ if (json === last)
20
+ return;
21
+ last = json;
22
+ invoke('tab_report', { report: { commands: list } }).catch(() => { });
23
+ };
24
+ const off = commands.onChange(() => {
25
+ if (timer === undefined)
26
+ timer = setTimeout(send, delay);
27
+ });
28
+ return () => { off(); if (timer !== undefined)
29
+ clearTimeout(timer); };
30
+ }
31
+ /**
32
+ * Developer mode (live reload): a plugin whose start failed shows `file:line — message` as a toast
33
+ * in this page. The host evaluates reloaded plugins with a `sourceURL`, so the line is the file's.
34
+ * `text` wraps the location in the app's words ("Plugin failed: {error}").
35
+ */
36
+ export function devErrorReporter(toast, text) {
37
+ return (file, error) => {
38
+ if (typeof file !== 'string')
39
+ return;
40
+ const location = formatDevError(devErrorLocation(error, file));
41
+ try {
42
+ toast()?.(text(location), { tone: 'danger', duration: 12000 });
43
+ }
44
+ catch { /* the page keeps working */ }
45
+ };
46
+ }
47
+ //# sourceMappingURL=commandReport.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"commandReport.js","sourceRoot":"","sources":["../../../runtime/src/commandReport.ts"],"names":[],"mappings":"AAAA,oGAAoG;AACpG,iGAAiG;AACjG,+FAA+F;AAC/F,+FAA+F;AAC/F,yFAAyF;AACzF,EAAE;AACF,iGAAiG;AAGjG,OAAO,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAKlE,oGAAoG;AACpG,MAAM,UAAU,oBAAoB,CAAC,QAAkB,EAAE,MAA0B,EAAE,KAAK,GAAG,EAAE;IAC7F,IAAI,CAAC,MAAM;QAAE,OAAO,GAAG,EAAE,GAAE,CAAC,CAAC;IAC7B,IAAI,IAAI,GAAG,IAAI,CAAC;IAChB,IAAI,KAAgD,CAAC;IACrD,MAAM,IAAI,GAAG,GAAG,EAAE;QAChB,KAAK,GAAG,SAAS,CAAC;QAClB,MAAM,IAAI,GAAG,QAAQ,CAAC,IAAI,EAAE,CAAC;QAC7B,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;QAClC,IAAI,IAAI,KAAK,IAAI;YAAE,OAAO;QAC1B,IAAI,GAAG,IAAI,CAAC;QACZ,MAAM,CAAC,YAAY,EAAE,EAAE,MAAM,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;IACvE,CAAC,CAAC;IACF,MAAM,GAAG,GAAG,QAAQ,CAAC,QAAQ,CAAC,GAAG,EAAE;QACjC,IAAI,KAAK,KAAK,SAAS;YAAE,KAAK,GAAG,UAAU,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;IAC3D,CAAC,CAAC,CAAC;IACH,OAAO,GAAG,EAAE,GAAG,GAAG,EAAE,CAAC,CAAC,IAAI,KAAK,KAAK,SAAS;QAAE,YAAY,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;AACxE,CAAC;AAID;;;;GAIG;AACH,MAAM,UAAU,gBAAgB,CAAC,KAA8B,EAAE,IAA+B;IAC9F,OAAO,CAAC,IAAa,EAAE,KAAc,EAAE,EAAE;QACvC,IAAI,OAAO,IAAI,KAAK,QAAQ;YAAE,OAAO;QACrC,MAAM,QAAQ,GAAG,cAAc,CAAC,gBAAgB,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC,CAAC;QAC/D,IAAI,CAAC;YAAC,KAAK,EAAE,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC,CAAC;QAAC,CAAC;QAAC,MAAM,CAAC,CAAC,4BAA4B,CAAC,CAAC;IAChH,CAAC,CAAC;AACJ,CAAC","sourcesContent":["// Plugin palette commands: a site tab tells the shell which commands its plugins registered, so the\n// command palette can list them under each plugin's name. Only `{ id, title, keywords }` strings\n// travel (capped in the registry and again natively, waybetter-host `plugins::commands`), only\n// about this tab, only when the list changes (`tab_report.commands`). Running one is the shell\n// asking native code to call `api.commands.run(id)` in this page; `run` never leaves it.\n//\n// Developer mode's start failures are reported here too: a toast in the page with file and line.\n\nimport type { CommandInfo } from './commands.ts';\nimport { devErrorLocation, formatDevError } from './devErrors.ts';\n\nexport type Invoke = (command: string, args: Record<string, unknown>) => Promise<unknown>;\ntype Commands = { list(): CommandInfo[]; onChange(callback: (list: CommandInfo[]) => void): () => void };\n\n/** Reports the command list after it changes (batched, only real changes). Returns the disposer. */\nexport function installCommandReport(commands: Commands, invoke: Invoke | undefined, delay = 80): () => void {\n if (!invoke) return () => {};\n let last = '[]';\n let timer: ReturnType<typeof setTimeout> | undefined;\n const send = () => {\n timer = undefined;\n const list = commands.list();\n const json = JSON.stringify(list);\n if (json === last) return;\n last = json;\n invoke('tab_report', { report: { commands: list } }).catch(() => {});\n };\n const off = commands.onChange(() => {\n if (timer === undefined) timer = setTimeout(send, delay);\n });\n return () => { off(); if (timer !== undefined) clearTimeout(timer); };\n}\n\ntype Toast = (message: string, options: { tone: 'danger'; duration: number }) => void;\n\n/**\n * Developer mode (live reload): a plugin whose start failed shows `file:line — message` as a toast\n * in this page. The host evaluates reloaded plugins with a `sourceURL`, so the line is the file's.\n * `text` wraps the location in the app's words (\"Plugin failed: {error}\").\n */\nexport function devErrorReporter(toast: () => Toast | undefined, text: (error: string) => string) {\n return (file: unknown, error: unknown) => {\n if (typeof file !== 'string') return;\n const location = formatDevError(devErrorLocation(error, file));\n try { toast()?.(text(location), { tone: 'danger', duration: 12000 }); } catch { /* the page keeps working */ }\n };\n}\n"]}
@@ -0,0 +1,72 @@
1
+ export type Dispose = () => void;
2
+ export type CommandDefinition = {
3
+ /** Unique within the plugin: letters, digits, `.`, `_`, `-`, 1–64 characters. */
4
+ id: string;
5
+ /** Shown in the palette (at most 80 characters are kept). */
6
+ title: string;
7
+ /** Extra words the palette matches (string or list; at most 160 characters are kept). */
8
+ keywords?: string | readonly string[];
9
+ /** Optional in-page shortcut such as `Alt+Shift+F` (works while this page has focus, not while typing). */
10
+ shortcut?: string;
11
+ run: () => unknown;
12
+ };
13
+ /** What the palette sees of a command: strings only. `id` is `<owner>:<command id>`. */
14
+ export type CommandInfo = {
15
+ id: string;
16
+ title: string;
17
+ keywords: string;
18
+ };
19
+ export declare const COMMAND_LIMITS: Readonly<{
20
+ /** Commands one plugin may register. */
21
+ perOwner: 16;
22
+ /** Commands one page may report. */
23
+ total: 48;
24
+ id: 64;
25
+ title: 80;
26
+ keywords: 160;
27
+ owner: 128;
28
+ }>;
29
+ /** Owner of commands registered outside any plugin start (e.g. later, from a timer). */
30
+ export declare const NO_OWNER = "_";
31
+ export type Shortcut = {
32
+ key: string;
33
+ ctrl: boolean;
34
+ alt: boolean;
35
+ shift: boolean;
36
+ meta: boolean;
37
+ };
38
+ /** Parses `Ctrl+Alt+Shift+Meta+<key>` (case-insensitive; `Cmd`/`Mod` = Meta/Ctrl). Null when invalid. */
39
+ export declare function parseShortcut(value: unknown): Shortcut | null;
40
+ /** Whether a keydown matches a parsed shortcut. Letters and digits match by physical key too. */
41
+ export declare function matchesShortcut(event: Pick<KeyboardEvent, 'key' | 'code' | 'ctrlKey' | 'altKey' | 'shiftKey' | 'metaKey'>, shortcut: Shortcut): boolean;
42
+ export type CommandRegistry = {
43
+ /** Registers a command for the current owner; returns its disposer. Throws on invalid input or caps. */
44
+ register(definition: CommandDefinition): Dispose;
45
+ /** The palette's view of every command (strings only), in registration order. */
46
+ list(): CommandInfo[];
47
+ /** Runs `<owner>:<id>` in this page. False when there is no such command. */
48
+ run(id: string): boolean;
49
+ /** Calls `callback(list())` after commands change (batched), until disposed. */
50
+ onChange(callback: (list: CommandInfo[]) => void): Dispose;
51
+ /** Host hook: runs `fn` with `owner` as the owner of commands registered meanwhile. */
52
+ withOwner<T>(owner: string, fn: () => T): T;
53
+ /** Host hook: removes every command of `owner` (called after a plugin stops). */
54
+ removeOwner(owner: string): void;
55
+ };
56
+ /** Registry internals the plugin API needs (not handed to plugins). */
57
+ export type CommandRegistryInternal = CommandRegistry & {
58
+ /** The owner commands registered right now would get. */
59
+ currentOwner(): string;
60
+ /** Registers for an explicit owner (a scope remembers the plugin that created it). */
61
+ registerFor(owner: string, definition: CommandDefinition): Dispose;
62
+ };
63
+ export type CommandEnv = {
64
+ /** Where shortcut keydowns are listened to (the page's document). */
65
+ target?: Pick<EventTarget, 'addEventListener' | 'removeEventListener'>;
66
+ /** True while the user types (no shortcut then). */
67
+ isTyping?: (event: KeyboardEvent) => boolean;
68
+ /** Batches change notifications; defaults to a microtask. */
69
+ schedule?: (fn: () => void) => void;
70
+ report?: (error: unknown) => void;
71
+ };
72
+ export declare function createCommandRegistry(env?: CommandEnv): CommandRegistryInternal;
@@ -0,0 +1,214 @@
1
+ // Plugin commands for the shell's command palette (Ctrl+K).
2
+ //
3
+ // A plugin registers `{ id, title, keywords, shortcut?, run }` with `api.commands.register` (or
4
+ // `scope.commands.register`, removed on dispose). The registry is local to the page: the runtime
5
+ // reports `list()` (ids, titles and keywords only, capped) about this tab to the host, and the
6
+ // shell asks this tab to `run(id)` when the user picks one in the palette. `run` always executes
7
+ // here, in the plugin's own page; nothing crosses to the shell but these strings.
8
+ //
9
+ // Every command belongs to the plugin that registered it: the host starts a plugin inside
10
+ // `withOwner(file, ...)`, and stopping the plugin removes all of its commands (`removeOwner`), so
11
+ // a plugin that forgets to unregister cannot leave a dead entry in the palette.
12
+ export const COMMAND_LIMITS = Object.freeze({
13
+ /** Commands one plugin may register. */
14
+ perOwner: 16,
15
+ /** Commands one page may report. */
16
+ total: 48,
17
+ id: 64,
18
+ title: 80,
19
+ keywords: 160,
20
+ owner: 128,
21
+ });
22
+ /** Owner of commands registered outside any plugin start (e.g. later, from a timer). */
23
+ export const NO_OWNER = '_';
24
+ const COMMAND_ID = /^[A-Za-z0-9][A-Za-z0-9._-]{0,63}$/;
25
+ /** Plugin file names (the host's `valid_file_name`) and `_`. */
26
+ const OWNER_ID = /^(?:_|[A-Za-z0-9_\- ][A-Za-z0-9_.\- ]{0,127})$/;
27
+ const clean = (value, max) =>
28
+ // eslint-disable-next-line no-control-regex
29
+ value.replace(/[\u0000-\u001f\u007f]+/g, ' ').replace(/\s+/g, ' ').trim().slice(0, max);
30
+ /** Parses `Ctrl+Alt+Shift+Meta+<key>` (case-insensitive; `Cmd`/`Mod` = Meta/Ctrl). Null when invalid. */
31
+ export function parseShortcut(value) {
32
+ if (typeof value !== 'string' || value.length > 40)
33
+ return null;
34
+ const parts = value.split('+').map(part => part.trim()).filter(Boolean);
35
+ if (!parts.length)
36
+ return null;
37
+ const shortcut = { key: '', ctrl: false, alt: false, shift: false, meta: false };
38
+ for (const [index, raw] of parts.entries()) {
39
+ const part = raw.toLowerCase();
40
+ const last = index === parts.length - 1;
41
+ if (!last) {
42
+ if (part === 'ctrl' || part === 'control' || part === 'mod')
43
+ shortcut.ctrl = true;
44
+ else if (part === 'alt' || part === 'option')
45
+ shortcut.alt = true;
46
+ else if (part === 'shift')
47
+ shortcut.shift = true;
48
+ else if (part === 'meta' || part === 'cmd' || part === 'command')
49
+ shortcut.meta = true;
50
+ else
51
+ return null;
52
+ continue;
53
+ }
54
+ if (!/^(?:[a-z0-9]|f(?:[1-9]|1[0-2])|arrow(?:up|down|left|right)|enter|escape|space|[[\]\\;',./`=-])$/.test(part))
55
+ return null;
56
+ shortcut.key = part;
57
+ }
58
+ return shortcut.key ? shortcut : null;
59
+ }
60
+ /** Whether a keydown matches a parsed shortcut. Letters and digits match by physical key too. */
61
+ export function matchesShortcut(event, shortcut) {
62
+ if (event.ctrlKey !== shortcut.ctrl || event.altKey !== shortcut.alt || event.shiftKey !== shortcut.shift || event.metaKey !== shortcut.meta)
63
+ return false;
64
+ const key = shortcut.key;
65
+ if (/^[a-z]$/.test(key))
66
+ return event.code === `Key${key.toUpperCase()}` || event.key.toLowerCase() === key;
67
+ if (/^[0-9]$/.test(key))
68
+ return event.code === `Digit${key}` || event.key === key;
69
+ if (key === 'space')
70
+ return event.key === ' ' || event.code === 'Space';
71
+ return event.key.toLowerCase() === key;
72
+ }
73
+ export function createCommandRegistry(env = {}) {
74
+ const entries = [];
75
+ const listeners = new Set();
76
+ const report = env.report ?? ((error) => console.error('[wayBetter] command failed', error));
77
+ const schedule = env.schedule ?? ((fn) => { void Promise.resolve().then(fn); });
78
+ const owners = [];
79
+ let pending = false;
80
+ let keyListening = false;
81
+ const info = (entry) => ({ id: `${entry.owner}:${entry.id}`, title: entry.title, keywords: entry.keywords });
82
+ const list = () => entries.map(info);
83
+ const changed = () => {
84
+ syncKeys();
85
+ if (pending)
86
+ return;
87
+ pending = true;
88
+ schedule(() => {
89
+ pending = false;
90
+ const snapshot = list();
91
+ for (const listener of [...listeners]) {
92
+ try {
93
+ listener(snapshot);
94
+ }
95
+ catch (error) {
96
+ report(error);
97
+ }
98
+ }
99
+ });
100
+ };
101
+ const invoke = (entry) => {
102
+ try {
103
+ const result = entry.run();
104
+ if (result && typeof result.then === 'function')
105
+ result.then(undefined, report);
106
+ }
107
+ catch (error) {
108
+ report(error);
109
+ }
110
+ };
111
+ const onKeyDown = (event) => {
112
+ const key = event;
113
+ if (key.defaultPrevented || key.repeat || env.isTyping?.(key))
114
+ return;
115
+ const entry = entries.find(item => item.shortcut && matchesShortcut(key, item.shortcut));
116
+ if (!entry)
117
+ return;
118
+ key.preventDefault();
119
+ key.stopPropagation();
120
+ invoke(entry);
121
+ };
122
+ function syncKeys() {
123
+ const wanted = !!env.target && entries.some(entry => entry.shortcut);
124
+ if (wanted === keyListening)
125
+ return;
126
+ keyListening = wanted;
127
+ if (wanted)
128
+ env.target.addEventListener('keydown', onKeyDown, true);
129
+ else
130
+ env.target.removeEventListener('keydown', onKeyDown, true);
131
+ }
132
+ const currentOwner = () => owners[owners.length - 1] ?? NO_OWNER;
133
+ function registerFor(owner, definition) {
134
+ if (typeof owner !== 'string' || !OWNER_ID.test(owner))
135
+ throw new Error('commands.register: invalid owner');
136
+ if (!definition || typeof definition !== 'object')
137
+ throw new Error('commands.register: expected { id, title, run }');
138
+ const { id, title, keywords, shortcut, run } = definition;
139
+ if (typeof id !== 'string' || !COMMAND_ID.test(id))
140
+ throw new Error(`commands.register: invalid id ${JSON.stringify(id)} (letters, digits, . _ -, at most ${COMMAND_LIMITS.id})`);
141
+ if (typeof run !== 'function')
142
+ throw new Error('commands.register: run must be a function');
143
+ const shownTitle = typeof title === 'string' ? clean(title, COMMAND_LIMITS.title) : '';
144
+ if (!shownTitle)
145
+ throw new Error('commands.register: title is required');
146
+ const words = typeof keywords === 'string' ? keywords : Array.isArray(keywords) ? keywords.filter(word => typeof word === 'string').join(' ') : '';
147
+ const parsed = shortcut === undefined ? null : parseShortcut(shortcut);
148
+ if (shortcut !== undefined && !parsed)
149
+ throw new Error(`commands.register: invalid shortcut ${JSON.stringify(shortcut)}`);
150
+ const existing = entries.findIndex(entry => entry.owner === owner && entry.id === id);
151
+ if (existing < 0) {
152
+ if (entries.filter(entry => entry.owner === owner).length >= COMMAND_LIMITS.perOwner)
153
+ throw new Error(`commands.register: at most ${COMMAND_LIMITS.perOwner} commands per plugin`);
154
+ if (entries.length >= COMMAND_LIMITS.total)
155
+ throw new Error(`commands.register: at most ${COMMAND_LIMITS.total} commands per page`);
156
+ }
157
+ const entry = { owner, id, title: shownTitle, keywords: clean(words, COMMAND_LIMITS.keywords), shortcut: parsed, run: run };
158
+ // Registering the same id again replaces the command in place (a plugin reloading its settings).
159
+ if (existing >= 0)
160
+ entries.splice(existing, 1, entry);
161
+ else
162
+ entries.push(entry);
163
+ changed();
164
+ return () => {
165
+ const index = entries.indexOf(entry);
166
+ if (index < 0)
167
+ return;
168
+ entries.splice(index, 1);
169
+ changed();
170
+ };
171
+ }
172
+ return {
173
+ register: definition => registerFor(currentOwner(), definition),
174
+ registerFor,
175
+ currentOwner,
176
+ list,
177
+ run(fullId) {
178
+ if (typeof fullId !== 'string')
179
+ return false;
180
+ const entry = entries.find(item => `${item.owner}:${item.id}` === fullId);
181
+ if (!entry)
182
+ return false;
183
+ invoke(entry);
184
+ return true;
185
+ },
186
+ onChange(callback) {
187
+ listeners.add(callback);
188
+ return () => { listeners.delete(callback); };
189
+ },
190
+ withOwner(owner, fn) {
191
+ if (typeof owner !== 'string' || !OWNER_ID.test(owner))
192
+ return fn();
193
+ owners.push(owner);
194
+ try {
195
+ return fn();
196
+ }
197
+ finally {
198
+ owners.pop();
199
+ }
200
+ },
201
+ removeOwner(owner) {
202
+ let removed = false;
203
+ for (let index = entries.length - 1; index >= 0; index -= 1) {
204
+ if (entries[index].owner === owner) {
205
+ entries.splice(index, 1);
206
+ removed = true;
207
+ }
208
+ }
209
+ if (removed)
210
+ changed();
211
+ },
212
+ };
213
+ }
214
+ //# sourceMappingURL=commands.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"commands.js","sourceRoot":"","sources":["../../../runtime/src/commands.ts"],"names":[],"mappings":"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","sourcesContent":["// Plugin commands for the shell's command palette (Ctrl+K).\n//\n// A plugin registers `{ id, title, keywords, shortcut?, run }` with `api.commands.register` (or\n// `scope.commands.register`, removed on dispose). The registry is local to the page: the runtime\n// reports `list()` (ids, titles and keywords only, capped) about this tab to the host, and the\n// shell asks this tab to `run(id)` when the user picks one in the palette. `run` always executes\n// here, in the plugin's own page; nothing crosses to the shell but these strings.\n//\n// Every command belongs to the plugin that registered it: the host starts a plugin inside\n// `withOwner(file, ...)`, and stopping the plugin removes all of its commands (`removeOwner`), so\n// a plugin that forgets to unregister cannot leave a dead entry in the palette.\n\nexport type Dispose = () => void;\n\nexport type CommandDefinition = {\n /** Unique within the plugin: letters, digits, `.`, `_`, `-`, 1–64 characters. */\n id: string;\n /** Shown in the palette (at most 80 characters are kept). */\n title: string;\n /** Extra words the palette matches (string or list; at most 160 characters are kept). */\n keywords?: string | readonly string[];\n /** Optional in-page shortcut such as `Alt+Shift+F` (works while this page has focus, not while typing). */\n shortcut?: string;\n run: () => unknown;\n};\n\n/** What the palette sees of a command: strings only. `id` is `<owner>:<command id>`. */\nexport type CommandInfo = { id: string; title: string; keywords: string };\n\nexport const COMMAND_LIMITS = Object.freeze({\n /** Commands one plugin may register. */\n perOwner: 16,\n /** Commands one page may report. */\n total: 48,\n id: 64,\n title: 80,\n keywords: 160,\n owner: 128,\n});\n\n/** Owner of commands registered outside any plugin start (e.g. later, from a timer). */\nexport const NO_OWNER = '_';\n\nconst COMMAND_ID = /^[A-Za-z0-9][A-Za-z0-9._-]{0,63}$/;\n/** Plugin file names (the host's `valid_file_name`) and `_`. */\nconst OWNER_ID = /^(?:_|[A-Za-z0-9_\\- ][A-Za-z0-9_.\\- ]{0,127})$/;\n\nconst clean = (value: string, max: number) =>\n // eslint-disable-next-line no-control-regex\n value.replace(/[\\u0000-\\u001f\\u007f]+/g, ' ').replace(/\\s+/g, ' ').trim().slice(0, max);\n\nexport type Shortcut = { key: string; ctrl: boolean; alt: boolean; shift: boolean; meta: boolean };\n\n/** Parses `Ctrl+Alt+Shift+Meta+<key>` (case-insensitive; `Cmd`/`Mod` = Meta/Ctrl). Null when invalid. */\nexport function parseShortcut(value: unknown): Shortcut | null {\n if (typeof value !== 'string' || value.length > 40) return null;\n const parts = value.split('+').map(part => part.trim()).filter(Boolean);\n if (!parts.length) return null;\n const shortcut: Shortcut = { key: '', ctrl: false, alt: false, shift: false, meta: false };\n for (const [index, raw] of parts.entries()) {\n const part = raw.toLowerCase();\n const last = index === parts.length - 1;\n if (!last) {\n if (part === 'ctrl' || part === 'control' || part === 'mod') shortcut.ctrl = true;\n else if (part === 'alt' || part === 'option') shortcut.alt = true;\n else if (part === 'shift') shortcut.shift = true;\n else if (part === 'meta' || part === 'cmd' || part === 'command') shortcut.meta = true;\n else return null;\n continue;\n }\n if (!/^(?:[a-z0-9]|f(?:[1-9]|1[0-2])|arrow(?:up|down|left|right)|enter|escape|space|[[\\]\\\\;',./`=-])$/.test(part)) return null;\n shortcut.key = part;\n }\n return shortcut.key ? shortcut : null;\n}\n\n/** Whether a keydown matches a parsed shortcut. Letters and digits match by physical key too. */\nexport function matchesShortcut(event: Pick<KeyboardEvent, 'key' | 'code' | 'ctrlKey' | 'altKey' | 'shiftKey' | 'metaKey'>, shortcut: Shortcut): boolean {\n if (event.ctrlKey !== shortcut.ctrl || event.altKey !== shortcut.alt || event.shiftKey !== shortcut.shift || event.metaKey !== shortcut.meta) return false;\n const key = shortcut.key;\n if (/^[a-z]$/.test(key)) return event.code === `Key${key.toUpperCase()}` || event.key.toLowerCase() === key;\n if (/^[0-9]$/.test(key)) return event.code === `Digit${key}` || event.key === key;\n if (key === 'space') return event.key === ' ' || event.code === 'Space';\n return event.key.toLowerCase() === key;\n}\n\nexport type CommandRegistry = {\n /** Registers a command for the current owner; returns its disposer. Throws on invalid input or caps. */\n register(definition: CommandDefinition): Dispose;\n /** The palette's view of every command (strings only), in registration order. */\n list(): CommandInfo[];\n /** Runs `<owner>:<id>` in this page. False when there is no such command. */\n run(id: string): boolean;\n /** Calls `callback(list())` after commands change (batched), until disposed. */\n onChange(callback: (list: CommandInfo[]) => void): Dispose;\n /** Host hook: runs `fn` with `owner` as the owner of commands registered meanwhile. */\n withOwner<T>(owner: string, fn: () => T): T;\n /** Host hook: removes every command of `owner` (called after a plugin stops). */\n removeOwner(owner: string): void;\n};\n\n/** Registry internals the plugin API needs (not handed to plugins). */\nexport type CommandRegistryInternal = CommandRegistry & {\n /** The owner commands registered right now would get. */\n currentOwner(): string;\n /** Registers for an explicit owner (a scope remembers the plugin that created it). */\n registerFor(owner: string, definition: CommandDefinition): Dispose;\n};\n\ntype Entry = { owner: string; id: string; title: string; keywords: string; shortcut: Shortcut | null; run: () => unknown };\n\nexport type CommandEnv = {\n /** Where shortcut keydowns are listened to (the page's document). */\n target?: Pick<EventTarget, 'addEventListener' | 'removeEventListener'>;\n /** True while the user types (no shortcut then). */\n isTyping?: (event: KeyboardEvent) => boolean;\n /** Batches change notifications; defaults to a microtask. */\n schedule?: (fn: () => void) => void;\n report?: (error: unknown) => void;\n};\n\nexport function createCommandRegistry(env: CommandEnv = {}): CommandRegistryInternal {\n const entries: Entry[] = [];\n const listeners = new Set<(list: CommandInfo[]) => void>();\n const report = env.report ?? ((error: unknown) => console.error('[wayBetter] command failed', error));\n const schedule = env.schedule ?? ((fn: () => void) => { void Promise.resolve().then(fn); });\n const owners: string[] = [];\n let pending = false;\n let keyListening = false;\n\n const info = (entry: Entry): CommandInfo => ({ id: `${entry.owner}:${entry.id}`, title: entry.title, keywords: entry.keywords });\n const list = () => entries.map(info);\n const changed = () => {\n syncKeys();\n if (pending) return;\n pending = true;\n schedule(() => {\n pending = false;\n const snapshot = list();\n for (const listener of [...listeners]) {\n try { listener(snapshot); } catch (error) { report(error); }\n }\n });\n };\n const invoke = (entry: Entry) => {\n try {\n const result = entry.run();\n if (result && typeof (result as Promise<unknown>).then === 'function') (result as Promise<unknown>).then(undefined, report);\n } catch (error) { report(error); }\n };\n const onKeyDown = (event: Event) => {\n const key = event as KeyboardEvent;\n if (key.defaultPrevented || key.repeat || env.isTyping?.(key)) return;\n const entry = entries.find(item => item.shortcut && matchesShortcut(key, item.shortcut));\n if (!entry) return;\n key.preventDefault();\n key.stopPropagation();\n invoke(entry);\n };\n function syncKeys() {\n const wanted = !!env.target && entries.some(entry => entry.shortcut);\n if (wanted === keyListening) return;\n keyListening = wanted;\n if (wanted) env.target!.addEventListener('keydown', onKeyDown, true);\n else env.target!.removeEventListener('keydown', onKeyDown, true);\n }\n\n const currentOwner = () => owners[owners.length - 1] ?? NO_OWNER;\n\n function registerFor(owner: string, definition: CommandDefinition): Dispose {\n if (typeof owner !== 'string' || !OWNER_ID.test(owner)) throw new Error('commands.register: invalid owner');\n if (!definition || typeof definition !== 'object') throw new Error('commands.register: expected { id, title, run }');\n const { id, title, keywords, shortcut, run } = definition;\n if (typeof id !== 'string' || !COMMAND_ID.test(id)) throw new Error(`commands.register: invalid id ${JSON.stringify(id)} (letters, digits, . _ -, at most ${COMMAND_LIMITS.id})`);\n if (typeof run !== 'function') throw new Error('commands.register: run must be a function');\n const shownTitle = typeof title === 'string' ? clean(title, COMMAND_LIMITS.title) : '';\n if (!shownTitle) throw new Error('commands.register: title is required');\n const words = typeof keywords === 'string' ? keywords : Array.isArray(keywords) ? keywords.filter(word => typeof word === 'string').join(' ') : '';\n const parsed = shortcut === undefined ? null : parseShortcut(shortcut);\n if (shortcut !== undefined && !parsed) throw new Error(`commands.register: invalid shortcut ${JSON.stringify(shortcut)}`);\n const existing = entries.findIndex(entry => entry.owner === owner && entry.id === id);\n if (existing < 0) {\n if (entries.filter(entry => entry.owner === owner).length >= COMMAND_LIMITS.perOwner) throw new Error(`commands.register: at most ${COMMAND_LIMITS.perOwner} commands per plugin`);\n if (entries.length >= COMMAND_LIMITS.total) throw new Error(`commands.register: at most ${COMMAND_LIMITS.total} commands per page`);\n }\n const entry: Entry = { owner, id, title: shownTitle, keywords: clean(words, COMMAND_LIMITS.keywords), shortcut: parsed, run: run as () => unknown };\n // Registering the same id again replaces the command in place (a plugin reloading its settings).\n if (existing >= 0) entries.splice(existing, 1, entry); else entries.push(entry);\n changed();\n return () => {\n const index = entries.indexOf(entry);\n if (index < 0) return;\n entries.splice(index, 1);\n changed();\n };\n }\n\n return {\n register: definition => registerFor(currentOwner(), definition),\n registerFor,\n currentOwner,\n list,\n run(fullId) {\n if (typeof fullId !== 'string') return false;\n const entry = entries.find(item => `${item.owner}:${item.id}` === fullId);\n if (!entry) return false;\n invoke(entry);\n return true;\n },\n onChange(callback) {\n listeners.add(callback);\n return () => { listeners.delete(callback); };\n },\n withOwner(owner, fn) {\n if (typeof owner !== 'string' || !OWNER_ID.test(owner)) return fn();\n owners.push(owner);\n try { return fn(); } finally { owners.pop(); }\n },\n removeOwner(owner) {\n let removed = false;\n for (let index = entries.length - 1; index >= 0; index -= 1) {\n if (entries[index]!.owner === owner) { entries.splice(index, 1); removed = true; }\n }\n if (removed) changed();\n },\n };\n}\n"]}
@@ -0,0 +1,16 @@
1
+ export type DevErrorLocation = {
2
+ file: string;
3
+ line: number | null;
4
+ column: number | null;
5
+ message: string;
6
+ };
7
+ /** Default prefix the host uses for plugin source URLs. */
8
+ export declare const DEV_SOURCE_PREFIX = "wb-dev/";
9
+ /**
10
+ * The first stack frame inside `file` (evaluated as `<prefix><file>`), mapped back to the file's
11
+ * own line numbers. Line is null when no frame names the file (e.g. an error thrown from a timer
12
+ * in other code). The message is one line, at most 300 characters.
13
+ */
14
+ export declare function devErrorLocation(error: unknown, file: string, prefix?: string, lineOffset?: number): DevErrorLocation;
15
+ /** `file:line:column — message` (parts that are unknown are left out). */
16
+ export declare function formatDevError(location: DevErrorLocation): string;
@@ -0,0 +1,30 @@
1
+ // Live-reload developer mode: where a plugin's start failure happened, for the in-page error toast.
2
+ //
3
+ // The host evaluates a plugin with `//# sourceURL=<prefix><file>` (waybetter-host
4
+ // `dev_start_script`), so V8/JavaScriptCore stack frames name that URL with the line and column
5
+ // of the evaluated script; the plugin file's line 1 is line `1 + lineOffset` there.
6
+ /** Default prefix the host uses for plugin source URLs. */
7
+ export const DEV_SOURCE_PREFIX = 'wb-dev/';
8
+ const escapeRegExp = (value) => value.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
9
+ /**
10
+ * The first stack frame inside `file` (evaluated as `<prefix><file>`), mapped back to the file's
11
+ * own line numbers. Line is null when no frame names the file (e.g. an error thrown from a timer
12
+ * in other code). The message is one line, at most 300 characters.
13
+ */
14
+ export function devErrorLocation(error, file, prefix = DEV_SOURCE_PREFIX, lineOffset = 1) {
15
+ const text = error instanceof Error ? error.message : String(error);
16
+ const message = `${error instanceof Error && error.name && error.name !== 'Error' ? `${error.name}: ` : ''}${text}`.split('\n')[0].slice(0, 300);
17
+ const stack = error instanceof Error && typeof error.stack === 'string' ? error.stack : '';
18
+ const url = `${prefix}${file.replace(/ /g, '%20')}`;
19
+ const match = new RegExp(`${escapeRegExp(url)}:(\\d+):(\\d+)`).exec(stack);
20
+ if (!match)
21
+ return { file, line: null, column: null, message };
22
+ const line = Number(match[1]) - lineOffset;
23
+ return { file, line: line >= 1 ? line : null, column: Number(match[2]), message };
24
+ }
25
+ /** `file:line:column — message` (parts that are unknown are left out). */
26
+ export function formatDevError(location) {
27
+ const where = location.line ? `${location.file}:${location.line}${location.column ? `:${location.column}` : ''}` : location.file;
28
+ return `${where} — ${location.message}`;
29
+ }
30
+ //# sourceMappingURL=devErrors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"devErrors.js","sourceRoot":"","sources":["../../../runtime/src/devErrors.ts"],"names":[],"mappings":"AAAA,oGAAoG;AACpG,EAAE;AACF,kFAAkF;AAClF,gGAAgG;AAChG,oFAAoF;AAIpF,2DAA2D;AAC3D,MAAM,CAAC,MAAM,iBAAiB,GAAG,SAAS,CAAC;AAE3C,MAAM,YAAY,GAAG,CAAC,KAAa,EAAE,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,qBAAqB,EAAE,MAAM,CAAC,CAAC;AAErF;;;;GAIG;AACH,MAAM,UAAU,gBAAgB,CAAC,KAAc,EAAE,IAAY,EAAE,MAAM,GAAG,iBAAiB,EAAE,UAAU,GAAG,CAAC;IACvG,MAAM,IAAI,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IACpE,MAAM,OAAO,GAAG,GAAG,KAAK,YAAY,KAAK,IAAI,KAAK,CAAC,IAAI,IAAI,KAAK,CAAC,IAAI,KAAK,OAAO,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,EAAE,GAAG,IAAI,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAE,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;IAClJ,MAAM,KAAK,GAAG,KAAK,YAAY,KAAK,IAAI,OAAO,KAAK,CAAC,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;IAC3F,MAAM,GAAG,GAAG,GAAG,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,KAAK,CAAC,EAAE,CAAC;IACpD,MAAM,KAAK,GAAG,IAAI,MAAM,CAAC,GAAG,YAAY,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAC3E,IAAI,CAAC,KAAK;QAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;IAC/D,MAAM,IAAI,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,UAAU,CAAC;IAC3C,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC;AACpF,CAAC;AAED,0EAA0E;AAC1E,MAAM,UAAU,cAAc,CAAC,QAA0B;IACvD,MAAM,KAAK,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,QAAQ,CAAC,IAAI,IAAI,QAAQ,CAAC,IAAI,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC;IACjI,OAAO,GAAG,KAAK,MAAM,QAAQ,CAAC,OAAO,EAAE,CAAC;AAC1C,CAAC","sourcesContent":["// Live-reload developer mode: where a plugin's start failure happened, for the in-page error toast.\n//\n// The host evaluates a plugin with `//# sourceURL=<prefix><file>` (waybetter-host\n// `dev_start_script`), so V8/JavaScriptCore stack frames name that URL with the line and column\n// of the evaluated script; the plugin file's line 1 is line `1 + lineOffset` there.\n\nexport type DevErrorLocation = { file: string; line: number | null; column: number | null; message: string };\n\n/** Default prefix the host uses for plugin source URLs. */\nexport const DEV_SOURCE_PREFIX = 'wb-dev/';\n\nconst escapeRegExp = (value: string) => value.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n\n/**\n * The first stack frame inside `file` (evaluated as `<prefix><file>`), mapped back to the file's\n * own line numbers. Line is null when no frame names the file (e.g. an error thrown from a timer\n * in other code). The message is one line, at most 300 characters.\n */\nexport function devErrorLocation(error: unknown, file: string, prefix = DEV_SOURCE_PREFIX, lineOffset = 1): DevErrorLocation {\n const text = error instanceof Error ? error.message : String(error);\n const message = `${error instanceof Error && error.name && error.name !== 'Error' ? `${error.name}: ` : ''}${text}`.split('\\n')[0]!.slice(0, 300);\n const stack = error instanceof Error && typeof error.stack === 'string' ? error.stack : '';\n const url = `${prefix}${file.replace(/ /g, '%20')}`;\n const match = new RegExp(`${escapeRegExp(url)}:(\\\\d+):(\\\\d+)`).exec(stack);\n if (!match) return { file, line: null, column: null, message };\n const line = Number(match[1]) - lineOffset;\n return { file, line: line >= 1 ? line : null, column: Number(match[2]), message };\n}\n\n/** `file:line:column — message` (parts that are unknown are left out). */\nexport function formatDevError(location: DevErrorLocation): string {\n const where = location.line ? `${location.file}:${location.line}${location.column ? `:${location.column}` : ''}` : location.file;\n return `${where} — ${location.message}`;\n}\n"]}
@@ -17,6 +17,8 @@ export type DomHubConfig = {
17
17
  label: string;
18
18
  /** Pathnames where `offOnHeavy` features are skipped; null = none. */
19
19
  heavyPath: RegExp | null;
20
+ /** Selectors of hosts whose open shadow roots are part of the page (observed and searched like it). */
21
+ shadowHosts: readonly string[];
20
22
  };
21
23
  export type DomWindow = {
22
24
  document: Document;
@@ -28,7 +30,26 @@ export type DomWindow = {
28
30
  };
29
31
  /** Set once by the site adapter, before features register. */
30
32
  export declare function configureDomHub(next: Partial<DomHubConfig>): void;
33
+ /** The page's roots: the document, then the open shadow roots of the configured hosts now in it. */
34
+ export declare function domRoots(win: {
35
+ document: Document;
36
+ }): Array<Document | ShadowRoot>;
37
+ /** The site names hosts whose shadow roots are part of the page. */
38
+ export declare function hasShadowHosts(): boolean;
31
39
  export declare function isHeavyPath(pathname: string): boolean;
40
+ export type ObserveOptions = {
41
+ /** Skip on the site's heavy pages (default false). */
42
+ offOnHeavy?: boolean;
43
+ /** A callback that throws is handed here (default: the hub's console line). */
44
+ report?(error: unknown): void;
45
+ };
46
+ /**
47
+ * Calls `callback` once for every element matching `selector`, now and as the page renders more.
48
+ * Every call shares the hub's one MutationObserver and one frame: a page with a hundred selector
49
+ * observers still has one observer, and a mutation costs one frame in which each observer looks
50
+ * for elements it has not seen yet. Returns the disposer.
51
+ */
52
+ export declare function observeSelector(win: DomWindow, selector: string, callback: (element: Element) => void, options?: ObserveOptions): () => void;
32
53
  /**
33
54
  * Runs `run` in the next animation frame after body mutations of the watched kinds (child list
34
55
  * always), or whenever `schedule()` is called (scroll, popstate, input, ...). Several calls in one