waybetter 0.1.1 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (537) hide show
  1. package/README.md +139 -6
  2. package/bin/waybetter.mjs +43 -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/release.mjs +437 -0
  9. package/cli/releasecheck.mjs +15 -0
  10. package/cli/remote.mjs +260 -0
  11. package/cli/store.mjs +378 -0
  12. package/cli/strings.mjs +123 -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 +61 -0
  74. package/dist/runtime/stringPackTranslate.js +267 -0
  75. package/dist/runtime/stringPackTranslate.js.map +1 -0
  76. package/dist/runtime/stringPacks.d.ts +248 -0
  77. package/dist/runtime/stringPacks.js +610 -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/themeBar.d.ts +28 -0
  89. package/dist/runtime/themeBar.js +82 -0
  90. package/dist/runtime/themeBar.js.map +1 -0
  91. package/dist/runtime/themeChoice.d.ts +52 -0
  92. package/dist/runtime/themeChoice.js +69 -0
  93. package/dist/runtime/themeChoice.js.map +1 -0
  94. package/dist/runtime/themeComponents.d.ts +435 -0
  95. package/dist/runtime/themeComponents.js +476 -0
  96. package/dist/runtime/themeComponents.js.map +1 -0
  97. package/dist/runtime/themeDecor.d.ts +73 -0
  98. package/dist/runtime/themeDecor.js +133 -0
  99. package/dist/runtime/themeDecor.js.map +1 -0
  100. package/dist/runtime/themeDerive.d.ts +69 -0
  101. package/dist/runtime/themeDerive.js +117 -0
  102. package/dist/runtime/themeDerive.js.map +1 -0
  103. package/dist/runtime/themeDoctor.d.ts +52 -0
  104. package/dist/runtime/themeDoctor.js +112 -0
  105. package/dist/runtime/themeDoctor.js.map +1 -0
  106. package/dist/runtime/themeGuards.d.ts +60 -0
  107. package/dist/runtime/themeGuards.js +235 -0
  108. package/dist/runtime/themeGuards.js.map +1 -0
  109. package/dist/runtime/themeIcons.d.ts +130 -0
  110. package/dist/runtime/themeIcons.js +271 -0
  111. package/dist/runtime/themeIcons.js.map +1 -0
  112. package/dist/runtime/themeInk.d.ts +37 -0
  113. package/dist/runtime/themeInk.js +111 -0
  114. package/dist/runtime/themeInk.js.map +1 -0
  115. package/dist/runtime/themeInvariants.d.ts +39 -0
  116. package/dist/runtime/themeInvariants.js +273 -0
  117. package/dist/runtime/themeInvariants.js.map +1 -0
  118. package/dist/runtime/themeRuntime.d.ts +114 -0
  119. package/dist/runtime/themeRuntime.js +570 -0
  120. package/dist/runtime/themeRuntime.js.map +1 -0
  121. package/dist/runtime/themeSchema.d.ts +10 -0
  122. package/dist/runtime/themeSchema.js +150 -0
  123. package/dist/runtime/themeSchema.js.map +1 -0
  124. package/dist/runtime/themeSpec.d.ts +263 -0
  125. package/dist/runtime/themeSpec.js +435 -0
  126. package/dist/runtime/themeSpec.js.map +1 -0
  127. package/dist/runtime/themeTokens.d.ts +12 -0
  128. package/dist/runtime/themeTokens.js +14 -6
  129. package/dist/runtime/themeTokens.js.map +1 -1
  130. package/dist/runtime/themeVariants.d.ts +30 -0
  131. package/dist/runtime/themeVariants.js +53 -0
  132. package/dist/runtime/themeVariants.js.map +1 -0
  133. package/dist/runtime/ui.d.ts +192 -0
  134. package/dist/runtime/ui.js +926 -0
  135. package/dist/runtime/ui.js.map +1 -0
  136. package/dist/shell/InstallDialog.d.ts +40 -0
  137. package/dist/shell/InstallDialog.js +176 -0
  138. package/dist/shell/InstallDialog.js.map +1 -0
  139. package/dist/shell/StoreView.d.ts +78 -0
  140. package/dist/shell/StoreView.js +108 -0
  141. package/dist/shell/StoreView.js.map +1 -0
  142. package/dist/shell/addressModel.js.map +1 -1
  143. package/dist/shell/chrome.js.map +1 -1
  144. package/dist/shell/deckModel.d.ts +117 -0
  145. package/dist/shell/deckModel.js +267 -0
  146. package/dist/shell/deckModel.js.map +1 -0
  147. package/dist/shell/frame/AccountSwitcher.d.ts +42 -0
  148. package/dist/shell/frame/AccountSwitcher.js +243 -0
  149. package/dist/shell/frame/AccountSwitcher.js.map +1 -0
  150. package/dist/shell/frame/AddColumnDialog.d.ts +8 -0
  151. package/dist/shell/frame/AddColumnDialog.js +81 -0
  152. package/dist/shell/frame/AddColumnDialog.js.map +1 -0
  153. package/dist/shell/frame/AppMenu.d.ts +44 -0
  154. package/dist/shell/frame/AppMenu.js +721 -0
  155. package/dist/shell/frame/AppMenu.js.map +1 -0
  156. package/dist/shell/frame/CommandPalette.d.ts +7 -0
  157. package/dist/shell/frame/CommandPalette.js +118 -0
  158. package/dist/shell/frame/CommandPalette.js.map +1 -0
  159. package/dist/shell/frame/DeckView.d.ts +13 -0
  160. package/dist/shell/frame/DeckView.js +287 -0
  161. package/dist/shell/frame/DeckView.js.map +1 -0
  162. package/dist/shell/frame/FindBar.d.ts +10 -0
  163. package/dist/shell/frame/FindBar.js +108 -0
  164. package/dist/shell/frame/FindBar.js.map +1 -0
  165. package/dist/shell/frame/MediaPanel.d.ts +8 -0
  166. package/dist/shell/frame/MediaPanel.js +76 -0
  167. package/dist/shell/frame/MediaPanel.js.map +1 -0
  168. package/dist/shell/frame/NewTabPage.d.ts +9 -0
  169. package/dist/shell/frame/NewTabPage.js +71 -0
  170. package/dist/shell/frame/NewTabPage.js.map +1 -0
  171. package/dist/shell/frame/PaneTheme.d.ts +16 -0
  172. package/dist/shell/frame/PaneTheme.js +67 -0
  173. package/dist/shell/frame/PaneTheme.js.map +1 -0
  174. package/dist/shell/frame/ReportDialog.d.ts +3 -0
  175. package/dist/shell/frame/ReportDialog.js +95 -0
  176. package/dist/shell/frame/ReportDialog.js.map +1 -0
  177. package/dist/shell/frame/Shell.d.ts +9 -0
  178. package/dist/shell/frame/Shell.js +1139 -0
  179. package/dist/shell/frame/Shell.js.map +1 -0
  180. package/dist/shell/frame/Titlebar.d.ts +17 -0
  181. package/dist/shell/frame/Titlebar.js +79 -0
  182. package/dist/shell/frame/Titlebar.js.map +1 -0
  183. package/dist/shell/frame/TitlebarExtras.d.ts +4 -0
  184. package/dist/shell/frame/TitlebarExtras.js +202 -0
  185. package/dist/shell/frame/TitlebarExtras.js.map +1 -0
  186. package/dist/shell/frame/WebPanel.d.ts +4 -0
  187. package/dist/shell/frame/WebPanel.js +185 -0
  188. package/dist/shell/frame/WebPanel.js.map +1 -0
  189. package/dist/shell/frame/accountModel.d.ts +49 -0
  190. package/dist/shell/frame/accountModel.js +67 -0
  191. package/dist/shell/frame/accountModel.js.map +1 -0
  192. package/dist/shell/frame/accountSwitcher.css +91 -0
  193. package/dist/shell/frame/appI18n.d.ts +44 -0
  194. package/dist/shell/frame/appI18n.js +64 -0
  195. package/dist/shell/frame/appI18n.js.map +1 -0
  196. package/dist/shell/frame/appMenu.css +127 -0
  197. package/dist/shell/frame/backupModel.d.ts +38 -0
  198. package/dist/shell/frame/backupModel.js +192 -0
  199. package/dist/shell/frame/backupModel.js.map +1 -0
  200. package/dist/shell/frame/boot.d.ts +8 -0
  201. package/dist/shell/frame/boot.js +37 -0
  202. package/dist/shell/frame/boot.js.map +1 -0
  203. package/dist/shell/frame/brand.d.ts +1 -0
  204. package/dist/shell/frame/brand.js +4 -0
  205. package/dist/shell/frame/brand.js.map +1 -0
  206. package/dist/shell/frame/bridge.d.ts +35 -0
  207. package/dist/shell/frame/bridge.js +70 -0
  208. package/dist/shell/frame/bridge.js.map +1 -0
  209. package/dist/shell/frame/chromeTheme.d.ts +47 -0
  210. package/dist/shell/frame/chromeTheme.js +118 -0
  211. package/dist/shell/frame/chromeTheme.js.map +1 -0
  212. package/dist/shell/frame/deck.css +209 -0
  213. package/dist/shell/frame/deckStore.d.ts +89 -0
  214. package/dist/shell/frame/deckStore.js +239 -0
  215. package/dist/shell/frame/deckStore.js.map +1 -0
  216. package/dist/shell/frame/devHost.d.ts +35 -0
  217. package/dist/shell/frame/devHost.js +80 -0
  218. package/dist/shell/frame/devHost.js.map +1 -0
  219. package/dist/shell/frame/devModel.d.ts +7 -0
  220. package/dist/shell/frame/devModel.js +17 -0
  221. package/dist/shell/frame/devModel.js.map +1 -0
  222. package/dist/shell/frame/diag.d.ts +7 -0
  223. package/dist/shell/frame/diag.js +39 -0
  224. package/dist/shell/frame/diag.js.map +1 -0
  225. package/dist/shell/frame/edges.css +159 -0
  226. package/dist/shell/frame/findBar.css +14 -0
  227. package/dist/shell/frame/frameMessages.d.ts +248 -0
  228. package/dist/shell/frame/frameMessages.js +252 -0
  229. package/dist/shell/frame/frameMessages.js.map +1 -0
  230. package/dist/shell/frame/hooks.d.ts +39 -0
  231. package/dist/shell/frame/hooks.js +97 -0
  232. package/dist/shell/frame/hooks.js.map +1 -0
  233. package/dist/shell/frame/i18n.d.ts +27 -0
  234. package/dist/shell/frame/i18n.js +66 -0
  235. package/dist/shell/frame/i18n.js.map +1 -0
  236. package/dist/shell/frame/iconPack.d.ts +11 -0
  237. package/dist/shell/frame/iconPack.js +45 -0
  238. package/dist/shell/frame/iconPack.js.map +1 -0
  239. package/dist/shell/frame/icons.d.ts +71 -0
  240. package/dist/shell/frame/icons.js +75 -0
  241. package/dist/shell/frame/icons.js.map +1 -0
  242. package/dist/shell/frame/index.d.ts +34 -0
  243. package/dist/shell/frame/index.js +43 -0
  244. package/dist/shell/frame/index.js.map +1 -0
  245. package/dist/shell/frame/language.d.ts +58 -0
  246. package/dist/shell/frame/language.js +165 -0
  247. package/dist/shell/frame/language.js.map +1 -0
  248. package/dist/shell/frame/mediaModel.d.ts +47 -0
  249. package/dist/shell/frame/mediaModel.js +67 -0
  250. package/dist/shell/frame/mediaModel.js.map +1 -0
  251. package/dist/shell/frame/menuMessages.en.json +96 -0
  252. package/dist/shell/frame/menuModel.d.ts +319 -0
  253. package/dist/shell/frame/menuModel.js +301 -0
  254. package/dist/shell/frame/menuModel.js.map +1 -0
  255. package/dist/shell/frame/nativeMenu.d.ts +5 -0
  256. package/dist/shell/frame/nativeMenu.js +178 -0
  257. package/dist/shell/frame/nativeMenu.js.map +1 -0
  258. package/dist/shell/frame/nativeMenuModel.d.ts +102 -0
  259. package/dist/shell/frame/nativeMenuModel.js +186 -0
  260. package/dist/shell/frame/nativeMenuModel.js.map +1 -0
  261. package/dist/shell/frame/paletteModel.d.ts +139 -0
  262. package/dist/shell/frame/paletteModel.js +114 -0
  263. package/dist/shell/frame/paletteModel.js.map +1 -0
  264. package/dist/shell/frame/paneTheme.css +9 -0
  265. package/dist/shell/frame/pluginCommandStore.d.ts +23 -0
  266. package/dist/shell/frame/pluginCommandStore.js +70 -0
  267. package/dist/shell/frame/pluginCommandStore.js.map +1 -0
  268. package/dist/shell/frame/reportModel.d.ts +52 -0
  269. package/dist/shell/frame/reportModel.js +105 -0
  270. package/dist/shell/frame/reportModel.js.map +1 -0
  271. package/dist/shell/frame/safeStore.d.ts +7 -0
  272. package/dist/shell/frame/safeStore.js +40 -0
  273. package/dist/shell/frame/safeStore.js.map +1 -0
  274. package/dist/shell/frame/searchInput.d.ts +2 -0
  275. package/dist/shell/frame/searchInput.js +11 -0
  276. package/dist/shell/frame/searchInput.js.map +1 -0
  277. package/dist/shell/frame/shell.css +634 -0
  278. package/dist/shell/frame/site.d.ts +206 -0
  279. package/dist/shell/frame/site.js +22 -0
  280. package/dist/shell/frame/site.js.map +1 -0
  281. package/dist/shell/frame/state.d.ts +101 -0
  282. package/dist/shell/frame/state.js +286 -0
  283. package/dist/shell/frame/state.js.map +1 -0
  284. package/dist/shell/frame/syncGate.d.ts +10 -0
  285. package/dist/shell/frame/syncGate.js +36 -0
  286. package/dist/shell/frame/syncGate.js.map +1 -0
  287. package/dist/shell/frame/syncHost.d.ts +35 -0
  288. package/dist/shell/frame/syncHost.js +85 -0
  289. package/dist/shell/frame/syncHost.js.map +1 -0
  290. package/dist/shell/frame/tabStill.d.ts +2 -0
  291. package/dist/shell/frame/tabStill.js +62 -0
  292. package/dist/shell/frame/tabStill.js.map +1 -0
  293. package/dist/shell/frame/themeScopes.d.ts +29 -0
  294. package/dist/shell/frame/themeScopes.js +61 -0
  295. package/dist/shell/frame/themeScopes.js.map +1 -0
  296. package/dist/shell/frame/themeStore.d.ts +99 -0
  297. package/dist/shell/frame/themeStore.js +267 -0
  298. package/dist/shell/frame/themeStore.js.map +1 -0
  299. package/dist/shell/frame/windowBinding.d.ts +2 -0
  300. package/dist/shell/frame/windowBinding.js +7 -0
  301. package/dist/shell/frame/windowBinding.js.map +1 -0
  302. package/dist/shell/frame/workspaceModel.d.ts +82 -0
  303. package/dist/shell/frame/workspaceModel.js +250 -0
  304. package/dist/shell/frame/workspaceModel.js.map +1 -0
  305. package/dist/shell/frame/workspaces.css +84 -0
  306. package/dist/shell/frame/workspaces.d.ts +22 -0
  307. package/dist/shell/frame/workspaces.js +125 -0
  308. package/dist/shell/frame/workspaces.js.map +1 -0
  309. package/dist/shell/frame/zoomStore.d.ts +10 -0
  310. package/dist/shell/frame/zoomStore.js +65 -0
  311. package/dist/shell/frame/zoomStore.js.map +1 -0
  312. package/dist/shell/installController.d.ts +137 -0
  313. package/dist/shell/installController.js +172 -0
  314. package/dist/shell/installController.js.map +1 -0
  315. package/dist/shell/installerMessages.d.ts +30 -0
  316. package/dist/shell/installerMessages.js +36 -0
  317. package/dist/shell/installerMessages.js.map +1 -0
  318. package/dist/shell/linkDrop.js.map +1 -1
  319. package/dist/shell/messages.d.ts +16 -0
  320. package/dist/shell/messages.js +27 -0
  321. package/dist/shell/messages.js.map +1 -0
  322. package/dist/shell/palette.js.map +1 -1
  323. package/dist/shell/paneModel.d.ts +22 -0
  324. package/dist/shell/paneModel.js +24 -1
  325. package/dist/shell/paneModel.js.map +1 -1
  326. package/dist/shell/panel/Appearance.d.ts +8 -0
  327. package/dist/shell/panel/Appearance.js +265 -0
  328. package/dist/shell/panel/Appearance.js.map +1 -0
  329. package/dist/shell/panel/BackupPanel.d.ts +5 -0
  330. package/dist/shell/panel/BackupPanel.js +198 -0
  331. package/dist/shell/panel/BackupPanel.js.map +1 -0
  332. package/dist/shell/panel/DeveloperPanel.d.ts +4 -0
  333. package/dist/shell/panel/DeveloperPanel.js +51 -0
  334. package/dist/shell/panel/DeveloperPanel.js.map +1 -0
  335. package/dist/shell/panel/FeatureToggles.d.ts +13 -0
  336. package/dist/shell/panel/FeatureToggles.js +42 -0
  337. package/dist/shell/panel/FeatureToggles.js.map +1 -0
  338. package/dist/shell/panel/Home.d.ts +3 -0
  339. package/dist/shell/panel/Home.js +23 -0
  340. package/dist/shell/panel/Home.js.map +1 -0
  341. package/dist/shell/panel/IconPackInstall.d.ts +15 -0
  342. package/dist/shell/panel/IconPackInstall.js +41 -0
  343. package/dist/shell/panel/IconPackInstall.js.map +1 -0
  344. package/dist/shell/panel/LanguageSettings.d.ts +1 -0
  345. package/dist/shell/panel/LanguageSettings.js +54 -0
  346. package/dist/shell/panel/LanguageSettings.js.map +1 -0
  347. package/dist/shell/panel/MakePanel.d.ts +3 -0
  348. package/dist/shell/panel/MakePanel.js +237 -0
  349. package/dist/shell/panel/MakePanel.js.map +1 -0
  350. package/dist/shell/panel/MarkdownDoc.d.ts +6 -0
  351. package/dist/shell/panel/MarkdownDoc.js +35 -0
  352. package/dist/shell/panel/MarkdownDoc.js.map +1 -0
  353. package/dist/shell/panel/Modes.d.ts +40 -0
  354. package/dist/shell/panel/Modes.js +270 -0
  355. package/dist/shell/panel/Modes.js.map +1 -0
  356. package/dist/shell/panel/NavIcon.d.ts +4 -0
  357. package/dist/shell/panel/NavIcon.js +6 -0
  358. package/dist/shell/panel/NavIcon.js.map +1 -0
  359. package/dist/shell/panel/Panel.d.ts +7 -0
  360. package/dist/shell/panel/Panel.js +139 -0
  361. package/dist/shell/panel/Panel.js.map +1 -0
  362. package/dist/shell/panel/PluginFeatures.d.ts +24 -0
  363. package/dist/shell/panel/PluginFeatures.js +165 -0
  364. package/dist/shell/panel/PluginFeatures.js.map +1 -0
  365. package/dist/shell/panel/Plugins.d.ts +33 -0
  366. package/dist/shell/panel/Plugins.js +112 -0
  367. package/dist/shell/panel/Plugins.js.map +1 -0
  368. package/dist/shell/panel/PowerSettings.d.ts +4 -0
  369. package/dist/shell/panel/PowerSettings.js +52 -0
  370. package/dist/shell/panel/PowerSettings.js.map +1 -0
  371. package/dist/shell/panel/Settings.d.ts +23 -0
  372. package/dist/shell/panel/Settings.js +117 -0
  373. package/dist/shell/panel/Settings.js.map +1 -0
  374. package/dist/shell/panel/ShareSetup.d.ts +8 -0
  375. package/dist/shell/panel/ShareSetup.js +130 -0
  376. package/dist/shell/panel/ShareSetup.js.map +1 -0
  377. package/dist/shell/panel/StoreSection.d.ts +7 -0
  378. package/dist/shell/panel/StoreSection.js +78 -0
  379. package/dist/shell/panel/StoreSection.js.map +1 -0
  380. package/dist/shell/panel/StringPacks.d.ts +20 -0
  381. package/dist/shell/panel/StringPacks.js +131 -0
  382. package/dist/shell/panel/StringPacks.js.map +1 -0
  383. package/dist/shell/panel/ThemeBuilder.d.ts +5 -0
  384. package/dist/shell/panel/ThemeBuilder.js +205 -0
  385. package/dist/shell/panel/ThemeBuilder.js.map +1 -0
  386. package/dist/shell/panel/backup.css +34 -0
  387. package/dist/shell/panel/builder.css +240 -0
  388. package/dist/shell/panel/builderModel.d.ts +55 -0
  389. package/dist/shell/panel/builderModel.js +95 -0
  390. package/dist/shell/panel/builderModel.js.map +1 -0
  391. package/dist/shell/panel/compare.d.ts +10 -0
  392. package/dist/shell/panel/compare.js +51 -0
  393. package/dist/shell/panel/compare.js.map +1 -0
  394. package/dist/shell/panel/controls.d.ts +135 -0
  395. package/dist/shell/panel/controls.js +213 -0
  396. package/dist/shell/panel/controls.js.map +1 -0
  397. package/dist/shell/panel/featureModel.d.ts +69 -0
  398. package/dist/shell/panel/featureModel.js +79 -0
  399. package/dist/shell/panel/featureModel.js.map +1 -0
  400. package/dist/shell/panel/fonts/FontBrowser.d.ts +10 -0
  401. package/dist/shell/panel/fonts/FontBrowser.js +189 -0
  402. package/dist/shell/panel/fonts/FontBrowser.js.map +1 -0
  403. package/dist/shell/panel/fonts/FontRoles.d.ts +20 -0
  404. package/dist/shell/panel/fonts/FontRoles.js +77 -0
  405. package/dist/shell/panel/fonts/FontRoles.js.map +1 -0
  406. package/dist/shell/panel/fonts/catalog.d.ts +37 -0
  407. package/dist/shell/panel/fonts/catalog.js +68 -0
  408. package/dist/shell/panel/fonts/catalog.js.map +1 -0
  409. package/dist/shell/panel/fonts/googleFontsCatalog.json +1 -0
  410. package/dist/shell/panel/index.d.ts +20 -0
  411. package/dist/shell/panel/index.js +34 -0
  412. package/dist/shell/panel/index.js.map +1 -0
  413. package/dist/shell/panel/languageModel.d.ts +5 -0
  414. package/dist/shell/panel/languageModel.js +7 -0
  415. package/dist/shell/panel/languageModel.js.map +1 -0
  416. package/dist/shell/panel/make.css +73 -0
  417. package/dist/shell/panel/makeModel.d.ts +32 -0
  418. package/dist/shell/panel/makeModel.js +84 -0
  419. package/dist/shell/panel/makeModel.js.map +1 -0
  420. package/dist/shell/panel/markdown.d.ts +46 -0
  421. package/dist/shell/panel/markdown.js +100 -0
  422. package/dist/shell/panel/markdown.js.map +1 -0
  423. package/dist/shell/panel/nav.d.ts +12 -0
  424. package/dist/shell/panel/nav.js +50 -0
  425. package/dist/shell/panel/nav.js.map +1 -0
  426. package/dist/shell/panel/panel.css +401 -0
  427. package/dist/shell/panel/panelMessages.d.ts +803 -0
  428. package/dist/shell/panel/panelMessages.js +779 -0
  429. package/dist/shell/panel/panelMessages.js.map +1 -0
  430. package/dist/shell/panel/plugins.css +59 -0
  431. package/dist/shell/panel/setupModel.d.ts +87 -0
  432. package/dist/shell/panel/setupModel.js +152 -0
  433. package/dist/shell/panel/setupModel.js.map +1 -0
  434. package/dist/shell/panel/site.d.ts +259 -0
  435. package/dist/shell/panel/site.js +25 -0
  436. package/dist/shell/panel/site.js.map +1 -0
  437. package/dist/shell/panel/strings.css +7 -0
  438. package/dist/shell/panel/themes.d.ts +10 -0
  439. package/dist/shell/panel/themes.js +8 -0
  440. package/dist/shell/panel/themes.js.map +1 -0
  441. package/dist/shell/profileModel.d.ts +3 -2
  442. package/dist/shell/profileModel.js +7 -5
  443. package/dist/shell/profileModel.js.map +1 -1
  444. package/dist/shell/store.css +250 -0
  445. package/dist/shell/storeMessages.d.ts +193 -0
  446. package/dist/shell/storeMessages.js +196 -0
  447. package/dist/shell/storeMessages.js.map +1 -0
  448. package/dist/shell/storeModel.d.ts +205 -0
  449. package/dist/shell/storeModel.js +146 -0
  450. package/dist/shell/storeModel.js.map +1 -0
  451. package/dist/shell/stringPacksModel.d.ts +44 -0
  452. package/dist/shell/stringPacksModel.js +99 -0
  453. package/dist/shell/stringPacksModel.js.map +1 -0
  454. package/dist/shell/updateModel.d.ts +2 -1
  455. package/dist/shell/updateModel.js +5 -4
  456. package/dist/shell/updateModel.js.map +1 -1
  457. package/dist/shell/windowControls.d.ts +4 -0
  458. package/dist/shell/windowControls.js +5 -0
  459. package/dist/shell/windowControls.js.map +1 -1
  460. package/i18n-config.schema.json +29 -0
  461. package/i18n-meta.schema.json +26 -0
  462. package/i18n.schema.json +42 -0
  463. package/icons.schema.json +655 -0
  464. package/languages.schema.json +23 -0
  465. package/locales/ar-x-fm.json +11 -0
  466. package/locales/ar.json +1388 -0
  467. package/locales/bg.json +1387 -0
  468. package/locales/bn.json +1387 -0
  469. package/locales/ca.json +1387 -0
  470. package/locales/cs.json +1387 -0
  471. package/locales/da.json +1387 -0
  472. package/locales/de.json +1387 -0
  473. package/locales/el.json +1387 -0
  474. package/locales/en-GB.json +27 -0
  475. package/locales/en.json +1386 -0
  476. package/locales/en.meta.json +51 -0
  477. package/locales/es.json +1387 -0
  478. package/locales/eu.json +1387 -0
  479. package/locales/fa.json +1388 -0
  480. package/locales/fi.json +1387 -0
  481. package/locales/fil.json +1387 -0
  482. package/locales/fr.json +1387 -0
  483. package/locales/ga.json +1387 -0
  484. package/locales/gl.json +1387 -0
  485. package/locales/gu.json +1387 -0
  486. package/locales/ha.json +1387 -0
  487. package/locales/he.json +1388 -0
  488. package/locales/hi.json +1387 -0
  489. package/locales/hr.json +1387 -0
  490. package/locales/hu.json +1387 -0
  491. package/locales/id.json +1387 -0
  492. package/locales/ig.json +1387 -0
  493. package/locales/it.json +1387 -0
  494. package/locales/ja.json +1387 -0
  495. package/locales/kn.json +1387 -0
  496. package/locales/ko.json +1387 -0
  497. package/locales/mr.json +1387 -0
  498. package/locales/ms.json +1387 -0
  499. package/locales/nb.json +1387 -0
  500. package/locales/nl.json +1387 -0
  501. package/locales/pl.json +1387 -0
  502. package/locales/pt.json +1387 -0
  503. package/locales/ro.json +1387 -0
  504. package/locales/ru.json +1387 -0
  505. package/locales/sk.json +1387 -0
  506. package/locales/sr.json +1387 -0
  507. package/locales/sv.json +1387 -0
  508. package/locales/ta.json +1387 -0
  509. package/locales/th.json +1387 -0
  510. package/locales/tr.json +1387 -0
  511. package/locales/uk.json +1387 -0
  512. package/locales/ur.json +1388 -0
  513. package/locales/vi.json +1387 -0
  514. package/locales/yo.json +1387 -0
  515. package/locales/zh-Hans.json +1387 -0
  516. package/locales/zh-Hant.json +1387 -0
  517. package/package.json +138 -5
  518. package/store-catalog.schema.json +78 -0
  519. package/theme.schema.json +4668 -0
  520. package/windows/installer.nsi +946 -0
  521. package/windows/languages/Basque.nsh +28 -0
  522. package/windows/languages/Catalan.nsh +28 -0
  523. package/windows/languages/Croatian.nsh +28 -0
  524. package/windows/languages/Czech.nsh +28 -0
  525. package/windows/languages/Danish.nsh +28 -0
  526. package/windows/languages/Finnish.nsh +28 -0
  527. package/windows/languages/Galician.nsh +28 -0
  528. package/windows/languages/Greek.nsh +28 -0
  529. package/windows/languages/Hungarian.nsh +28 -0
  530. package/windows/languages/Indonesian.nsh +28 -0
  531. package/windows/languages/Irish.nsh +28 -0
  532. package/windows/languages/Malay.nsh +28 -0
  533. package/windows/languages/Polish.nsh +28 -0
  534. package/windows/languages/Romanian.nsh +28 -0
  535. package/windows/languages/Serbian.nsh +28 -0
  536. package/windows/languages/Slovak.nsh +28 -0
  537. package/windows/languages/Thai.nsh +28 -0
@@ -0,0 +1,570 @@
1
+ // The theme engine in a site's page: keeps one `<style>` with the theme's CSS in sync while the site
2
+ // adds its own rules (React apps insert them lazily), exposes the resolved theme as `--wb-*` custom
3
+ // properties for plugins and the UI kit, follows the site's own color mode, and paints the last
4
+ // theme from the page's first frame (a snapshot in the page's storage). What the CSS is comes from
5
+ // the site adapter (`ThemeRuntimeSite`): X re-declares its own stylesheet rules with the theme's
6
+ // colors (`buildThemeCss`) and adds type/shape/layout rules over its selectors.
7
+ import { domRoots, watchDom } from "./domHub.js";
8
+ import { FONT_ROLE_NAMES, themeKey, themeVarsCss } from "./themeApi.js";
9
+ import { bundledFontsUsed, isNeutral, resolveFontRoles } from "./themeSpec.js";
10
+ /** The font roles as the plugin API reports them in a site's page; an inheriting interface uses `siteStack` (the site's own font). */
11
+ export function resolvedFonts(font, siteStack) {
12
+ const roles = resolveFontRoles(font, siteStack);
13
+ return Object.fromEntries(FONT_ROLE_NAMES.map(role => {
14
+ const { stack, weight, size, tracking, tabular, inherited } = roles[role];
15
+ return [role, { stack, weight, size, tracking, tabular, inherited }];
16
+ }));
17
+ }
18
+ const isSupports = (rule) => rule.type === 12 || rule.constructor?.name === 'CSSSupportsRule';
19
+ /**
20
+ * A style rule as it takes effect. Tailwind 4 writes an opacity utility as a fallback plus the real
21
+ * value in a nested `@supports`:
22
+ * `.bg-white\/15 { background-color: var(--white); @supports (color: color-mix(in lab, red, red)) { background-color: color-mix(in oklab, var(--white) 15%, transparent) } }`.
23
+ * Read alone, the outer declaration is a solid white fill; where the browser passes the condition the
24
+ * nested one is what paints, so it answers for the rule.
25
+ */
26
+ function effectiveRule(rule, supported) {
27
+ const overrides = [];
28
+ for (const child of Array.from(rule.cssRules ?? [])) {
29
+ if (!isSupports(child) || !supported(child.conditionText ?? ''))
30
+ continue;
31
+ for (const inner of Array.from(child.cssRules ?? [])) {
32
+ // Bare declarations inside the group: a CSSNestedDeclarations, or `& { }` in older engines.
33
+ if (inner.style && (inner.selectorText === undefined || inner.selectorText === '&'))
34
+ overrides.push(inner.style);
35
+ }
36
+ }
37
+ if (!overrides.length)
38
+ return rule;
39
+ const outer = rule.style;
40
+ return {
41
+ selectorText: rule.selectorText,
42
+ style: {
43
+ getPropertyValue(name) {
44
+ for (let i = overrides.length - 1; i >= 0; i--) {
45
+ const value = overrides[i].getPropertyValue(name);
46
+ if (value)
47
+ return value;
48
+ }
49
+ return outer.getPropertyValue(name);
50
+ },
51
+ length: outer.length,
52
+ },
53
+ };
54
+ }
55
+ /**
56
+ * Every style rule of `doc`'s stylesheets (inside media/supports groups too), except `own`'s (the
57
+ * engine's own sheets: read as the site's, their radii and colors would be re-declared), each as it
58
+ * takes effect (`effectiveRule`). A `@supports` group the browser does not pass is left out.
59
+ */
60
+ export function collectRules(doc, own) {
61
+ const ours = (Array.isArray(own) ? own : [own]).filter(Boolean);
62
+ const sheets = Array.from(doc.styleSheets).filter(sheet => !ours.includes(sheet.ownerNode));
63
+ return rulesOf(sheets, doc.defaultView?.CSS);
64
+ }
65
+ /**
66
+ * The same for an open shadow root the site renders a part of itself in (X's chat embed): its adopted
67
+ * sheets and its `<style>` elements, except the engine's own adopted `own` sheet.
68
+ */
69
+ export function collectRootRules(root, own, css) {
70
+ const sheets = [...Array.from(root.adoptedStyleSheets ?? []), ...Array.from(root.styleSheets ?? [])].filter(sheet => sheet !== own);
71
+ return rulesOf(sheets, css);
72
+ }
73
+ function rulesOf(sheets, css) {
74
+ const rules = [];
75
+ const verdicts = new Map();
76
+ const supported = (condition) => {
77
+ if (!condition || !css?.supports)
78
+ return true;
79
+ let verdict = verdicts.get(condition);
80
+ if (verdict === undefined) {
81
+ try {
82
+ verdict = css.supports(condition);
83
+ }
84
+ catch {
85
+ verdict = true;
86
+ }
87
+ verdicts.set(condition, verdict);
88
+ }
89
+ return verdict;
90
+ };
91
+ const walk = (list) => {
92
+ for (const rule of Array.from(list)) {
93
+ if (rule.selectorText !== undefined && rule.style)
94
+ rules.push(effectiveRule(rule, supported));
95
+ else if (rule.cssRules && rule.selectorText === undefined && (!isSupports(rule) || supported(rule.conditionText ?? '')))
96
+ walk(rule.cssRules);
97
+ }
98
+ };
99
+ for (const sheet of sheets) {
100
+ try {
101
+ walk(sheet.cssRules);
102
+ }
103
+ catch { /* Cross-origin sheet. */ }
104
+ }
105
+ return rules;
106
+ }
107
+ function rootRuleCount(root, own) {
108
+ let count = 0;
109
+ for (const sheet of [...Array.from(root.adoptedStyleSheets ?? []), ...Array.from(root.styleSheets ?? [])]) {
110
+ if (sheet === own)
111
+ continue;
112
+ try {
113
+ count += sheet.cssRules.length;
114
+ }
115
+ catch { /* Cross-origin. */ }
116
+ }
117
+ return count;
118
+ }
119
+ function ruleCount(doc) {
120
+ let count = 0;
121
+ for (const sheet of Array.from(doc.styleSheets)) {
122
+ try {
123
+ count += sheet.cssRules.length;
124
+ }
125
+ catch { /* Cross-origin. */ }
126
+ }
127
+ return count;
128
+ }
129
+ const SNAPSHOT_KEY = 'wb:theme-snapshot';
130
+ export const SNAPSHOT_SESSION_MAX = 1_000_000;
131
+ export const SNAPSHOT_LOCAL_MAX = 200_000;
132
+ function stores(win) {
133
+ const get = (name) => { try {
134
+ return win[name];
135
+ }
136
+ catch {
137
+ return null;
138
+ } };
139
+ return { session: get('sessionStorage'), local: get('localStorage') };
140
+ }
141
+ export function readSnapshot({ session, local }) {
142
+ for (const store of [session, local]) {
143
+ try {
144
+ const value = JSON.parse(store?.getItem(SNAPSHOT_KEY) || 'null');
145
+ if (value && typeof value.key === 'string' && typeof value.css === 'string' && value.css && value.choice)
146
+ return value;
147
+ }
148
+ catch { /* Missing, blocked or foreign data: no snapshot. */ }
149
+ }
150
+ return null;
151
+ }
152
+ /** Stores `snapshot` (null clears it: the site's own look needs none), each store within its cap. */
153
+ export function writeSnapshot({ session, local }, snapshot) {
154
+ const json = snapshot ? JSON.stringify(snapshot) : '';
155
+ for (const [store, max] of [[session, SNAPSHOT_SESSION_MAX], [local, SNAPSHOT_LOCAL_MAX]]) {
156
+ try {
157
+ if (json && json.length <= max)
158
+ store?.setItem(SNAPSHOT_KEY, json);
159
+ else
160
+ store?.removeItem(SNAPSHOT_KEY);
161
+ }
162
+ catch { /* Quota or blocked storage: the next document just starts unthemed. */ }
163
+ }
164
+ }
165
+ /** The attribute a page flag sets on `<html>`. */
166
+ export const flagAttribute = (name) => `data-wb-${name}`;
167
+ /** Which of `flags` hold in `roots` now (pure, for tests). */
168
+ export function pageFlags(roots, flags) {
169
+ const on = [];
170
+ for (const [name, selector] of Object.entries(flags)) {
171
+ try {
172
+ if (roots.some(root => !!root.querySelector(selector)))
173
+ on.push(name);
174
+ }
175
+ catch { /* A bad selector is never on. */ }
176
+ }
177
+ return on;
178
+ }
179
+ const VARS_ID = 'wb-theme-vars';
180
+ /** Keeps the site's page in the owner's theme (see the top of this file). */
181
+ export function installThemeRuntime(win, site, options = {}) {
182
+ const doc = win.document;
183
+ const name = site.name ?? 'wayBetter';
184
+ const styleId = site.styleId ?? 'wb-theme-css';
185
+ const staticId = site.staticId ?? 'wb-theme-static';
186
+ const { catalog } = site;
187
+ // Document start (no <html> yet): the snapshot as an adopted sheet paints with the site's first
188
+ // frame. It stays while the live CSS is for the same theme and site mode, and goes when they differ.
189
+ const storage = stores(win);
190
+ const snapshot = readSnapshot(storage);
191
+ let early = null;
192
+ if (snapshot) {
193
+ try {
194
+ const Sheet = win.CSSStyleSheet;
195
+ early = new Sheet();
196
+ early.replaceSync(snapshot.css);
197
+ doc.adoptedStyleSheets = [...doc.adoptedStyleSheets, early];
198
+ }
199
+ catch {
200
+ early = null;
201
+ }
202
+ }
203
+ const dropEarly = () => {
204
+ if (!early)
205
+ return;
206
+ const sheet = early;
207
+ early = null;
208
+ try {
209
+ doc.adoptedStyleSheets = doc.adoptedStyleSheets.filter(item => item !== sheet);
210
+ }
211
+ catch { /* Never break the site. */ }
212
+ };
213
+ let savedCss = snapshot?.css ?? '';
214
+ let choice = catalog.defaultChoice;
215
+ let theme = catalog.resolve(choice);
216
+ let lastKey = '';
217
+ let timer = null;
218
+ const active = () => !isNeutral(theme) || !!choice.accent || !!choice.icons;
219
+ let mode = site.initialMode;
220
+ let resolved = site.resolved(choice, mode);
221
+ let resolvedKey = themeKey(resolved);
222
+ const listeners = new Set();
223
+ const readMode = () => (doc.body ? site.readMode(win) : mode);
224
+ /** `--wb-*` on :root for plugin CSS, and a change notice when anything visible changed. */
225
+ const syncResolved = () => {
226
+ if (doc.body)
227
+ mode = readMode();
228
+ resolved = site.resolved(choice, mode);
229
+ const key = themeKey(resolved);
230
+ let vars = doc.getElementById(VARS_ID);
231
+ if (!vars?.isConnected) {
232
+ vars = doc.createElement('style');
233
+ vars.id = VARS_ID;
234
+ (doc.head || doc.documentElement).appendChild(vars);
235
+ }
236
+ const css = themeVarsCss(resolved);
237
+ if (vars.textContent !== css)
238
+ vars.textContent = css;
239
+ if (key === resolvedKey)
240
+ return;
241
+ resolvedKey = key;
242
+ for (const listener of [...listeners]) {
243
+ try {
244
+ listener();
245
+ }
246
+ catch (error) {
247
+ console.error(`[${name}] theme listener failed`, error);
248
+ }
249
+ }
250
+ };
251
+ let modeObserver = null;
252
+ const watchMode = () => {
253
+ if (modeObserver || !doc.body)
254
+ return;
255
+ // Sites repaint the body when their own display setting changes (X: Default / Dim / Lights out).
256
+ const Observer = win.MutationObserver ?? globalThis.MutationObserver;
257
+ if (!Observer)
258
+ return;
259
+ modeObserver = new Observer(() => { try {
260
+ if (readMode() !== mode)
261
+ syncResolved();
262
+ }
263
+ catch { /* Never break the site. */ } });
264
+ modeObserver.observe(doc.body, { attributes: true, attributeFilter: ['style'] });
265
+ };
266
+ let staticKey = '';
267
+ let staticText = '';
268
+ let siteVars = {};
269
+ // Page flags (`site.flags`): checked once per hub frame after the page changed, on every page (heavy ones too).
270
+ const flagNames = Object.keys(site.flags ?? {});
271
+ let flagWatch = null;
272
+ // The flags that hold now; the theme's CSS is rebuilt when they change (a rule that only applies to a
273
+ // signed-out page can then be left out of a signed-in one instead of being gated by `:has()`).
274
+ let flagState = [];
275
+ const syncFlags = () => {
276
+ const root = doc.documentElement;
277
+ if (!root || !flagNames.length)
278
+ return;
279
+ let on = [];
280
+ try {
281
+ on = pageFlags(domRoots(win), site.flags);
282
+ }
283
+ catch {
284
+ on = [];
285
+ }
286
+ for (const name of flagNames) {
287
+ const attr = flagAttribute(name);
288
+ const want = on.includes(name);
289
+ if (root.hasAttribute(attr) !== want) {
290
+ if (want)
291
+ root.setAttribute(attr, '');
292
+ else
293
+ root.removeAttribute(attr);
294
+ }
295
+ }
296
+ const changed = on.join(' ') !== flagState.join(' ');
297
+ flagState = on;
298
+ return changed;
299
+ };
300
+ const flagsOn = (on) => {
301
+ if (!flagNames.length)
302
+ return;
303
+ if (on) {
304
+ syncFlags();
305
+ if (!flagWatch) {
306
+ try {
307
+ flagWatch = watchDom(win, () => { if (syncFlags()) {
308
+ try {
309
+ render();
310
+ }
311
+ catch { /* Never break the site. */ }
312
+ } }, { offOnHeavy: false });
313
+ }
314
+ catch {
315
+ flagWatch = null;
316
+ }
317
+ }
318
+ }
319
+ else {
320
+ flagWatch?.dispose();
321
+ flagWatch = null;
322
+ for (const name of flagNames)
323
+ doc.documentElement?.removeAttribute(flagAttribute(name));
324
+ }
325
+ };
326
+ // Open shadow roots the site renders a part of itself in (domHub `shadowHosts`; X's chat embed since
327
+ // 2026-10-01): the document's sheets do not reach inside, so each root adopts the theme built from
328
+ // its own rules plus the static sheet, kept last among its sheets, rebuilt when its rules change and
329
+ // taken off when the theme is off or the root is gone.
330
+ const rootSheets = new Map();
331
+ const detach = (root, sheet) => { try {
332
+ root.adoptedStyleSheets = root.adoptedStyleSheets.filter(item => item !== sheet);
333
+ }
334
+ catch { /* Root gone. */ } };
335
+ const syncRoots = (on, snapshotKey, force) => {
336
+ let roots = [];
337
+ if (on) {
338
+ try {
339
+ roots = domRoots(win).slice(1);
340
+ }
341
+ catch {
342
+ roots = [];
343
+ }
344
+ }
345
+ for (const [root, item] of rootSheets)
346
+ if (!roots.includes(root)) {
347
+ detach(root, item.sheet);
348
+ rootSheets.delete(root);
349
+ }
350
+ const Sheet = win.CSSStyleSheet;
351
+ for (const root of roots) {
352
+ let item = rootSheets.get(root);
353
+ if (!item) {
354
+ try {
355
+ item = { sheet: new Sheet(), key: '' };
356
+ }
357
+ catch {
358
+ continue;
359
+ }
360
+ rootSheets.set(root, item);
361
+ }
362
+ const key = `${snapshotKey}|${flagState.join(' ')}|${rootRuleCount(root, item.sheet)}|${staticText.length}`;
363
+ if (force || item.key !== key) {
364
+ item.key = key;
365
+ // The site's primitives as the root sees them (its own sheets may declare them; the document may not), read with our sheet off.
366
+ const vars = { ...siteVars };
367
+ if (site.siteVars?.length) {
368
+ const probe = root.firstElementChild ?? root.host;
369
+ item.sheet.disabled = true;
370
+ try {
371
+ const style = win.getComputedStyle(probe);
372
+ for (const name of site.siteVars) {
373
+ const value = style.getPropertyValue(name).trim();
374
+ if (value)
375
+ vars[name] = value;
376
+ }
377
+ }
378
+ catch { /* Keep the document's. */ }
379
+ item.sheet.disabled = false;
380
+ }
381
+ let css = '';
382
+ try {
383
+ css = site.css(collectRootRules(root, item.sheet, win.CSS), choice, mode, vars, flagState);
384
+ }
385
+ catch (error) {
386
+ console.error(`[${name}] theme (shadow root) failed`, error);
387
+ }
388
+ try {
389
+ item.sheet.replaceSync(staticText ? `${css}\n${staticText}` : css);
390
+ }
391
+ catch { /* Keeps the last good rules. */ }
392
+ }
393
+ // Last, so equal-specificity `!important` rules win over the site's; the site may re-set its list.
394
+ const list = root.adoptedStyleSheets;
395
+ if (list[list.length - 1] !== item.sheet) {
396
+ try {
397
+ root.adoptedStyleSheets = [...list.filter(sheet => sheet !== item.sheet), item.sheet];
398
+ }
399
+ catch { /* Never break the site. */ }
400
+ }
401
+ }
402
+ };
403
+ /** The static sheet sits right after the palette sheet (its part rules are more specific anyway; order only breaks ties). */
404
+ const placeStatic = (fixed, style) => {
405
+ if (!fixed || !style?.isConnected)
406
+ return;
407
+ if (style.nextElementSibling !== fixed)
408
+ style.after(fixed);
409
+ };
410
+ const render = (force = false) => {
411
+ let style = doc.getElementById(styleId);
412
+ let fixed = doc.getElementById(staticId);
413
+ if (doc.body) {
414
+ watchMode();
415
+ syncResolved();
416
+ }
417
+ if (!active()) {
418
+ style?.remove();
419
+ fixed?.remove();
420
+ lastKey = '';
421
+ staticKey = '';
422
+ dropEarly();
423
+ syncRoots(false, '', false);
424
+ flagsOn(false);
425
+ if (savedCss) {
426
+ savedCss = '';
427
+ writeSnapshot(storage, null);
428
+ }
429
+ return;
430
+ }
431
+ if (!doc.body)
432
+ return;
433
+ flagsOn(true);
434
+ const snapshotKey = `${JSON.stringify(choice)}|${mode}`;
435
+ if (early && snapshot?.key !== snapshotKey)
436
+ dropEarly();
437
+ // The static sheet follows the theme and the mode only (and `refresh()`), never the site's rules.
438
+ if (site.staticCss && (force || staticKey !== snapshotKey)) {
439
+ staticKey = snapshotKey;
440
+ let text = '';
441
+ try {
442
+ text = site.staticCss(choice, mode);
443
+ }
444
+ catch (error) {
445
+ console.error(`[${name}] theme structure failed`, error);
446
+ }
447
+ staticText = text;
448
+ if (text) {
449
+ if (!fixed) {
450
+ fixed = doc.createElement('style');
451
+ fixed.id = staticId;
452
+ }
453
+ if (fixed.textContent !== text)
454
+ fixed.textContent = text;
455
+ }
456
+ else {
457
+ fixed?.remove();
458
+ fixed = null;
459
+ }
460
+ }
461
+ const key = `${JSON.stringify(choice)}|${mode}|${flagState.join(' ')}|${ruleCount(doc) - (style?.sheet?.cssRules.length ?? 0) - (fixed?.sheet?.cssRules.length ?? 0)}`;
462
+ if (!force && key === lastKey) {
463
+ placeStatic(fixed, style);
464
+ syncRoots(true, snapshotKey, false);
465
+ return;
466
+ }
467
+ lastKey = key;
468
+ if (!style) {
469
+ style = doc.createElement('style');
470
+ style.id = styleId;
471
+ }
472
+ // The site's own values, not the ones our previous render overrode (switching themes re-reads them).
473
+ if (style.sheet)
474
+ style.sheet.disabled = true;
475
+ const vars = {};
476
+ if (site.siteVars?.length) {
477
+ const rootStyle = win.getComputedStyle(doc.documentElement);
478
+ for (const name of site.siteVars)
479
+ vars[name] = rootStyle.getPropertyValue(name).trim();
480
+ }
481
+ if (style.sheet)
482
+ style.sheet.disabled = false;
483
+ siteVars = vars;
484
+ const css = site.css(collectRules(doc, [style, fixed]), choice, mode, vars, flagState);
485
+ if (style.textContent !== css)
486
+ style.textContent = css;
487
+ // Last in <head> so equal-specificity `!important` rules win over the site's; the static sheet after it.
488
+ const last = fixed?.isConnected && doc.head?.lastElementChild === fixed ? fixed.previousElementSibling : doc.head?.lastElementChild;
489
+ if (style.parentNode !== doc.head || last !== style)
490
+ (doc.head || doc.documentElement).appendChild(style);
491
+ placeStatic(fixed, style);
492
+ syncRoots(true, snapshotKey, force);
493
+ const full = `${themeVarsCss(resolved)}\n${css}${staticText ? `\n${staticText}` : ''}`;
494
+ if (full !== savedCss) {
495
+ savedCss = full;
496
+ writeSnapshot(storage, { key: snapshotKey, choice, css: full });
497
+ }
498
+ };
499
+ const handle = {
500
+ apply(input) {
501
+ choice = catalog.normalize(input);
502
+ theme = catalog.resolve(choice);
503
+ const fonts = bundledFontsUsed(theme);
504
+ if (fonts.length) {
505
+ try {
506
+ options.loadFonts?.(fonts);
507
+ }
508
+ catch (error) {
509
+ console.error(`[${name}] theme fonts failed`, error);
510
+ }
511
+ }
512
+ if (active()) {
513
+ if (!timer)
514
+ timer = setInterval(() => { try {
515
+ render();
516
+ }
517
+ catch { /* Never break the site. */ } }, 1200);
518
+ }
519
+ else if (timer) {
520
+ clearInterval(timer);
521
+ timer = null;
522
+ }
523
+ try {
524
+ render(true);
525
+ }
526
+ catch (error) {
527
+ console.error(`[${name}] theme failed`, error);
528
+ }
529
+ win.dispatchEvent(new CustomEvent('wb-theme'));
530
+ },
531
+ current: () => choice,
532
+ theme: () => theme,
533
+ mode: () => mode,
534
+ resolved: () => {
535
+ if (doc.body && readMode() !== mode)
536
+ syncResolved();
537
+ return resolved;
538
+ },
539
+ onChange(listener) {
540
+ listeners.add(listener);
541
+ return () => { listeners.delete(listener); };
542
+ },
543
+ refresh() { try {
544
+ render(true);
545
+ }
546
+ catch (error) {
547
+ console.error(`[${name}] theme failed`, error);
548
+ } },
549
+ };
550
+ // The snapshot's theme until native code hands over the current one (usually the same): the
551
+ // live CSS then already renders at DOMContentLoaded instead of after the page finished loading.
552
+ if (snapshot) {
553
+ try {
554
+ handle.apply(snapshot.choice);
555
+ }
556
+ catch { /* Never break the site. */ }
557
+ }
558
+ if (doc.readyState === 'loading')
559
+ doc.addEventListener('DOMContentLoaded', () => render(true), { once: true });
560
+ // `--wb-*` exist from the start (the site's own palette until a theme is applied), for plugins and the UI kit.
561
+ else if (doc.body) {
562
+ try {
563
+ watchMode();
564
+ syncResolved();
565
+ }
566
+ catch { /* Never break the site. */ }
567
+ }
568
+ return handle;
569
+ }
570
+ //# sourceMappingURL=themeRuntime.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"themeRuntime.js","sourceRoot":"","sources":["../../../runtime/src/themeRuntime.ts"],"names":[],"mappings":"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","sourcesContent":["// The theme engine in a site's page: keeps one `<style>` with the theme's CSS in sync while the site\n// adds its own rules (React apps insert them lazily), exposes the resolved theme as `--wb-*` custom\n// properties for plugins and the UI kit, follows the site's own color mode, and paints the last\n// theme from the page's first frame (a snapshot in the page's storage). What the CSS is comes from\n// the site adapter (`ThemeRuntimeSite`): X re-declares its own stylesheet rules with the theme's\n// colors (`buildThemeCss`) and adds type/shape/layout rules over its selectors.\n\nimport { domRoots, watchDom, type DomWatchHandle } from './domHub.ts';\nimport { FONT_ROLE_NAMES, themeKey, themeVarsCss, type ResolvedFonts, type ResolvedTheme } from './themeApi.ts';\nimport type { ThemeCatalog, ThemeChoice } from './themeChoice.ts';\nimport { bundledFontsUsed, isNeutral, resolveFontRoles, type FontSpec, type ThemeSpec } from './themeSpec.ts';\n\n/** A style rule as the engine reads it (CSSStyleRule, or a plain object in tests). */\nexport type RuleLike = { selectorText: string; style: { getPropertyValue(name: string): string; length?: number } };\n\n/** The font roles as the plugin API reports them in a site's page; an inheriting interface uses `siteStack` (the site's own font). */\nexport function resolvedFonts(font: FontSpec, siteStack: string): ResolvedFonts {\n const roles = resolveFontRoles(font, siteStack);\n return Object.fromEntries(FONT_ROLE_NAMES.map(role => {\n const { stack, weight, size, tracking, tabular, inherited } = roles[role];\n return [role, { stack, weight, size, tracking, tabular, inherited }];\n })) as ResolvedFonts;\n}\n\ntype RuleNode = { selectorText?: string; style?: RuleLike['style']; cssRules?: ArrayLike<RuleNode>; conditionText?: string; type?: number; constructor?: { name?: string } };\nconst isSupports = (rule: RuleNode) => rule.type === 12 || rule.constructor?.name === 'CSSSupportsRule';\n\n/**\n * A style rule as it takes effect. Tailwind 4 writes an opacity utility as a fallback plus the real\n * value in a nested `@supports`:\n * `.bg-white\\/15 { background-color: var(--white); @supports (color: color-mix(in lab, red, red)) { background-color: color-mix(in oklab, var(--white) 15%, transparent) } }`.\n * Read alone, the outer declaration is a solid white fill; where the browser passes the condition the\n * nested one is what paints, so it answers for the rule.\n */\nfunction effectiveRule(rule: RuleNode, supported: (condition: string) => boolean): RuleLike {\n const overrides: Array<RuleLike['style']> = [];\n for (const child of Array.from(rule.cssRules ?? [])) {\n if (!isSupports(child) || !supported(child.conditionText ?? '')) continue;\n for (const inner of Array.from(child.cssRules ?? [])) {\n // Bare declarations inside the group: a CSSNestedDeclarations, or `& { }` in older engines.\n if (inner.style && (inner.selectorText === undefined || inner.selectorText === '&')) overrides.push(inner.style);\n }\n }\n if (!overrides.length) return rule as RuleLike;\n const outer = rule.style!;\n return {\n selectorText: rule.selectorText!,\n style: {\n getPropertyValue(name) {\n for (let i = overrides.length - 1; i >= 0; i--) { const value = overrides[i]!.getPropertyValue(name); if (value) return value; }\n return outer.getPropertyValue(name);\n },\n length: outer.length,\n },\n };\n}\n\n/**\n * Every style rule of `doc`'s stylesheets (inside media/supports groups too), except `own`'s (the\n * engine's own sheets: read as the site's, their radii and colors would be re-declared), each as it\n * takes effect (`effectiveRule`). A `@supports` group the browser does not pass is left out.\n */\nexport function collectRules(doc: Document, own: HTMLStyleElement | null | ReadonlyArray<HTMLStyleElement | null>): RuleLike[] {\n const ours = (Array.isArray(own) ? own : [own]).filter(Boolean) as HTMLStyleElement[];\n const sheets = Array.from(doc.styleSheets).filter(sheet => !ours.includes(sheet.ownerNode as HTMLStyleElement));\n return rulesOf(sheets, (doc.defaultView as (Window & typeof globalThis) | null)?.CSS);\n}\n\ntype SheetLike = { cssRules: CSSRuleList | ArrayLike<unknown> };\n/**\n * The same for an open shadow root the site renders a part of itself in (X's chat embed): its adopted\n * sheets and its `<style>` elements, except the engine's own adopted `own` sheet.\n */\nexport function collectRootRules(root: { adoptedStyleSheets?: readonly SheetLike[]; styleSheets?: ArrayLike<SheetLike> }, own: SheetLike | null, css?: { supports?(condition: string): boolean }): RuleLike[] {\n const sheets = [...Array.from(root.adoptedStyleSheets ?? []), ...Array.from(root.styleSheets ?? [])].filter(sheet => sheet !== own);\n return rulesOf(sheets, css);\n}\n\nfunction rulesOf(sheets: readonly SheetLike[], css: { supports?(condition: string): boolean } | undefined): RuleLike[] {\n const rules: RuleLike[] = [];\n const verdicts = new Map<string, boolean>();\n const supported = (condition: string) => {\n if (!condition || !css?.supports) return true;\n let verdict = verdicts.get(condition);\n if (verdict === undefined) { try { verdict = css.supports(condition); } catch { verdict = true; } verdicts.set(condition, verdict); }\n return verdict;\n };\n const walk = (list: ArrayLike<RuleNode>) => {\n for (const rule of Array.from(list)) {\n if (rule.selectorText !== undefined && rule.style) rules.push(effectiveRule(rule, supported));\n else if (rule.cssRules && rule.selectorText === undefined && (!isSupports(rule) || supported(rule.conditionText ?? ''))) walk(rule.cssRules);\n }\n };\n for (const sheet of sheets) {\n try { walk(sheet.cssRules as unknown as ArrayLike<RuleNode>); } catch { /* Cross-origin sheet. */ }\n }\n return rules;\n}\n\nfunction rootRuleCount(root: ShadowRoot, own: CSSStyleSheet | null): number {\n let count = 0;\n for (const sheet of [...Array.from(root.adoptedStyleSheets ?? []), ...Array.from(root.styleSheets ?? [])]) {\n if (sheet === own) continue;\n try { count += sheet.cssRules.length; } catch { /* Cross-origin. */ }\n }\n return count;\n}\n\nfunction ruleCount(doc: Document): number {\n let count = 0;\n for (const sheet of Array.from(doc.styleSheets)) { try { count += sheet.cssRules.length; } catch { /* Cross-origin. */ } }\n return count;\n}\n\n/**\n * The last theme CSS a tab showed, kept in the page's own storage so the next document paints it\n * from its first frame: native code only hands the theme over once the page has finished loading,\n * and the live CSS needs the site's rules, which it inserts while it renders. sessionStorage is per\n * tab and survives reloads and navigations; localStorage (smaller cap: the site uses it too) is per\n * account and covers a tab's first document.\n */\nexport type ThemeSnapshot = { key: string; choice: unknown; css: string };\nconst SNAPSHOT_KEY = 'wb:theme-snapshot';\nexport const SNAPSHOT_SESSION_MAX = 1_000_000;\nexport const SNAPSHOT_LOCAL_MAX = 200_000;\nexport type SnapshotStores = { session?: Storage | null; local?: Storage | null };\n\nfunction stores(win: Window): SnapshotStores {\n const get = (name: 'sessionStorage' | 'localStorage') => { try { return win[name]; } catch { return null; } };\n return { session: get('sessionStorage'), local: get('localStorage') };\n}\n\nexport function readSnapshot({ session, local }: SnapshotStores): ThemeSnapshot | null {\n for (const store of [session, local]) {\n try {\n const value = JSON.parse(store?.getItem(SNAPSHOT_KEY) || 'null') as Partial<ThemeSnapshot> | null;\n if (value && typeof value.key === 'string' && typeof value.css === 'string' && value.css && value.choice) return value as ThemeSnapshot;\n } catch { /* Missing, blocked or foreign data: no snapshot. */ }\n }\n return null;\n}\n\n/** Stores `snapshot` (null clears it: the site's own look needs none), each store within its cap. */\nexport function writeSnapshot({ session, local }: SnapshotStores, snapshot: ThemeSnapshot | null) {\n const json = snapshot ? JSON.stringify(snapshot) : '';\n for (const [store, max] of [[session, SNAPSHOT_SESSION_MAX], [local, SNAPSHOT_LOCAL_MAX]] as const) {\n try {\n if (json && json.length <= max) store?.setItem(SNAPSHOT_KEY, json);\n else store?.removeItem(SNAPSHOT_KEY);\n } catch { /* Quota or blocked storage: the next document just starts unthemed. */ }\n }\n}\n\n/** What the engine needs to know about a site. `Mode` is the site's own color mode (X: light, dim, dark). */\nexport type ThemeRuntimeSite<Mode extends string = string> = {\n /** The site's built-in themes (themeChoice.ts). */\n catalog: ThemeCatalog;\n /** The mode before the page has a body. */\n initialMode: Mode;\n /** The site's color mode as the page paints it now (read before the theme's own override: e.g. the body's inline style). */\n readMode(win: Window): Mode;\n /** The theme's CSS for the site's current `rules` (the engine's own sheet excluded) in `mode`; `vars` are `siteVars` as the site sets them. */\n css(rules: RuleLike[], choice: ThemeChoice, mode: Mode, vars: Record<string, string>, flags: readonly string[]): string;\n /** The active theme resolved for plugins and the UI kit (the site's own palette when the theme keeps its colors). */\n resolved(choice: ThemeChoice, mode: Mode): ResolvedTheme;\n /** Custom properties of the site's root read with the theme's sheet disabled (their unthemed values). */\n siteVars?: readonly string[];\n /**\n * The theme's CSS that does not depend on the site's stylesheet: components, variants, decoration,\n * icons. It lives in its own sheet (`staticId`), so the site inserting rules never rebuilds it; it is\n * rebuilt when the theme or the site's mode changes and on `refresh()` (the owner's switches, the\n * icon choice, the language).\n */\n staticCss?(choice: ThemeChoice, mode: Mode): string;\n /** Id of that sheet's `<style>` (default `wb-theme-static`). */\n staticId?: string;\n /** Id of the theme's `<style>` (default `wb-theme-css`). */\n styleId?: string;\n /** Name in console errors. */\n name?: string;\n /**\n * Page states the theme's CSS keys on, as `html[data-wb-<name>]` attributes kept by the engine:\n * set while `selector` matches in the page or one of its open shadow roots (domHub `shadowHosts`).\n * A theme rule gated by `html[data-wb-chat]` costs nothing when the page changes; the same gate\n * as `html:has(...)` makes the browser re-match the whole page on every insertion (seen on x.com:\n * 10-100 ms per inserted node under a theme instead of 0.1 ms).\n */\n flags?: Readonly<Record<string, string>>;\n};\n\n/** The attribute a page flag sets on `<html>`. */\nexport const flagAttribute = (name: string) => `data-wb-${name}`;\n\n/** Which of `flags` hold in `roots` now (pure, for tests). */\nexport function pageFlags(roots: ReadonlyArray<{ querySelector(selector: string): unknown }>, flags: Readonly<Record<string, string>>): string[] {\n const on: string[] = [];\n for (const [name, selector] of Object.entries(flags)) {\n try { if (roots.some(root => !!root.querySelector(selector))) on.push(name); } catch { /* A bad selector is never on. */ }\n }\n return on;\n}\n\nexport type ThemeHandle<Mode extends string = string> = {\n apply(choice: unknown): void;\n current(): ThemeChoice;\n theme(): ThemeSpec;\n /** The site's color mode the theme was last rendered for. */\n mode(): Mode;\n /** The active theme as values for plugins (`api.theme.current()`). */\n resolved(): ResolvedTheme;\n /** Calls `listener` after the theme or the site's color mode changes. */\n onChange(listener: () => void): () => void;\n /** Rebuilds the theme's CSS now: something it depends on besides the theme changed (the owner's switches, the icon choice). */\n refresh(): void;\n};\nexport type ThemeRuntimeOptions = { /** Registers bundled families (e.g. \"Geist\") in the page before they are used. */ loadFonts?(names: string[]): void };\n\nconst VARS_ID = 'wb-theme-vars';\n\n/** Keeps the site's page in the owner's theme (see the top of this file). */\nexport function installThemeRuntime<Mode extends string>(win: Window, site: ThemeRuntimeSite<Mode>, options: ThemeRuntimeOptions = {}): ThemeHandle<Mode> {\n const doc = win.document;\n const name = site.name ?? 'wayBetter';\n const styleId = site.styleId ?? 'wb-theme-css';\n const staticId = site.staticId ?? 'wb-theme-static';\n const { catalog } = site;\n // Document start (no <html> yet): the snapshot as an adopted sheet paints with the site's first\n // frame. It stays while the live CSS is for the same theme and site mode, and goes when they differ.\n const storage = stores(win);\n const snapshot = readSnapshot(storage);\n let early: CSSStyleSheet | null = null;\n if (snapshot) {\n try {\n const Sheet = (win as Window & typeof globalThis).CSSStyleSheet;\n early = new Sheet();\n early.replaceSync(snapshot.css);\n doc.adoptedStyleSheets = [...doc.adoptedStyleSheets, early];\n } catch { early = null; }\n }\n const dropEarly = () => {\n if (!early) return;\n const sheet = early;\n early = null;\n try { doc.adoptedStyleSheets = doc.adoptedStyleSheets.filter(item => item !== sheet); } catch { /* Never break the site. */ }\n };\n let savedCss = snapshot?.css ?? '';\n let choice = catalog.defaultChoice;\n let theme = catalog.resolve(choice);\n let lastKey = '';\n let timer: ReturnType<typeof setInterval> | null = null;\n const active = () => !isNeutral(theme) || !!choice.accent || !!choice.icons;\n let mode: Mode = site.initialMode;\n let resolved: ResolvedTheme = site.resolved(choice, mode);\n let resolvedKey = themeKey(resolved);\n const listeners = new Set<() => void>();\n const readMode = () => (doc.body ? site.readMode(win) : mode);\n /** `--wb-*` on :root for plugin CSS, and a change notice when anything visible changed. */\n const syncResolved = () => {\n if (doc.body) mode = readMode();\n resolved = site.resolved(choice, mode);\n const key = themeKey(resolved);\n let vars = doc.getElementById(VARS_ID) as HTMLStyleElement | null;\n if (!vars?.isConnected) {\n vars = doc.createElement('style');\n vars.id = VARS_ID;\n (doc.head || doc.documentElement).appendChild(vars);\n }\n const css = themeVarsCss(resolved);\n if (vars.textContent !== css) vars.textContent = css;\n if (key === resolvedKey) return;\n resolvedKey = key;\n for (const listener of [...listeners]) {\n try { listener(); } catch (error) { console.error(`[${name}] theme listener failed`, error); }\n }\n };\n let modeObserver: MutationObserver | null = null;\n const watchMode = () => {\n if (modeObserver || !doc.body) return;\n // Sites repaint the body when their own display setting changes (X: Default / Dim / Lights out).\n const Observer = (win as Window & typeof globalThis).MutationObserver ?? globalThis.MutationObserver;\n if (!Observer) return;\n modeObserver = new Observer(() => { try { if (readMode() !== mode) syncResolved(); } catch { /* Never break the site. */ } });\n modeObserver.observe(doc.body, { attributes: true, attributeFilter: ['style'] });\n };\n\n let staticKey = '';\n let staticText = '';\n let siteVars: Record<string, string> = {};\n // Page flags (`site.flags`): checked once per hub frame after the page changed, on every page (heavy ones too).\n const flagNames = Object.keys(site.flags ?? {});\n let flagWatch: DomWatchHandle | null = null;\n // The flags that hold now; the theme's CSS is rebuilt when they change (a rule that only applies to a\n // signed-out page can then be left out of a signed-in one instead of being gated by `:has()`).\n let flagState: string[] = [];\n const syncFlags = () => {\n const root = doc.documentElement;\n if (!root || !flagNames.length) return;\n let on: string[] = [];\n try { on = pageFlags(domRoots(win), site.flags!); } catch { on = []; }\n for (const name of flagNames) {\n const attr = flagAttribute(name);\n const want = on.includes(name);\n if (root.hasAttribute(attr) !== want) { if (want) root.setAttribute(attr, ''); else root.removeAttribute(attr); }\n }\n const changed = on.join(' ') !== flagState.join(' ');\n flagState = on;\n return changed;\n };\n const flagsOn = (on: boolean) => {\n if (!flagNames.length) return;\n if (on) {\n syncFlags();\n if (!flagWatch) { try { flagWatch = watchDom(win as never, () => { if (syncFlags()) { try { render(); } catch { /* Never break the site. */ } } }, { offOnHeavy: false }); } catch { flagWatch = null; } }\n } else {\n flagWatch?.dispose(); flagWatch = null;\n for (const name of flagNames) doc.documentElement?.removeAttribute(flagAttribute(name));\n }\n };\n // Open shadow roots the site renders a part of itself in (domHub `shadowHosts`; X's chat embed since\n // 2026-10-01): the document's sheets do not reach inside, so each root adopts the theme built from\n // its own rules plus the static sheet, kept last among its sheets, rebuilt when its rules change and\n // taken off when the theme is off or the root is gone.\n const rootSheets = new Map<ShadowRoot, { sheet: CSSStyleSheet; key: string }>();\n const detach = (root: ShadowRoot, sheet: CSSStyleSheet) => { try { root.adoptedStyleSheets = root.adoptedStyleSheets.filter(item => item !== sheet); } catch { /* Root gone. */ } };\n const syncRoots = (on: boolean, snapshotKey: string, force: boolean) => {\n let roots: ShadowRoot[] = [];\n if (on) { try { roots = domRoots(win).slice(1) as ShadowRoot[]; } catch { roots = []; } }\n for (const [root, item] of rootSheets) if (!roots.includes(root)) { detach(root, item.sheet); rootSheets.delete(root); }\n const Sheet = (win as Window & typeof globalThis).CSSStyleSheet;\n for (const root of roots) {\n let item = rootSheets.get(root);\n if (!item) {\n try { item = { sheet: new Sheet(), key: '' }; } catch { continue; }\n rootSheets.set(root, item);\n }\n const key = `${snapshotKey}|${flagState.join(' ')}|${rootRuleCount(root, item.sheet)}|${staticText.length}`;\n if (force || item.key !== key) {\n item.key = key;\n // The site's primitives as the root sees them (its own sheets may declare them; the document may not), read with our sheet off.\n const vars = { ...siteVars };\n if (site.siteVars?.length) {\n const probe = root.firstElementChild ?? root.host;\n item.sheet.disabled = true;\n try { const style = win.getComputedStyle(probe); for (const name of site.siteVars) { const value = style.getPropertyValue(name).trim(); if (value) vars[name] = value; } } catch { /* Keep the document's. */ }\n item.sheet.disabled = false;\n }\n let css = '';\n try { css = site.css(collectRootRules(root, item.sheet, (win as Window & typeof globalThis).CSS), choice, mode, vars, flagState); } catch (error) { console.error(`[${name}] theme (shadow root) failed`, error); }\n try { item.sheet.replaceSync(staticText ? `${css}\\n${staticText}` : css); } catch { /* Keeps the last good rules. */ }\n }\n // Last, so equal-specificity `!important` rules win over the site's; the site may re-set its list.\n const list = root.adoptedStyleSheets;\n if (list[list.length - 1] !== item.sheet) { try { root.adoptedStyleSheets = [...list.filter(sheet => sheet !== item!.sheet), item.sheet]; } catch { /* Never break the site. */ } }\n }\n };\n /** The static sheet sits right after the palette sheet (its part rules are more specific anyway; order only breaks ties). */\n const placeStatic = (fixed: HTMLStyleElement | null, style: HTMLStyleElement | null) => {\n if (!fixed || !style?.isConnected) return;\n if (style.nextElementSibling !== fixed) style.after(fixed);\n };\n const render = (force = false) => {\n let style = doc.getElementById(styleId) as HTMLStyleElement | null;\n let fixed = doc.getElementById(staticId) as HTMLStyleElement | null;\n if (doc.body) { watchMode(); syncResolved(); }\n if (!active()) { style?.remove(); fixed?.remove(); lastKey = ''; staticKey = ''; dropEarly(); syncRoots(false, '', false); flagsOn(false); if (savedCss) { savedCss = ''; writeSnapshot(storage, null); } return; }\n if (!doc.body) return;\n flagsOn(true);\n const snapshotKey = `${JSON.stringify(choice)}|${mode}`;\n if (early && snapshot?.key !== snapshotKey) dropEarly();\n // The static sheet follows the theme and the mode only (and `refresh()`), never the site's rules.\n if (site.staticCss && (force || staticKey !== snapshotKey)) {\n staticKey = snapshotKey;\n let text = '';\n try { text = site.staticCss(choice, mode); } catch (error) { console.error(`[${name}] theme structure failed`, error); }\n staticText = text;\n if (text) {\n if (!fixed) { fixed = doc.createElement('style'); fixed.id = staticId; }\n if (fixed.textContent !== text) fixed.textContent = text;\n } else { fixed?.remove(); fixed = null; }\n }\n const key = `${JSON.stringify(choice)}|${mode}|${flagState.join(' ')}|${ruleCount(doc) - (style?.sheet?.cssRules.length ?? 0) - (fixed?.sheet?.cssRules.length ?? 0)}`;\n if (!force && key === lastKey) { placeStatic(fixed, style); syncRoots(true, snapshotKey, false); return; }\n lastKey = key;\n if (!style) { style = doc.createElement('style'); style.id = styleId; }\n // The site's own values, not the ones our previous render overrode (switching themes re-reads them).\n if (style.sheet) style.sheet.disabled = true;\n const vars: Record<string, string> = {};\n if (site.siteVars?.length) {\n const rootStyle = win.getComputedStyle(doc.documentElement);\n for (const name of site.siteVars) vars[name] = rootStyle.getPropertyValue(name).trim();\n }\n if (style.sheet) style.sheet.disabled = false;\n siteVars = vars;\n const css = site.css(collectRules(doc, [style, fixed]), choice, mode, vars, flagState);\n if (style.textContent !== css) style.textContent = css;\n // Last in <head> so equal-specificity `!important` rules win over the site's; the static sheet after it.\n const last = fixed?.isConnected && doc.head?.lastElementChild === fixed ? fixed.previousElementSibling : doc.head?.lastElementChild;\n if (style.parentNode !== doc.head || last !== style) (doc.head || doc.documentElement).appendChild(style);\n placeStatic(fixed, style);\n syncRoots(true, snapshotKey, force);\n const full = `${themeVarsCss(resolved)}\\n${css}${staticText ? `\\n${staticText}` : ''}`;\n if (full !== savedCss) { savedCss = full; writeSnapshot(storage, { key: snapshotKey, choice, css: full }); }\n };\n\n const handle: ThemeHandle<Mode> = {\n apply(input) {\n choice = catalog.normalize(input);\n theme = catalog.resolve(choice);\n const fonts = bundledFontsUsed(theme);\n if (fonts.length) { try { options.loadFonts?.(fonts); } catch (error) { console.error(`[${name}] theme fonts failed`, error); } }\n if (active()) {\n if (!timer) timer = setInterval(() => { try { render(); } catch { /* Never break the site. */ } }, 1200);\n } else if (timer) { clearInterval(timer); timer = null; }\n try { render(true); } catch (error) { console.error(`[${name}] theme failed`, error); }\n win.dispatchEvent(new CustomEvent('wb-theme'));\n },\n current: () => choice,\n theme: () => theme,\n mode: () => mode,\n resolved: () => {\n if (doc.body && readMode() !== mode) syncResolved();\n return resolved;\n },\n onChange(listener) {\n listeners.add(listener);\n return () => { listeners.delete(listener); };\n },\n refresh() { try { render(true); } catch (error) { console.error(`[${name}] theme failed`, error); } },\n };\n // The snapshot's theme until native code hands over the current one (usually the same): the\n // live CSS then already renders at DOMContentLoaded instead of after the page finished loading.\n if (snapshot) { try { handle.apply(snapshot.choice); } catch { /* Never break the site. */ } }\n if (doc.readyState === 'loading') doc.addEventListener('DOMContentLoaded', () => render(true), { once: true });\n // `--wb-*` exist from the start (the site's own palette until a theme is applied), for plugins and the UI kit.\n else if (doc.body) { try { watchMode(); syncResolved(); } catch { /* Never break the site. */ } }\n return handle;\n}\n"]}