@mudlet/mudlet-web 0.5.0 → 1.0.1

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 (301) hide show
  1. package/README.md +1 -1
  2. package/dist-lib/analytics.d.ts +27 -0
  3. package/dist-lib/assets/fonts/Vera.woff2 +0 -0
  4. package/dist-lib/assets/fonts/VeraBI.woff2 +0 -0
  5. package/dist-lib/assets/fonts/VeraBd.woff2 +0 -0
  6. package/dist-lib/assets/fonts/VeraIt.woff2 +0 -0
  7. package/dist-lib/assets/mapParser.worker-DrVZ3wg_.js +9 -0
  8. package/dist-lib/backupImport-wt8r7JXI.js +233 -0
  9. package/dist-lib/branding.d.ts +111 -13
  10. package/dist-lib/db/sqliteClient.d.ts +195 -7
  11. package/dist-lib/hooks/useAutoReconnect.d.ts +61 -0
  12. package/dist-lib/hooks/useDocumentFullscreen.d.ts +23 -0
  13. package/dist-lib/hooks/useKeyboardShortcuts.d.ts +37 -0
  14. package/dist-lib/hooks/useRecordLastPlayed.d.ts +10 -0
  15. package/dist-lib/import/applyMudletProfile.d.ts +35 -9
  16. package/dist-lib/import/backupImport.d.ts +118 -0
  17. package/dist-lib/import/collectProfileExport.d.ts +33 -2
  18. package/dist-lib/import/defaultPackages.d.ts +57 -14
  19. package/dist-lib/import/defaults/CF-loader/CF-loader.mpackage +0 -0
  20. package/dist-lib/import/defaults/MedBootstrap/MedBootstrap.mpackage +0 -0
  21. package/dist-lib/import/defaults/deleteOldProfiles/deleteOldProfiles.mpackage +0 -0
  22. package/dist-lib/import/defaults/echo/echo.mpackage +0 -0
  23. package/dist-lib/import/defaults/enable-accessibility/enable-accessibility.mpackage +0 -0
  24. package/dist-lib/import/defaults/generic_mapper/generic_mapper.mpackage +0 -0
  25. package/dist-lib/import/defaults/gui-drop/gui-drop.mpackage +0 -0
  26. package/dist-lib/import/defaults/icesus-loader/icesus-loader.mpackage +0 -0
  27. package/dist-lib/import/defaults/mg-loader/mg-loader.mpackage +0 -0
  28. package/dist-lib/import/defaults/mudlet-base-ui/mudlet-base-ui.mpackage +0 -0
  29. package/dist-lib/import/defaults/mudlet-mapper.xml +1215 -389
  30. package/dist-lib/import/mudletControlChars.d.ts +14 -0
  31. package/dist-lib/import/mudletHost.d.ts +73 -10
  32. package/dist-lib/import/mudletLink.d.ts +53 -2
  33. package/dist-lib/import/mudletProfileExport.d.ts +38 -5
  34. package/dist-lib/import/mudletProfileImport.d.ts +110 -12
  35. package/dist-lib/import/mudletVariables.d.ts +4 -3
  36. package/dist-lib/import/mudletWriteback.d.ts +15 -1
  37. package/dist-lib/import/mudletXmlImport.d.ts +46 -0
  38. package/dist-lib/import/packageFonts.d.ts +33 -0
  39. package/dist-lib/import/packageInstaller.d.ts +111 -7
  40. package/dist-lib/import/qtProfileData.d.ts +10 -0
  41. package/dist-lib/import/remotePackageInstall.d.ts +23 -7
  42. package/dist-lib/import/zipEntries.d.ts +45 -0
  43. package/dist-lib/index.d.ts +7 -3
  44. package/dist-lib/index.js +50508 -29836
  45. package/dist-lib/logging/SessionLogger.d.ts +75 -15
  46. package/dist-lib/map/MapSelectionOverlay.d.ts +2 -2
  47. package/dist-lib/map/MapStore.d.ts +387 -60
  48. package/dist-lib/map/MudletHighlightOverlay.d.ts +2 -2
  49. package/dist-lib/map/{MudixMapReader.d.ts → MudletMapReader.d.ts} +2 -2
  50. package/dist-lib/map/areaGraph.d.ts +120 -0
  51. package/dist-lib/map/environmentKit.d.ts +36 -0
  52. package/dist-lib/map/labelPixmap.d.ts +90 -0
  53. package/dist-lib/map/mapImageExport.d.ts +36 -2
  54. package/dist-lib/map/mapStyle.d.ts +11 -0
  55. package/dist-lib/map/mapVersion.d.ts +66 -0
  56. package/dist-lib/map/pathfinding.d.ts +2 -2
  57. package/dist-lib/mud/CharLoginController.d.ts +230 -0
  58. package/dist-lib/mud/ItemIdSequence.d.ts +1 -1
  59. package/dist-lib/mud/MudSession.d.ts +279 -22
  60. package/dist-lib/mud/PatternEngine.d.ts +153 -14
  61. package/dist-lib/mud/aliases/AliasEngine.d.ts +55 -9
  62. package/dist-lib/mud/autoLogin.d.ts +59 -0
  63. package/dist-lib/mud/commandSplit.d.ts +9 -0
  64. package/dist-lib/mud/connection/LineAssembler.d.ts +38 -11
  65. package/dist-lib/mud/connection/MudClient.d.ts +291 -53
  66. package/dist-lib/mud/connection/SubnegotiationRepair.d.ts +24 -0
  67. package/dist-lib/mud/connection/TelnetNegotiator.d.ts +208 -68
  68. package/dist-lib/mud/connection/telnetDebug.d.ts +8 -8
  69. package/dist-lib/mud/events.d.ts +102 -23
  70. package/dist-lib/mud/games/bundledGames.d.ts +12 -7
  71. package/dist-lib/mud/games/gameLinks.d.ts +40 -0
  72. package/dist-lib/mud/games/icons/3Kingdoms.png +0 -0
  73. package/dist-lib/mud/games/icons/3Scapes.png +0 -0
  74. package/dist-lib/mud/games/icons/achaea.png +0 -0
  75. package/dist-lib/mud/games/icons/aetolia.png +0 -0
  76. package/dist-lib/mud/games/icons/banner_astaria.png +0 -0
  77. package/dist-lib/mud/games/icons/banner_darkmists.png +0 -0
  78. package/dist-lib/mud/games/icons/banner_dreamland.png +0 -0
  79. package/dist-lib/mud/games/icons/banner_petria.jpg +0 -0
  80. package/dist-lib/mud/games/icons/banner_ropmud.png +0 -0
  81. package/dist-lib/mud/games/icons/blackmud.png +0 -0
  82. package/dist-lib/mud/games/icons/carrionfields.png +0 -0
  83. package/dist-lib/mud/games/icons/dragonfire_icon.png +0 -0
  84. package/dist-lib/mud/games/icons/fed2-logo.png +0 -0
  85. package/dist-lib/mud/games/icons/icesus_480x120.png +0 -0
  86. package/dist-lib/mud/games/icons/imperian.png +0 -0
  87. package/dist-lib/mud/games/icons/infinity_480x120.png +0 -0
  88. package/dist-lib/mud/games/icons/lusternia.png +0 -0
  89. package/dist-lib/mud/games/icons/morgengrauen_480x120.png +0 -0
  90. package/dist-lib/mud/games/icons/mudlet-tutorial.png +0 -0
  91. package/dist-lib/mud/games/icons/phoenixmud_480x120.png +0 -0
  92. package/dist-lib/mud/games/icons/starmourn.png +0 -0
  93. package/dist-lib/mud/games/icons/voidmud_icon.png +0 -0
  94. package/dist-lib/mud/games/icons/wotmudicon.png +0 -0
  95. package/dist-lib/mud/games/websiteLinks.d.ts +21 -0
  96. package/dist-lib/mud/keybindings/KeyEngine.d.ts +110 -4
  97. package/dist-lib/mud/keybindings/browserReservedKeys.d.ts +2 -2
  98. package/dist-lib/mud/keybindings/keyEventTarget.d.ts +61 -0
  99. package/dist-lib/mud/keybindings/qtKeys.d.ts +91 -12
  100. package/dist-lib/mud/protocol/atcp.d.ts +19 -0
  101. package/dist-lib/mud/protocol/byteString.d.ts +24 -0
  102. package/dist-lib/mud/protocol/charLoginFlow.d.ts +243 -16
  103. package/dist-lib/mud/protocol/charset.d.ts +111 -46
  104. package/dist-lib/mud/protocol/codePages.d.ts +10 -0
  105. package/dist-lib/mud/protocol/constants.d.ts +17 -10
  106. package/dist-lib/mud/protocol/echo.d.ts +23 -27
  107. package/dist-lib/mud/protocol/gmcp.d.ts +36 -6
  108. package/dist-lib/mud/protocol/index.d.ts +3 -2
  109. package/dist-lib/mud/protocol/luaLiteral.d.ts +12 -0
  110. package/dist-lib/mud/protocol/mccp.d.ts +83 -1
  111. package/dist-lib/mud/protocol/mnes.d.ts +41 -58
  112. package/dist-lib/mud/protocol/msdp.d.ts +11 -4
  113. package/dist-lib/mud/protocol/msp.d.ts +3 -2
  114. package/dist-lib/mud/protocol/mssp.d.ts +9 -4
  115. package/dist-lib/mud/protocol/multiByte.d.ts +51 -0
  116. package/dist-lib/mud/protocol/multiByteEncode.d.ts +42 -0
  117. package/dist-lib/mud/protocol/mxp.d.ts +193 -14
  118. package/dist-lib/mud/protocol/oauthClientFlow.d.ts +128 -0
  119. package/dist-lib/mud/protocol/qtCodePages.generated.d.ts +1 -0
  120. package/dist-lib/mud/protocol/tlsCodes.d.ts +40 -3
  121. package/dist-lib/mud/replay/ReplayPlayer.d.ts +16 -1
  122. package/dist-lib/mud/replay/replayFormat.d.ts +29 -2
  123. package/dist-lib/mud/text/Console.d.ts +255 -49
  124. package/dist-lib/mud/text/FormatState.d.ts +137 -14
  125. package/dist-lib/mud/text/ansiEscapes.d.ts +32 -16
  126. package/dist-lib/mud/text/colorParsers.d.ts +14 -2
  127. package/dist-lib/mud/text/colorSpaceId.d.ts +2 -0
  128. package/dist-lib/mud/text/colors.d.ts +17 -10
  129. package/dist-lib/mud/text/controlCharacterMode.d.ts +1 -1
  130. package/dist-lib/mud/text/hyperlinkVisibility.d.ts +1 -1
  131. package/dist-lib/mud/text/lineBreak.d.ts +5 -0
  132. package/dist-lib/mud/text/serverWrap.d.ts +2 -2
  133. package/dist-lib/mud/text/textAnalyzer.d.ts +79 -0
  134. package/dist-lib/mud/text/unicodeRuns.d.ts +11 -0
  135. package/dist-lib/mud/text/unicodeTables.generated.d.ts +3 -0
  136. package/dist-lib/mud/text/wcwidth.d.ts +27 -22
  137. package/dist-lib/mud/timers/TimerEngine.d.ts +163 -11
  138. package/dist-lib/mud/timers/workerClock.d.ts +67 -0
  139. package/dist-lib/mud/triggers/TriggerEngine.d.ts +449 -47
  140. package/dist-lib/mud/triggers/legacyColorPatterns.d.ts +58 -0
  141. package/dist-lib/mud/triggers/pcre/Pcre2.d.ts +83 -1
  142. package/dist-lib/oauth-callback.html +94 -0
  143. package/dist-lib/pcre2Wasm.d.ts +54 -0
  144. package/dist-lib/pcre2Wasm.js +241 -0
  145. package/dist-lib/scripting/EngineHost.d.ts +45 -21
  146. package/dist-lib/scripting/IScriptingRuntime.d.ts +103 -27
  147. package/dist-lib/scripting/MxpFrameManager.d.ts +10 -1
  148. package/dist-lib/scripting/ScriptingAPI.d.ts +1030 -213
  149. package/dist-lib/scripting/ScriptingEngine.d.ts +727 -106
  150. package/dist-lib/scripting/StopwatchManager.d.ts +97 -36
  151. package/dist-lib/scripting/http/HttpService.d.ts +9 -1
  152. package/dist-lib/scripting/http/userUrl.d.ts +41 -0
  153. package/dist-lib/scripting/lua/LuaRuntime.d.ts +352 -77
  154. package/dist-lib/scripting/lua/argContracts.d.ts +71 -0
  155. package/dist-lib/scripting/lua/bindings/automation.d.ts +1 -1
  156. package/dist-lib/scripting/lua/bindings/commands.d.ts +13 -0
  157. package/dist-lib/scripting/lua/bindings/context.d.ts +20 -2
  158. package/dist-lib/scripting/lua/bindings/diagnostics.d.ts +1 -1
  159. package/dist-lib/scripting/lua/bindings/map.d.ts +1 -1
  160. package/dist-lib/scripting/lua/bindings/media.d.ts +2 -2
  161. package/dist-lib/scripting/lua/bindings/output.d.ts +1 -1
  162. package/dist-lib/scripting/lua/bindings/session.d.ts +2 -2
  163. package/dist-lib/scripting/lua/bindings/textEdit.d.ts +1 -1
  164. package/dist-lib/scripting/lua/bindings/userWindows.d.ts +1 -1
  165. package/dist-lib/scripting/lua/byteArmor.d.ts +36 -0
  166. package/dist-lib/scripting/lua/imageSize.d.ts +7 -0
  167. package/dist-lib/scripting/lua/rex.d.ts +4 -2
  168. package/dist-lib/scripting/lua/sqlRowEncoder.d.ts +6 -1
  169. package/dist-lib/scripting/lua/utf8CaseMap.d.ts +1 -0
  170. package/dist-lib/scripting/lua/utf8Patterns.d.ts +21 -1
  171. package/dist-lib/scripting/lua/wellFormedStrings.d.ts +40 -0
  172. package/dist-lib/scripting/lua/yajl.d.ts +43 -5
  173. package/dist-lib/scripting/profilesPresence.d.ts +20 -2
  174. package/dist-lib/scripting/vfs/ProfileVFS.d.ts +164 -10
  175. package/dist-lib/scripting/vfs/fsErrors.d.ts +28 -0
  176. package/dist-lib/scripting/vfs/idbCommit.d.ts +20 -0
  177. package/dist-lib/storage/appStore.d.ts +24 -9
  178. package/dist-lib/storage/hooks.d.ts +5 -1
  179. package/dist-lib/storage/index.d.ts +2 -2
  180. package/dist-lib/storage/mapStorage.d.ts +2 -0
  181. package/dist-lib/storage/persistentStorage.d.ts +3 -1
  182. package/dist-lib/storage/profileStorage.d.ts +15 -0
  183. package/dist-lib/storage/profileVfsData.d.ts +3 -3
  184. package/dist-lib/storage/schema.d.ts +512 -40
  185. package/dist-lib/storage/storageMigration.d.ts +82 -0
  186. package/dist-lib/storage-g5V1b-c1.js +2039 -0
  187. package/dist-lib/styles.css +1 -1
  188. package/dist-lib/ui/AboutModal.d.ts +1 -1
  189. package/dist-lib/ui/BrandLoginFields.d.ts +1 -1
  190. package/dist-lib/ui/BrowserSignInModal.d.ts +23 -0
  191. package/dist-lib/ui/CmdLineMenuRegistry.d.ts +14 -5
  192. package/dist-lib/ui/CommandBar.d.ts +8 -8
  193. package/dist-lib/ui/ConnectionFormModal.d.ts +20 -1
  194. package/dist-lib/ui/ConnectionScreen.d.ts +9 -1
  195. package/dist-lib/ui/GameLinkPrompt.d.ts +28 -0
  196. package/dist-lib/ui/HelpModal.d.ts +5 -1
  197. package/dist-lib/ui/MapSymbolUsageModal.d.ts +32 -0
  198. package/dist-lib/ui/MouseEventRegistry.d.ts +31 -4
  199. package/dist-lib/ui/NotepadModal.d.ts +22 -0
  200. package/dist-lib/ui/ResizableModal.d.ts +16 -1
  201. package/dist-lib/ui/SettingsModal.d.ts +10 -1
  202. package/dist-lib/ui/TlsAlertBanner.d.ts +3 -1
  203. package/dist-lib/ui/Toolbar.d.ts +22 -1
  204. package/dist-lib/ui/VaultManageButton.d.ts +10 -5
  205. package/dist-lib/ui/VaultModal.d.ts +3 -0
  206. package/dist-lib/ui/buttons/ButtonsBar.d.ts +3 -1
  207. package/dist-lib/ui/buttons/inactiveButtons.d.ts +25 -0
  208. package/dist-lib/ui/cmdline/CommandLineManager.d.ts +19 -0
  209. package/dist-lib/ui/cmdline/plainText.d.ts +16 -0
  210. package/dist-lib/ui/cmdline/subCommandLine.d.ts +78 -0
  211. package/dist-lib/ui/cmdline/useCmdLineSelection.d.ts +26 -0
  212. package/dist-lib/ui/cmdline/useSubCommandLineKeys.d.ts +33 -0
  213. package/dist-lib/ui/codemirror/lineParagraphMarks.d.ts +19 -0
  214. package/dist-lib/ui/codemirror/luaHover.d.ts +7 -0
  215. package/dist-lib/ui/codemirror/options.d.ts +33 -0
  216. package/dist-lib/ui/codemirror/theme.d.ts +29 -5
  217. package/dist-lib/ui/commands/addonCommands.d.ts +134 -0
  218. package/dist-lib/ui/commands/appShortcuts.d.ts +86 -0
  219. package/dist-lib/ui/commands/hostCommands.d.ts +88 -0
  220. package/dist-lib/ui/commands/keyMatch.d.ts +20 -0
  221. package/dist-lib/ui/commands/keySequence.d.ts +57 -0
  222. package/dist-lib/ui/components/ContextMenu.d.ts +21 -1
  223. package/dist-lib/ui/components/FontPicker.d.ts +5 -1
  224. package/dist-lib/ui/components/useModalFocus.d.ts +13 -1
  225. package/dist-lib/ui/helpTopics.d.ts +15 -0
  226. package/dist-lib/ui/labels/LabelManager.d.ts +172 -9
  227. package/dist-lib/ui/labels/LabelOverlay.d.ts +19 -0
  228. package/dist-lib/ui/labels/backgroundImageSize.d.ts +19 -0
  229. package/dist-lib/ui/labels/labelModel.d.ts +64 -0
  230. package/dist-lib/ui/labels/qColor.d.ts +13 -0
  231. package/dist-lib/ui/labels/qtCss.d.ts +12 -4
  232. package/dist-lib/ui/landmarks.d.ts +9 -0
  233. package/dist-lib/ui/launcher/ActionMenu.d.ts +19 -0
  234. package/dist-lib/ui/launcher/GameDetails.d.ts +21 -0
  235. package/dist-lib/ui/launcher/GameSection.d.ts +18 -0
  236. package/dist-lib/ui/launcher/LauncherSearch.d.ts +23 -0
  237. package/dist-lib/ui/launcher/ProfileArt.d.ts +20 -0
  238. package/dist-lib/ui/launcher/ProfileSection.d.ts +43 -0
  239. package/dist-lib/ui/launcher/launcherModel.d.ts +72 -0
  240. package/dist-lib/ui/layout/overlayLayerOrder.d.ts +2 -2
  241. package/dist-lib/ui/menu/MenuBar.d.ts +31 -0
  242. package/dist-lib/ui/menu/SplitButton.d.ts +39 -0
  243. package/dist-lib/ui/menu/anchoredPopup.d.ts +74 -0
  244. package/dist-lib/ui/menu/appMenus.d.ts +65 -0
  245. package/dist-lib/ui/menu/menuModel.d.ts +88 -0
  246. package/dist-lib/ui/menu/toolbarModel.d.ts +56 -0
  247. package/dist-lib/ui/notepad.d.ts +76 -0
  248. package/dist-lib/ui/openSignInPage.d.ts +14 -0
  249. package/dist-lib/ui/output/OutputContextMenu.d.ts +14 -1
  250. package/dist-lib/ui/output/OutputRenderer.d.ts +5 -0
  251. package/dist-lib/ui/output/OutputSearchBar.d.ts +5 -1
  252. package/dist-lib/ui/output/StickyOutputPanel.d.ts +17 -3
  253. package/dist-lib/ui/output/TextAnalyzerModal.d.ts +25 -0
  254. package/dist-lib/ui/output/caretMode.d.ts +3 -2
  255. package/dist-lib/ui/output/clearSplit.d.ts +11 -0
  256. package/dist-lib/ui/output/outputCopy.d.ts +41 -2
  257. package/dist-lib/ui/output/outputRows.d.ts +43 -0
  258. package/dist-lib/ui/output/selectionGesture.d.ts +35 -0
  259. package/dist-lib/ui/output/wordSelection.d.ts +33 -0
  260. package/dist-lib/ui/search/matcher.d.ts +14 -4
  261. package/dist-lib/ui/settings/SettingsShell.d.ts +91 -0
  262. package/dist-lib/ui/settings/ShortcutEditor.d.ts +13 -0
  263. package/dist-lib/ui/sound/SoundManager.d.ts +210 -44
  264. package/dist-lib/ui/sound/closedCaption.d.ts +4 -1
  265. package/dist-lib/ui/sound/mediaDirection.d.ts +35 -0
  266. package/dist-lib/ui/tabCompletion.d.ts +53 -0
  267. package/dist-lib/ui/textedit/TextEditManager.d.ts +11 -2
  268. package/dist-lib/ui/useOpenProfiles.d.ts +1 -1
  269. package/dist-lib/ui/video/VideoManager.d.ts +7 -0
  270. package/dist-lib/ui/windows/WindowManager.d.ts +452 -37
  271. package/dist-lib/ui/windows/panels/ScriptEditorPanel.d.ts +14 -0
  272. package/dist-lib/ui/windows/panels/ScriptSearch.d.ts +6 -1
  273. package/dist-lib/ui/windows/panels/TextPanel.d.ts +4 -1
  274. package/dist-lib/ui/windows/panels/VariablesView.d.ts +37 -7
  275. package/dist-lib/ui/windows/panels/WindowCmdLine.d.ts +4 -2
  276. package/dist-lib/ui/windows/panels/aliasLoop.d.ts +24 -0
  277. package/dist-lib/ui/windows/panels/editorClipboard.d.ts +45 -0
  278. package/dist-lib/ui/windows/panels/editorUndo.d.ts +79 -0
  279. package/dist-lib/ui/windows/panels/mapAreaChange.d.ts +10 -0
  280. package/dist-lib/utils/appShellCache.d.ts +25 -0
  281. package/dist-lib/utils/fontFamilyName.d.ts +13 -0
  282. package/dist-lib/utils/fontLoader.d.ts +31 -0
  283. package/dist-lib/utils/formatBytes.d.ts +4 -0
  284. package/dist-lib/utils/mustBeOneOf.d.ts +9 -0
  285. package/dist-lib/utils/profileLock.d.ts +1 -1
  286. package/dist-lib/utils/systemTheme.d.ts +24 -0
  287. package/dist-lib/utils/timeZone.d.ts +10 -0
  288. package/dist-lib/vault/CredentialVault.d.ts +51 -5
  289. package/dist-lib/vault/deviceUnlock.d.ts +47 -0
  290. package/dist-lib/vault/vaultAccess.d.ts +24 -2
  291. package/dist-lib/vault/vaultHelpTopic.d.ts +9 -0
  292. package/dist-lib/vault/vaultRecord.d.ts +33 -1
  293. package/dist-lib/vfs-sw.js +220 -11
  294. package/dist-lib/vite.d.ts +1 -1
  295. package/dist-lib/vite.js +66 -43
  296. package/package.json +23 -15
  297. package/dist-lib/assets/mapParser.worker-t-3rd1zR.js +0 -9
  298. package/dist-lib/mud/connection/PingTracker.d.ts +0 -41
  299. package/dist-lib/ui/BundledGameGrid.d.ts +0 -21
  300. package/dist-lib/ui/ConnectionGrid.d.ts +0 -21
  301. package/dist-lib/ui/bufferWords.d.ts +0 -38
@@ -0,0 +1,26 @@
1
+ import { type RefObject } from 'react';
2
+ /** Where a script left the command line's caret: at the end with nothing
3
+ * selected (printCmdLine, appendCmdLine), or around all of it
4
+ * (selectCmdLineText, sendCmdLine). */
5
+ export type CmdLineSelection = 'end' | 'all';
6
+ /**
7
+ * Place a command line's caret or selection once the text a script put there
8
+ * has actually reached the input.
9
+ *
10
+ * A script's printCmdLine only reaches the input through React state, so the
11
+ * new value lands on the next commit — and writing a controlled input's value
12
+ * moves its caret to the end, wiping any selection made before it. Applying
13
+ * the selection straight away (or from a microtask, which runs before a
14
+ * render scheduled from a timer) is how `printCmdLine("ghi");
15
+ * selectCmdLineText()` left nothing selected, so the next keystroke appended
16
+ * instead of replacing (issue #284). Desktop applies both to the widget
17
+ * synchronously, so the later call always wins; here the latest request is
18
+ * held and applied in a layout effect after the commit that carries the text.
19
+ *
20
+ * `value` is the input's controlled value. The returned function records a
21
+ * request and forces a render, so a request with no text change still lands.
22
+ * A script's request also focuses the input; `focus: false` is for the
23
+ * client's own selection after a send, which must not pull focus back to an
24
+ * input the send just let go of (a phone's keyboard).
25
+ */
26
+ export declare function useCmdLineSelection(inputRef: RefObject<HTMLInputElement | HTMLTextAreaElement | null>, value: string): (selection: CmdLineSelection | null, focus?: boolean) => void;
@@ -0,0 +1,33 @@
1
+ import { type MutableRefObject, type RefObject } from 'react';
2
+ import type React from 'react';
3
+ import type { CmdLineHost, SubCommandLine } from './subCommandLine';
4
+ interface Options {
5
+ model: SubCommandLine;
6
+ host: () => CmdLineHost;
7
+ inputRef: RefObject<HTMLTextAreaElement | null>;
8
+ /** The line's live text (what getCmdLine reads), kept current by the caller. */
9
+ valueRef: MutableRefObject<string>;
10
+ setValue: (text: string) => void;
11
+ /** Hand one command (one line of the box) to the action, or the game. */
12
+ dispatch: (command: string) => void;
13
+ /** The text a script put on this line (printCmdLine and the like) while
14
+ * the commands ran, marking it applied; null when none did. */
15
+ takeScripted: () => string | null;
16
+ }
17
+ /**
18
+ * Key handling for a named command line — the createCommandLine overlay and a
19
+ * miniconsole's / user window's own line — driving {@link SubCommandLine}, the
20
+ * port of desktop's TCommandLine. Returns the textarea's onKeyDown and
21
+ * onChange.
22
+ *
23
+ * The keys desktop's TCommandLine::event takes for itself are taken here too:
24
+ * Enter sends, Shift+Enter starts another line in the box, Up/Down walk the
25
+ * history, Tab and Shift+Tab complete, Escape selects everything. Only a Tab
26
+ * on an empty line, or after a space, is let through, as on the main command
27
+ * line, so the keyboard can still leave the box (WCAG 2.1.2).
28
+ */
29
+ export declare function useSubCommandLineKeys({ model, host, inputRef, valueRef, setValue, dispatch, takeScripted }: Options): {
30
+ onKeyDown: (e: React.KeyboardEvent<HTMLTextAreaElement>) => void;
31
+ onChange: (e: React.ChangeEvent<HTMLTextAreaElement>) => void;
32
+ };
33
+ export {};
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Mudlet's Editor option "Show Line/Paragraphs", as the checkbox is named:
3
+ * a visible mark where each line of the script ends.
4
+ *
5
+ * Desktop currently under-delivers on its own label. `slot_changeShowLineFeeds\
6
+ * AndParagraphs` (dlgProfilePreferences.cpp:4073) sets edbee's
7
+ * `useLineSeparator`, which rules a faint horizontal line under each row, and
8
+ * the method's comment says so: the marks the option is named for "may in the
9
+ * future" arrive. The tooltip in `profile_preferences.ui:1746` still promises
10
+ * them — "show line and paragraph ends with visible marks as well as
11
+ * whitespace" — so that is what this draws, next to `highlightWhitespace()`'s
12
+ * dots and arrows, which is where the tooltip puts it.
13
+ *
14
+ * CodeMirror has no built-in for this (`highlightWhitespace` covers spaces and
15
+ * tabs only), so it is a decoration: a zero-width widget at every line end,
16
+ * with the last line marked differently because it has no line feed after it.
17
+ */
18
+ /** The extension behind the "Show Line/Paragraphs" toggle. */
19
+ export declare function showLineParagraphs(): import("@codemirror/state").Extension[];
@@ -0,0 +1,7 @@
1
+ export declare const luaHoverTheme: import("@codemirror/state").Extension;
2
+ /** Signature + description for the Mudlet function under the pointer. Shared by
3
+ * the script editor and by a `.lua` file opened from the file browser — the
4
+ * same code deserves the same tooltip whichever door you came in through. */
5
+ export declare const luaHover: import("@codemirror/state").Extension & {
6
+ active: import("@codemirror/state").StateField<readonly import("@codemirror/view").Tooltip[]>;
7
+ };
@@ -0,0 +1,33 @@
1
+ import { Compartment, type Extension } from '@codemirror/state';
2
+ /** Mudlet's Editor preference page, which Mudlet Web had no equivalent of: the
3
+ * display options and autocomplete were hard-coded on. Held in a compartment
4
+ * so a change reconfigures the live editor instead of remounting it, which is
5
+ * what the theme swap alongside it already does.
6
+ *
7
+ * Every CodeMirror surface in the app shares these — the script editor and
8
+ * the file browser's editor and JSON viewer. "Show Spaces/Tabs" that only
9
+ * applied to one of the three would be a setting you have to remember the
10
+ * scope of; `useEditorSettings()` is the single source for all of them. */
11
+ export interface EditorOptions {
12
+ /** "Autocomplete Lua functions in code editor". */
13
+ autocomplete: boolean;
14
+ /** "Show Spaces/Tabs" — dots for runs of spaces, arrows for tabs. */
15
+ showWhitespace: boolean;
16
+ /** "Show Line/Paragraphs" — a ¶ where each line ends. */
17
+ showLineParagraphs: boolean;
18
+ /** "Show invisible Unicode control characters". */
19
+ showControlChars: boolean;
20
+ /** "Theme" — the editor palette, pinned or following the app's. */
21
+ theme: 'app' | 'dark' | 'light';
22
+ }
23
+ export declare const EDITOR_OPTION_DEFAULTS: EditorOptions;
24
+ export declare const optionsCompartment: Compartment;
25
+ /**
26
+ * The display options as extensions.
27
+ *
28
+ * @param lua whether to offer Lua completion — true for the script editor and
29
+ * for a `.lua` file opened from the file browser, false for the
30
+ * JSON, XML and plain-text documents the same editor also serves,
31
+ * where Mudlet's function list is noise.
32
+ */
33
+ export declare function optionExtensions(opts: EditorOptions, lua: boolean): Extension[];
@@ -1,5 +1,29 @@
1
- import { Compartment } from '@codemirror/state';
2
- import { syntaxHighlighting } from '@codemirror/language';
3
- export declare const mudixCmTheme: import("@codemirror/state").Extension;
4
- export declare const highlightCompartment: Compartment;
5
- export declare function highlightFor(theme: string): ReturnType<typeof syntaxHighlighting>;
1
+ import { Compartment, type Extension } from '@codemirror/state';
2
+ export declare const mudletCmTheme: Extension;
3
+ export declare const paletteCompartment: Compartment;
4
+ /**
5
+ * Mudlet's Editor → Theme, as far as it makes sense here. Desktop downloads a
6
+ * catalogue from colorsublime; Mudlet Web ships the two palettes it already has and
7
+ * lets you pin one, which is the part of that feature people actually use — a
8
+ * dark editor under a light app theme, or the reverse.
9
+ *
10
+ * `app` is the default and keeps the old behaviour exactly.
11
+ */
12
+ export type EditorTheme = 'app' | 'dark' | 'light';
13
+ export declare const EDITOR_THEME_CHOICES: {
14
+ value: EditorTheme;
15
+ label: string;
16
+ }[];
17
+ /**
18
+ * The whole palette for one editor: syntax colours, plus — when the theme is
19
+ * pinned — the chrome that goes with them.
20
+ *
21
+ * Pinning means pinning: "Atom One Light" under a dark app theme is a light
22
+ * editor, background and all, not light syntax colours floating on a black
23
+ * page. `'app'` returns highlighting alone and leaves the chrome on whatever
24
+ * CSS vars the document carries, which is also what keeps a brand theme's own
25
+ * surface colours from being flattened into the stock two.
26
+ *
27
+ * @param theme the app theme, consulted only when `editorTheme` is 'app'.
28
+ */
29
+ export declare function paletteFor(theme: string, editorTheme?: EditorTheme): Extension;
@@ -0,0 +1,134 @@
1
+ /**
2
+ * Mudlet's addon command API — the commands a package places on the client's
3
+ * own surfaces (`addCommand`, `removeCommand`, `enableCommand`, …).
4
+ *
5
+ * This holds the state and the answers; the argument contract in front of it
6
+ * lives in Bridge.lua, because the refusals name the Lua type of what they were
7
+ * given ("surfaces has to be a list of surface names and this one holds a
8
+ * boolean") and a value's Lua type is exactly what does not survive the trip
9
+ * across wasmoon.
10
+ *
11
+ * What "reserved" means here is worth being straight about. On desktop Mudlet
12
+ * answers "is this key free?" by asking Qt what is currently wired to the
13
+ * window. There is no widget tree to ask in a browser tab, so the keys Mudlet
14
+ * itself holds are written down below instead — a mirror of another
15
+ * application's keyboard map, and it will need revisiting when Mudlet moves a
16
+ * shortcut. The alternative was to reserve nothing, which is technically true
17
+ * of a client with no menu bar and useless to a package author: a shortcut
18
+ * accepted here and refused on desktop is a bug report either way, and the
19
+ * quiet version (Qt disables BOTH bindings when two things claim one key) is
20
+ * the worse of the two to debug.
21
+ */
22
+ /** Where a command can be placed. Absent means both, never neither. */
23
+ export type CommandSurface = 'menu' | 'toolbar' | 'both';
24
+ export interface AddonCommand {
25
+ id: number;
26
+ name: string;
27
+ icon: string;
28
+ tooltip: string;
29
+ menuPath: string;
30
+ shortcut: string;
31
+ surfaces: CommandSurface;
32
+ enabled: boolean;
33
+ checked: boolean;
34
+ /** Mudlet shows a pinned command in every profile's window, not just its
35
+ * own. A page here holds one profile, so this is kept and reported but
36
+ * there is no second window for it to appear in. */
37
+ pinned: boolean;
38
+ pulse: {
39
+ colour: string;
40
+ altColour: string;
41
+ intervalMs: number;
42
+ } | null;
43
+ /** The package or module whose code placed it, or '' for the profile's. */
44
+ owner: string;
45
+ }
46
+ /** A request as Bridge.lua hands it over, already type-checked there. */
47
+ export interface CommandRequest {
48
+ name: string;
49
+ icon?: string;
50
+ tooltip?: string;
51
+ menuPath?: string;
52
+ shortcut?: string;
53
+ surfaces?: CommandSurface;
54
+ owner?: string;
55
+ }
56
+ /** Qt's QKeySequence holds four steps and silently drops the rest, so a longer
57
+ * sequence binds a key nobody asked for. */
58
+ export declare const MAX_SHORTCUT_STEPS = 4;
59
+ /** Normalised for comparison only — case and spacing carry no meaning in a Qt
60
+ * key sequence, so "Ctrl+Alt+L" and "ctrl+alt+l" are one key. */
61
+ export declare function normaliseShortcut(shortcut: string): string;
62
+ export declare class AddonCommandRegistry {
63
+ private readonly commands;
64
+ /** Monotonic and never reused: an id that has been removed must answer as
65
+ * unknown for good, not come back as a different command. */
66
+ private nextId;
67
+ private listeners;
68
+ /** Whether the buffer search currently holds its key. Pushed in rather than
69
+ * read out, so this file needs no store dependency. */
70
+ private searchActive;
71
+ /** Which platform's key map Mudlet would be answering from. Pushed in for
72
+ * the same reason. */
73
+ private reserved;
74
+ /**
75
+ * What the client's own commands hold right now, normalised key → the name
76
+ * to quote back. Separate from `reserved` because that one is a mirror of
77
+ * Mudlet's fixed map, while these move: the player can rebind any of them
78
+ * (see `appShortcuts.ts`), and a package asking about the key they moved it
79
+ * TO deserves the truth rather than "free".
80
+ */
81
+ private clientKeys;
82
+ setPlatform(platform: string): void;
83
+ /** Told by the UI whenever the client's own bindings change: normalised key
84
+ * → the command's name. */
85
+ setClientShortcuts(keys: ReadonlyMap<string, string>): void;
86
+ subscribe(fn: () => void): () => void;
87
+ private notify;
88
+ list(): AddonCommand[];
89
+ get(id: number): AddonCommand | undefined;
90
+ /**
91
+ * Who holds `shortcut`, or null when it is free. `null` for an empty
92
+ * shortcut too — asking for no key is not a clash.
93
+ *
94
+ * A command of THIS profile is named outright; Mudlet's own keys answer
95
+ * with the reserved name. The spec tells the two apart deliberately: a
96
+ * package author can fix a clash with their own command, and needs to know
97
+ * when they cannot.
98
+ */
99
+ holderOf(shortcut: string, ignoreId?: number): string | null;
100
+ /** Commands currently on `shortcut` — what the buffer search needs to know
101
+ * before it takes its key back. */
102
+ commandsOn(shortcut: string): AddonCommand[];
103
+ get searchHoldsItsKey(): boolean;
104
+ get searchShortcut(): string;
105
+ /** Told by the config layer, because the search is a preference rather than
106
+ * anything this registry owns. */
107
+ setSearchActive(active: boolean): void;
108
+ add(request: CommandRequest): number;
109
+ remove(id: number): boolean;
110
+ /** Take away every command the package or module `owner`'s code placed —
111
+ * once it is gone nothing knows their ids, and left behind they would
112
+ * stay on screen and hold their shortcuts against its own reinstall. */
113
+ removeOwnedBy(owner: string): void;
114
+ setEnabled(id: number, enabled: boolean): boolean;
115
+ setChecked(id: number, checked: boolean): boolean;
116
+ setPinned(id: number, pinned: boolean): boolean;
117
+ setIcon(id: number, icon: string): boolean;
118
+ setTooltip(id: number, tooltip: string): boolean;
119
+ setPulse(id: number, pulse: AddonCommand['pulse']): boolean;
120
+ /** Whether the command has a button to colour — the pulse needs one, and a
121
+ * menu-only command has none. */
122
+ hasButton(id: number): boolean;
123
+ private mutate;
124
+ /** The commands with a button, in placement order — what the toolbar draws.
125
+ * A disabled command keeps its button and is drawn unavailable, which is
126
+ * what enableCommand/disableCommand are for; a removed one is gone. */
127
+ buttons(): AddonCommand[];
128
+ /** The commands with a menu entry, in placement order — what the menu bar
129
+ * draws. Same rule as `buttons()`: a disabled one keeps its entry and is
130
+ * drawn unavailable, and only a removed one is gone. */
131
+ menuItems(): AddonCommand[];
132
+ /** Profile teardown. */
133
+ clear(): void;
134
+ }
@@ -0,0 +1,86 @@
1
+ /**
2
+ * The client's own keyboard shortcuts — Mudlet's menu accelerators, and the
3
+ * handful of things this client has that Mudlet does not.
4
+ *
5
+ * Mudlet's are fixed, compiled into the menu actions. These are defaults: the
6
+ * settings dialog can move any of them, and the stored override is what the
7
+ * dispatcher and the menu labels both read. That is the one place this
8
+ * deliberately goes further than Mudlet — in a browser a shortcut can collide
9
+ * with something the browser or an extension already holds, and a player who
10
+ * cannot reach the script editor because Alt+E is spoken for has no recourse
11
+ * unless the binding moves.
12
+ *
13
+ * The keys themselves are Mudlet's, including the platform split: the menu
14
+ * group is Alt on Windows and Linux and Ctrl on macOS (mudlet.cpp:1462-1512),
15
+ * where Alt is a text-entry modifier. Commands Mudlet has no key for start
16
+ * unbound rather than being given one this client invented — a player who wants
17
+ * one can say so, and a default that disagreed with Mudlet's would be a trap
18
+ * for anyone who uses both.
19
+ *
20
+ * Mudlet's profile-switching keys (Ctrl+1…9, Ctrl+Tab) are absent by design:
21
+ * multiple profiles here are multiple browser tabs, and the browser owns those
22
+ * keys. `addonCommands.ts` still reserves them against packages, because a
23
+ * package written for desktop Mudlet will expect them to be taken.
24
+ */
25
+ import { type StockToolbarButton } from '../../branding';
26
+ /** Everything the client can be asked to do from the keyboard. */
27
+ export type AppCommandId = 'connect' | 'disconnect' | 'reconnect' | 'closeProfile' | 'scriptEditor' | 'map' | 'notepad' | 'files' | 'logs' | 'toggleReplay' | 'preferences' | 'toggleTimestamps' | 'mute' | 'toggleLogging' | 'fullscreen' | 'toggleButtonBar' | 'inputLine' | 'docs' | 'help' | 'about';
28
+ export interface AppShortcutDef {
29
+ id: AppCommandId;
30
+ label: string;
31
+ /**
32
+ * The stock button this command belongs to, where it has one. A brand that
33
+ * hid the button has removed the feature, so the shortcut goes with it —
34
+ * both the binding and its row in the settings. A key that still opened the
35
+ * script editor after the brand took the script editor away would be a back
36
+ * door into something they deliberately removed.
37
+ */
38
+ stock?: StockToolbarButton;
39
+ /** The menu this command lives in, so the settings list is grouped the way
40
+ * the menu bar is rather than as one flat run of nineteen rows. */
41
+ group: 'Games' | 'Toolbox' | 'Options' | 'Window' | 'Help';
42
+ /** Mudlet's key on Windows and Linux, and on macOS. Empty on both where
43
+ * Mudlet has no key for it. */
44
+ defaultKey: string;
45
+ defaultKeyMac: string;
46
+ }
47
+ /** Mudlet's menu group: Alt+<letter> on Windows and Linux, Ctrl+<letter> on
48
+ * macOS. Written out rather than generated so each entry is greppable. */
49
+ export declare const APP_SHORTCUTS: readonly AppShortcutDef[];
50
+ /**
51
+ * The commands this build actually exposes.
52
+ *
53
+ * A brand that hid a stock button removed the feature, and a shortcut is
54
+ * another door onto the same room — so the binding goes with the button, and so
55
+ * does its row in the settings. Otherwise a white-label client that took the
56
+ * script editor away would still open it on Alt+E, and offer to rebind it.
57
+ *
58
+ * Commands with no `stock` id (timestamps, logging, fullscreen, the bars, the
59
+ * command line, About) belong to no button and are always available.
60
+ */
61
+ export declare function availableShortcuts(): readonly AppShortcutDef[];
62
+ /** The order the settings list draws the groups in — the menu bar's own. */
63
+ export declare const SHORTCUT_GROUPS: readonly AppShortcutDef['group'][];
64
+ /** Which key map this machine gets, in the same spelling `getOS()` uses so the
65
+ * addon-command registry and this agree on what "mac" means. */
66
+ export declare function shortcutPlatform(): string;
67
+ /** What the client would use with nothing overridden. `platform` is what
68
+ * `getOS()` reports: 'mac' picks Mudlet's macOS key. */
69
+ export declare function defaultShortcut(def: AppShortcutDef, platform: string): string;
70
+ /** What a stored override means. A key that is present and empty is a binding
71
+ * the player deliberately cleared, which is not the same as never having
72
+ * touched it — clearing has to survive a default changing under them. */
73
+ export type ShortcutOverrides = Readonly<Record<string, string>>;
74
+ /** The key actually in force for `def`. */
75
+ export declare function effectiveShortcut(def: AppShortcutDef, overrides: ShortcutOverrides | undefined, platform: string): string;
76
+ /** A reader for one command's key, for the menu entries that draw it beside
77
+ * their label. Undefined rather than empty for an unbound command, so a menu
78
+ * entry can leave the column blank rather than drawing nothing-in-particular. */
79
+ export declare function shortcutLookup(overrides: ShortcutOverrides | undefined, platform: string): (id: AppCommandId) => string | undefined;
80
+ /** Every command with a key, as `{id, label, shortcut}`. Commands with no key
81
+ * are left out — there is nothing to dispatch or to warn about. */
82
+ export declare function boundShortcuts(overrides: ShortcutOverrides | undefined, platform: string): {
83
+ id: AppCommandId;
84
+ label: string;
85
+ shortcut: string;
86
+ }[];
@@ -0,0 +1,88 @@
1
+ /**
2
+ * `addCommand` for the application embedding this client.
3
+ *
4
+ * A package written in Lua can already place a command on the toolbar and the
5
+ * menu bar and change it afterwards. A white-label host had no equivalent: it
6
+ * could declare buttons in its `BrandConfig` at boot and nothing after, so a
7
+ * command that appears when the player logs in, or greys out while a request is
8
+ * in flight, meant re-rendering the whole client with a new brand object.
9
+ *
10
+ * This is the same contract from JavaScript. It is a module-level singleton
11
+ * rather than a React context on purpose — a host app's command usually lives
12
+ * next to the state that decides whether it should be there, which is rarely a
13
+ * component inside the client's tree.
14
+ *
15
+ * Ids are strings and never reused, so a removed command's id answers as
16
+ * unknown for good rather than coming back as something else.
17
+ */
18
+ import type { ReactNode } from 'react';
19
+ import type { BrandToolbarContext } from '../../branding';
20
+ import type { CommandSurface } from './addonCommands';
21
+ export interface HostCommandRequest {
22
+ /** The caller's own id, if it wants one — `commands.remove('roll')` then
23
+ * works without holding on to what `add` returned. Absent gets a generated
24
+ * one. Placing a second command under an id that is taken replaces it. */
25
+ id?: string;
26
+ /** Shown on the button and the menu entry. */
27
+ name: string;
28
+ /** An image URL, or any node — an inline SVG needs no round trip through a
29
+ * file. Sized to the text by the stylesheet either way. */
30
+ icon?: ReactNode;
31
+ tooltip?: string;
32
+ /** Where on the menu bar: '/'-separated, the first segment naming a
33
+ * top-level menu (an existing title joins it, a new one opens a menu at
34
+ * the end of the bar). Absent puts it among the other package tools. */
35
+ menuPath?: string;
36
+ /** Qt-style key sequence, e.g. "Ctrl+Alt+K". */
37
+ shortcut?: string;
38
+ /** Which bars it appears on. Absent means both. */
39
+ surfaces?: CommandSurface;
40
+ enabled?: boolean;
41
+ checked?: boolean;
42
+ /**
43
+ * Run when the command is picked. The context is the same one brand
44
+ * toolbar buttons get: `send` a command as if typed, `raiseEvent` for the
45
+ * profile's Lua handlers, and the open profile's id.
46
+ *
47
+ * Called with null when no profile is open — a command can be placed before
48
+ * the player has picked one, and refusing to fire silently would be worse
49
+ * than letting the host decide.
50
+ */
51
+ onClick: (ctx: BrandToolbarContext | null) => void;
52
+ }
53
+ export interface HostCommand extends HostCommandRequest {
54
+ id: string;
55
+ surfaces: CommandSurface;
56
+ enabled: boolean;
57
+ checked: boolean;
58
+ }
59
+ export declare class HostCommandRegistry {
60
+ private readonly commands;
61
+ private next;
62
+ private readonly listeners;
63
+ /** The snapshot handed to React. Rebuilt on change rather than on read, so
64
+ * `useSyncExternalStore` sees a stable reference between changes and does
65
+ * not re-render on every commit. */
66
+ private snapshot;
67
+ subscribe: (fn: () => void) => (() => void);
68
+ /** Every placed command, in placement order — which is drawing order. */
69
+ list: () => readonly HostCommand[];
70
+ private changed;
71
+ /** Place a command. Returns its id, for everything below. */
72
+ add(request: HostCommandRequest): string;
73
+ /** False for an id nobody knows, rather than throwing — one sequence covers
74
+ * every command, so an unknown id names nothing at all. */
75
+ remove(id: string): boolean;
76
+ /** Change anything about a placed command except its id. */
77
+ update(id: string, patch: Partial<HostCommandRequest>): boolean;
78
+ setEnabled(id: string, enabled: boolean): boolean;
79
+ setChecked(id: string, checked: boolean): boolean;
80
+ setIcon(id: string, icon: string): boolean;
81
+ setTooltip(id: string, tooltip: string): boolean;
82
+ /** Drop everything. For a host tearing its own UI down; the client never
83
+ * calls this, since these commands outlive any one profile. */
84
+ clear(): void;
85
+ }
86
+ /** The one registry the client reads. Exported from the package root as
87
+ * `commands`. */
88
+ export declare const hostCommands: HostCommandRegistry;
@@ -0,0 +1,20 @@
1
+ /**
2
+ * One step in its canonical spelling: modifiers in a fixed order, lower case,
3
+ * joined to the key by '+'. "Ctrl+Alt+L", "alt+ctrl+l" and "CTRL+ALT+L" all
4
+ * become "ctrl+alt+l".
5
+ */
6
+ export declare function canonicalStep(step: string): string;
7
+ /** A whole sequence as canonical steps, or null when Qt could not read it. */
8
+ export declare function canonicalSequence(shortcut: string): string[] | null;
9
+ /** The key half of a step, from a physical key code. Null for a modifier key
10
+ * pressed on its own — holding Ctrl is not yet a shortcut. */
11
+ export declare function keyNameFromCode(code: string): string | null;
12
+ /** A keypress in the same spelling as `canonicalStep`, or null when it is not
13
+ * a key a shortcut can be built from. */
14
+ export declare function stepFromEvent(e: Pick<KeyboardEvent, 'code' | 'ctrlKey' | 'altKey' | 'shiftKey' | 'metaKey'>): string | null;
15
+ /** Whether a step carries a modifier. A bare key is not safe to dispatch while
16
+ * the player is typing into something. */
17
+ export declare function stepHasModifier(step: string): boolean;
18
+ /** Written the way a person reads it: "Ctrl+Alt+L", "Alt+E", "F3". Steps in a
19
+ * multi-step sequence are joined with ", " as Qt writes them. */
20
+ export declare function formatSequence(steps: readonly string[]): string;
@@ -0,0 +1,57 @@
1
+ /**
2
+ * Qt key-sequence parsing, as much of it as deciding whether to accept a
3
+ * package's shortcut needs.
4
+ *
5
+ * Counting the steps in "Ctrl+Alt+F1, Ctrl+Alt+F2" looks like splitting on
6
+ * commas until you meet the two characters that are both punctuation AND keys:
7
+ *
8
+ * "Ctrl+," the comma key. One step, not two of nothing.
9
+ * "Ctrl++" the plus key. One step whose last character is the same
10
+ * one that joins a modifier to its key.
11
+ * "Ctrl+,, X" the comma key, then a separator, then X. Two steps.
12
+ * "Ctrl++, X" the plus key, then a separator, then X. Two steps — and
13
+ * the reading that looks at what precedes the comma calls
14
+ * this one, which is how a five-step sequence slipped past
15
+ * the length check to be truncated by Qt after all.
16
+ *
17
+ * So this parses rather than splits: each step is its modifiers, then exactly
18
+ * one key, and only a comma that follows a completed key is a separator. Qt
19
+ * steps over that separator and the single space after it, which is why a
20
+ * sequence written with a trailing one — what generating a list in a loop
21
+ * produces — is the steps it names and not one more of nothing.
22
+ */
23
+ /** Qt's QKeySequence holds this many steps and silently drops the rest. */
24
+ export declare const MAX_STEPS = 4;
25
+ export interface SequenceProblem {
26
+ /** 'length' when the sequence has more steps than Qt can hold, 'key' when a
27
+ * step names something Qt cannot read. */
28
+ kind: 'length' | 'key';
29
+ /** The unreadable chunk, for a 'key' problem. */
30
+ chunk?: string;
31
+ }
32
+ /**
33
+ * The steps in a Qt key sequence, or a problem describing why it is not one.
34
+ * An empty (or whitespace-only) shortcut is no shortcut at all and parses to
35
+ * zero steps, which is not an error — a command may simply have no key.
36
+ */
37
+ export declare function parseKeySequence(shortcut: string): {
38
+ steps: string[];
39
+ } | {
40
+ problem: SequenceProblem;
41
+ };
42
+ /**
43
+ * A shortcut as a key binding would hold it: one DOM `KeyboardEvent.code` plus
44
+ * the modifiers pressed with it.
45
+ *
46
+ * Null for anything a binding cannot be: a sequence of more than one step (a
47
+ * binding is one key and its modifiers, so a two-step sequence can never be the
48
+ * one holding it — as `mudlet::addonShortcutUsable` decides with
49
+ * `sequence.count() == 1`), an empty shortcut, or a key the browser has no code
50
+ * for.
51
+ */
52
+ export declare function shortcutAsBinding(shortcut: string): {
53
+ code: string;
54
+ modifiers: string[];
55
+ } | null;
56
+ /** The refusal a package should read, or null when the sequence is fine. */
57
+ export declare function shortcutProblemMessage(shortcut: string): string | null;
@@ -3,7 +3,27 @@ interface ContextMenuProps {
3
3
  x: number;
4
4
  y: number;
5
5
  onClose: () => void;
6
+ /** Accessible name for the menu, e.g. "Output actions". */
7
+ label?: string;
8
+ /** Override for popups that are not lists of commands — the script editor's
9
+ * colour picker is a grid of swatches, and calling that a menu when it holds
10
+ * no menuitem misdescribes it. */
11
+ role?: 'menu' | 'group';
12
+ /** Where to hand focus back on close, when that is not the element the menu
13
+ * was opened from. The output console needs this: a right-click focuses the
14
+ * console (it is a tab stop), but the player types into the command line, so
15
+ * returning focus to the opener would send their next keystroke nowhere. */
16
+ returnFocusTo?: () => HTMLElement | null | undefined;
17
+ /** Extra class on the menu box, for a screen that styles its menus to
18
+ * match its own layout (the launcher's are larger than the app's). */
19
+ className?: string;
6
20
  children: React.ReactNode;
7
21
  }
8
- export declare function ContextMenu({ x, y, onClose, children }: ContextMenuProps): import("react").ReactPortal;
22
+ /**
23
+ * Where an arrow/Home/End press should move within a menu of `count` entries,
24
+ * given the currently focused index (-1 when focus is outside). Returns null for
25
+ * keys the menu doesn't handle. Wraps at both ends. Pure — exported for testing.
26
+ */
27
+ export declare function nextMenuIndex(count: number, current: number, key: string): number | null;
28
+ export declare function ContextMenu({ x, y, onClose, label, role, returnFocusTo, className, children }: ContextMenuProps): import("react").ReactPortal;
9
29
  export {};
@@ -4,6 +4,10 @@ interface FontPickerProps {
4
4
  value: OutputFontSource | undefined;
5
5
  onChange: (next: OutputFontSource | undefined) => void;
6
6
  vfs: ProfileVFS | null;
7
+ /** What is drawn with when nothing is chosen. The main display falls back to
8
+ * the browser's monospace; the map's room symbols to the bundled Bitstream
9
+ * Vera Sans Mono — so the picker has to be told, rather than assert one. */
10
+ fallbackLabel?: string;
7
11
  }
8
- export declare function FontPicker({ value, onChange, vfs }: FontPickerProps): import("react/jsx-runtime").JSX.Element;
12
+ export declare function FontPicker({ value, onChange, vfs, fallbackLabel }: FontPickerProps): import("react/jsx-runtime").JSX.Element;
9
13
  export {};
@@ -12,8 +12,20 @@ export interface ModalFocusOptions {
12
12
  * modal manages its own initial focus (e.g. a specific field or button). */
13
13
  autoFocus?: boolean;
14
14
  /** Close on Escape via `onClose`. Default true. Set false when the modal has
15
- * its own Escape handling (then `onClose` may be omitted). */
15
+ * its own Escape handling (then `onClose` may be omitted). Read live on
16
+ * every key, so it may vary over the dialog's life — a dialog can hand
17
+ * Escape to an inner editor for exactly as long as that editor is open
18
+ * (the file browser's inline rename does) without the trap being torn
19
+ * down and re-armed, which would re-grab focus. */
16
20
  closeOnEscape?: boolean;
21
+ /** Gate for a dialog whose node is not in the DOM on the first render — a
22
+ * portal whose container is only known after a layout effect, say. The
23
+ * setup below runs once, off a null ref, and refs don't re-render, so
24
+ * without this the trap, the Escape handler and the focus restore are all
25
+ * silently skipped (issue #49). Flip it true in the render that mounts the
26
+ * dialog node. One-way: flipping it back to false counts as a close and
27
+ * restores focus to the opener. Default true (node present immediately). */
28
+ ready?: boolean;
17
29
  /** Where focus should land on close, instead of the opener. Use when the
18
30
  * dialog was raised by the game rather than by a click, so "the opener" is
19
31
  * either nothing or a control that has since gone away — the GMCP login
@@ -11,6 +11,21 @@ export interface HelpTopic {
11
11
  }
12
12
  export declare const HELP_TOPICS: HelpTopic[];
13
13
  export declare const DEFAULT_HELP_TOPIC: string;
14
+ /**
15
+ * Add a topic that only some builds have.
16
+ *
17
+ * The manual is otherwise a fixed list, but a few features are stock-app-only —
18
+ * the credential vault above all — and a branded build must not carry
19
+ * documentation for something it doesn't ship. Those topics are registered from
20
+ * `main.tsx` at boot, alongside the feature itself, so they never enter the
21
+ * library's module graph. See `vault/vaultAccess` for the same seam.
22
+ *
23
+ * Idempotent, and ordered by `after` rather than appended, so an added topic
24
+ * lands next to the one it relates to instead of at the bottom.
25
+ */
26
+ export declare function registerHelpTopic(topic: HelpTopic, opts?: {
27
+ after?: string;
28
+ }): void;
14
29
  /** Resolve a markdown link href to a topic id, or null if it isn't one of ours.
15
30
  * Handles `./storage.md`, `storage.md`, `docs/help/storage.md` and a `#anchor`
16
31
  * suffix — the shapes a relative link between these files can take. */