flea-qml 0.0.0-stage → 0.2.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 (637) hide show
  1. package/LICENSE +22 -0
  2. package/README.md +511 -2
  3. package/THIRD-PARTY-NOTICES.md +29 -0
  4. package/demos/App.java +5 -0
  5. package/demos/Dockerfile +4 -0
  6. package/demos/Main.kt +3 -0
  7. package/demos/Program.cs +1 -0
  8. package/demos/README.md +12 -0
  9. package/demos/app.dart +3 -0
  10. package/demos/app.deb +0 -0
  11. package/demos/app.js +1 -0
  12. package/demos/backup.tar +0 -0
  13. package/demos/budget.xlsx +0 -0
  14. package/demos/build.sh +2 -0
  15. package/demos/bundle.zip +0 -0
  16. package/demos/clip.mp4 +0 -0
  17. package/demos/data.sqlite +0 -0
  18. package/demos/disk.iso +0 -0
  19. package/demos/engine.cpp +5 -0
  20. package/demos/firmware.bin +0 -0
  21. package/demos/flake.nix +4 -0
  22. package/demos/folder/inside.txt +1 -0
  23. package/demos/font.ttf +0 -0
  24. package/demos/index.html +5 -0
  25. package/demos/index.php +2 -0
  26. package/demos/init.lua +1 -0
  27. package/demos/letter.docx +0 -0
  28. package/demos/lib.rs +3 -0
  29. package/demos/main.c +6 -0
  30. package/demos/main.h +3 -0
  31. package/demos/math-and-diagrams.md +200 -0
  32. package/demos/notes.tar.gz +0 -0
  33. package/demos/notes.txt +3 -0
  34. package/demos/photo.png +0 -0
  35. package/demos/program +2 -0
  36. package/demos/report.pdf +32 -0
  37. package/demos/script.py +1 -0
  38. package/demos/server.go +7 -0
  39. package/demos/settings.json +4 -0
  40. package/demos/slides.pptx +0 -0
  41. package/demos/song.mp3 +0 -0
  42. package/demos/style.css +4 -0
  43. package/demos/tool.rb +1 -0
  44. package/demos/types.ts +2 -0
  45. package/docs/pele.md +23 -0
  46. package/docs/protocol.md +3420 -0
  47. package/docs/temml.md +63 -0
  48. package/index.js +107 -0
  49. package/package.json +34 -4
  50. package/src/archive.js +407 -0
  51. package/src/archiveops.js +728 -0
  52. package/src/backend.js +369 -0
  53. package/src/bulkrename.js +95 -0
  54. package/src/clip-host.js +76 -0
  55. package/src/clip.js +462 -0
  56. package/src/code.js +168 -0
  57. package/src/compare.js +74 -0
  58. package/src/create.js +128 -0
  59. package/src/dirsize.js +147 -0
  60. package/src/figure-svg.js +530 -0
  61. package/src/figure-thread.js +23 -0
  62. package/src/figure.js +132 -0
  63. package/src/find.js +55 -0
  64. package/src/flea.js +39 -0
  65. package/src/fsinfo.js +39 -0
  66. package/src/highlight.js +141 -0
  67. package/src/html.js +52 -0
  68. package/src/kinds.js +89 -0
  69. package/src/listing.js +130 -0
  70. package/src/markdown-html.js +317 -0
  71. package/src/mathml.js +186 -0
  72. package/src/menu.js +180 -0
  73. package/src/meta.js +135 -0
  74. package/src/office.js +810 -0
  75. package/src/order.js +100 -0
  76. package/src/peek.js +49 -0
  77. package/src/pele-wrapper.js +695 -0
  78. package/src/permissions.js +180 -0
  79. package/src/places.js +313 -0
  80. package/src/preview-language.js +10 -0
  81. package/src/terminal-server.js +95 -0
  82. package/src/terminal-shell.js +26 -0
  83. package/src/transfer.js +669 -0
  84. package/src/trash-record.js +41 -0
  85. package/src/trash.js +210 -0
  86. package/src/trashbrowse.js +327 -0
  87. package/src/uistate.js +393 -0
  88. package/src/uistore.js +168 -0
  89. package/src/vendor/LICENSES/Apache-2.0.txt +202 -0
  90. package/src/vendor/LICENSES/MIT-katex-2015.txt +27 -0
  91. package/src/vendor/LICENSES/MIT-katex.txt +21 -0
  92. package/src/vendor/LICENSES/MIT-mermaid.txt +21 -0
  93. package/src/vendor/LICENSES/MIT-pele.txt +40 -0
  94. package/src/vendor/LICENSES/MIT-perseus.txt +18 -0
  95. package/src/vendor/LICENSES/MIT-temml.txt +21 -0
  96. package/src/vendor/pele.js +145 -0
  97. package/src/vendor/temml.mjs +14708 -0
  98. package/src/watch.js +98 -0
  99. package/src/wayland/client.js +109 -0
  100. package/src/wayland/protocol.js +55 -0
  101. package/src/wayland/protocols/ext-data-control-v1.xml +276 -0
  102. package/src/wayland/protocols/wayland.xml +3248 -0
  103. package/src/wayland/protocols/wlr-data-control-unstable-v1.xml +278 -0
  104. package/src/wayland/resource-io.js +6 -0
  105. package/src/wayland/socket-discovery.js +26 -0
  106. package/src/wayland/transport-posix.js +120 -0
  107. package/src/wayland/transport-win32.js +11 -0
  108. package/src/wayland/transport.js +3 -0
  109. package/src/wayland/win32-resources.js +80 -0
  110. package/src/wayland/win32-wire.js +62 -0
  111. package/test/archive.test.js +80 -0
  112. package/test/bench-markdown-scroll.mjs +190 -0
  113. package/test/clip-host.test.js +113 -0
  114. package/test/code-preview.test.js +35 -0
  115. package/test/compare-ui-paths.test.js +24 -0
  116. package/test/compare.test.js +54 -0
  117. package/test/delete-trash.test.js +67 -0
  118. package/test/dirsize.test.js +138 -0
  119. package/test/file-ops.test.js +307 -0
  120. package/test/file-url.test.js +24 -0
  121. package/test/find-contents.test.js +161 -0
  122. package/test/find-input.test.js +66 -0
  123. package/test/fixtures/pele-parity.json +1006 -0
  124. package/test/highlight-launcher.test.js +35 -0
  125. package/test/html-preview.test.js +22 -0
  126. package/test/input.test.js +15 -0
  127. package/test/keymap.test.js +26 -0
  128. package/test/language-icons.test.js +36 -0
  129. package/test/launcher.test.js +51 -0
  130. package/test/manual-archive-here-ui.mjs +47 -0
  131. package/test/manual-code-scroll.mjs +28 -0
  132. package/test/manual-column-scroll.mjs +24 -0
  133. package/test/manual-compare-ui.mjs +20 -0
  134. package/test/manual-find-status.mjs +37 -0
  135. package/test/manual-folder-focus.mjs +63 -0
  136. package/test/manual-html-security.mjs +23 -0
  137. package/test/manual-html-ui.mjs +30 -0
  138. package/test/manual-syntax-preview.mjs +26 -0
  139. package/test/manual-terminal-lifecycle.mjs +42 -0
  140. package/test/manual-terminal-navigation.mjs +48 -0
  141. package/test/manual-terminal-ui.mjs +47 -0
  142. package/test/manual-trash-ui.mjs +86 -0
  143. package/test/markdown-diagrams.test.js +93 -0
  144. package/test/markdown-html.test.js +105 -0
  145. package/test/mathml.test.js +92 -0
  146. package/test/menu-transfer.test.js +57 -0
  147. package/test/office-preview.test.js +154 -0
  148. package/test/pele-parity.test.js +28 -0
  149. package/test/places.test.js +134 -0
  150. package/test/preview-keys.test.js +60 -0
  151. package/test/preview-language.test.js +22 -0
  152. package/test/status-filename.test.js +20 -0
  153. package/test/transfer-replace-merge.test.js +187 -0
  154. package/test/trash-address.test.js +23 -0
  155. package/test/trash-view.test.js +37 -0
  156. package/test/trashbrowse.test.js +135 -0
  157. package/ui/AboutFacts.qml +78 -0
  158. package/ui/ArchiveCards.qml +95 -0
  159. package/ui/ArchiveCompressDialog.qml +378 -0
  160. package/ui/ArchiveHereConfirm.qml +127 -0
  161. package/ui/ArchivePasswordDialog.qml +257 -0
  162. package/ui/Backend.qml +775 -0
  163. package/ui/BulkOldNames.qml +47 -0
  164. package/ui/BulkRenameDialog.qml +380 -0
  165. package/ui/CardFrame.qml +67 -0
  166. package/ui/CardScroll.qml +79 -0
  167. package/ui/CheckBox.qml +73 -0
  168. package/ui/ChromeBar.qml +360 -0
  169. package/ui/ChromeButton.qml +131 -0
  170. package/ui/ChromeModes.qml +43 -0
  171. package/ui/CodeLines.qml +256 -0
  172. package/ui/CodeRefusal.qml +52 -0
  173. package/ui/CollideConfirm.qml +147 -0
  174. package/ui/CollideHost.qml +167 -0
  175. package/ui/ColumnPane.qml +525 -0
  176. package/ui/ColumnRow.qml +380 -0
  177. package/ui/ColumnsArea.qml +594 -0
  178. package/ui/ColumnsLanding.qml +147 -0
  179. package/ui/CompareView.qml +321 -0
  180. package/ui/ContextMenu.qml +743 -0
  181. package/ui/ConvertDialog.qml +456 -0
  182. package/ui/CountedWorker.qml +7 -0
  183. package/ui/Crumb.qml +64 -0
  184. package/ui/CrumbDrop.qml +25 -0
  185. package/ui/CsvTable.qml +394 -0
  186. package/ui/CursorMark.qml +41 -0
  187. package/ui/DefaultClaim.qml +130 -0
  188. package/ui/DeviceLock.qml +47 -0
  189. package/ui/DeviceMounts.qml +540 -0
  190. package/ui/DialogButton.qml +150 -0
  191. package/ui/DialogField.qml +147 -0
  192. package/ui/DialogHeader.qml +31 -0
  193. package/ui/DialogScrim.qml +20 -0
  194. package/ui/DialogTitle.qml +37 -0
  195. package/ui/Divider.qml +9 -0
  196. package/ui/DropInto.qml +126 -0
  197. package/ui/DropTarget.qml +35 -0
  198. package/ui/DropboxMark.qml +60 -0
  199. package/ui/EmptyState.qml +150 -0
  200. package/ui/EscapeHint.qml +11 -0
  201. package/ui/FactsTable.qml +54 -0
  202. package/ui/FastScrollHandler.qml +476 -0
  203. package/ui/FatNamesConfirm.qml +157 -0
  204. package/ui/Favourites.qml +143 -0
  205. package/ui/FigureService.qml +120 -0
  206. package/ui/FileDrag.qml +267 -0
  207. package/ui/FilterStrip.qml +133 -0
  208. package/ui/FitMetrics.qml +22 -0
  209. package/ui/FlashDriveRows.qml +137 -0
  210. package/ui/FlashHost.qml +72 -0
  211. package/ui/FlashImageRow.qml +104 -0
  212. package/ui/FlashRunner.qml +119 -0
  213. package/ui/FlashStepRow.qml +172 -0
  214. package/ui/FlashStrip.qml +38 -0
  215. package/ui/FlashView.qml +397 -0
  216. package/ui/FleaMark.qml +88 -0
  217. package/ui/FlyoutFade.qml +23 -0
  218. package/ui/FontPane.qml +170 -0
  219. package/ui/Glass.qml +114 -0
  220. package/ui/GlassTagger.qml +59 -0
  221. package/ui/Glyph.qml +64 -0
  222. package/ui/GlyphSolid.qml +22 -0
  223. package/ui/GridArea.qml +664 -0
  224. package/ui/GridTile.qml +325 -0
  225. package/ui/GvfsBridge.qml +164 -0
  226. package/ui/Header.qml +433 -0
  227. package/ui/HoverTimers.qml +39 -0
  228. package/ui/HtmlClip.qml +30 -0
  229. package/ui/HtmlPane.qml +63 -0
  230. package/ui/HyprlandMark.qml +45 -0
  231. package/ui/Ipc.qml +1005 -0
  232. package/ui/IpcControls.qml +7 -0
  233. package/ui/IpcMenuState.qml +48 -0
  234. package/ui/IpcPreviewState.qml +185 -0
  235. package/ui/JumpPath.qml +51 -0
  236. package/ui/KeymapSheet.qml +561 -0
  237. package/ui/KeymapSheetResult.qml +89 -0
  238. package/ui/KindStack.qml +40 -0
  239. package/ui/LangMark.qml +51 -0
  240. package/ui/LangMarkLoader.qml +26 -0
  241. package/ui/List.qml +480 -0
  242. package/ui/LoadingState.qml +54 -0
  243. package/ui/LocalSend.qml +56 -0
  244. package/ui/LocalSendMark.qml +73 -0
  245. package/ui/MarkdownBlockView.qml +311 -0
  246. package/ui/MarkdownBlocks.qml +35 -0
  247. package/ui/MarkdownFigure.qml +254 -0
  248. package/ui/MarkdownImages.qml +72 -0
  249. package/ui/MarkdownList.qml +81 -0
  250. package/ui/MarkdownMathsText.qml +97 -0
  251. package/ui/MarkdownPane.qml +83 -0
  252. package/ui/MarkdownPictures.qml +41 -0
  253. package/ui/MarkdownQuote.qml +52 -0
  254. package/ui/MarkdownRemote.qml +82 -0
  255. package/ui/MarkdownSource.qml +155 -0
  256. package/ui/MarkdownTable.qml +222 -0
  257. package/ui/MarkdownTableScroll.qml +64 -0
  258. package/ui/MarkdownTableWheel.qml +126 -0
  259. package/ui/MarkdownText.qml +87 -0
  260. package/ui/MarkdownWorker.js +132 -0
  261. package/ui/MatchText.qml +99 -0
  262. package/ui/MediaSession.qml +38 -0
  263. package/ui/MediaSound.qml +26 -0
  264. package/ui/MediaStrip.qml +191 -0
  265. package/ui/MediaTrack.qml +36 -0
  266. package/ui/MediaVolume.qml +54 -0
  267. package/ui/MenuActionDialog.qml +396 -0
  268. package/ui/MenuEdgeFade.qml +24 -0
  269. package/ui/MenuHost.qml +227 -0
  270. package/ui/MenuRow.qml +351 -0
  271. package/ui/MountListing.qml +100 -0
  272. package/ui/NetworkDialog.qml +435 -0
  273. package/ui/NetworkForm.qml +426 -0
  274. package/ui/NetworkMounts.qml +913 -0
  275. package/ui/NetworkPlaces.qml +127 -0
  276. package/ui/OpenWithDialog.qml +613 -0
  277. package/ui/Opener.qml +95 -0
  278. package/ui/Pane.qml +1320 -0
  279. package/ui/PaneMenuActions.qml +527 -0
  280. package/ui/PanePath.qml +90 -0
  281. package/ui/PaneRail.qml +268 -0
  282. package/ui/PaneStates.qml +88 -0
  283. package/ui/PaneSwap.qml +339 -0
  284. package/ui/PaneWire.qml +601 -0
  285. package/ui/ParkedWait.qml +9 -0
  286. package/ui/PathEntry.qml +186 -0
  287. package/ui/PathJump.qml +400 -0
  288. package/ui/PdfViewer.qml +297 -0
  289. package/ui/PermissionsDialog.qml +658 -0
  290. package/ui/PermissionsHeadings.qml +31 -0
  291. package/ui/PhoneMounts.qml +67 -0
  292. package/ui/PickerAnswers.qml +75 -0
  293. package/ui/PickerBox.qml +26 -0
  294. package/ui/PickerChrome.qml +295 -0
  295. package/ui/PickerFilter.qml +97 -0
  296. package/ui/PickerGrid.qml +308 -0
  297. package/ui/PickerHeader.qml +28 -0
  298. package/ui/PickerLifecycle.qml +27 -0
  299. package/ui/PickerList.qml +218 -0
  300. package/ui/PickerListing.qml +149 -0
  301. package/ui/PickerPathBar.qml +127 -0
  302. package/ui/PickerPlaces.qml +189 -0
  303. package/ui/PickerRecent.qml +92 -0
  304. package/ui/PickerSave.qml +101 -0
  305. package/ui/PickerSelection.qml +155 -0
  306. package/ui/PickerWindow.qml +846 -0
  307. package/ui/PowerSectorsReader.qml +10 -0
  308. package/ui/PrebuildDriver.qml +146 -0
  309. package/ui/Preview.qml +1005 -0
  310. package/ui/PreviewAnimation.qml +24 -0
  311. package/ui/PreviewArchive.qml +91 -0
  312. package/ui/PreviewColumn.qml +553 -0
  313. package/ui/PreviewEdge.qml +63 -0
  314. package/ui/PreviewFacts.qml +30 -0
  315. package/ui/PreviewFactsLine.qml +34 -0
  316. package/ui/PreviewHtml.qml +233 -0
  317. package/ui/PreviewImage.qml +253 -0
  318. package/ui/PreviewImagePan.qml +13 -0
  319. package/ui/PreviewImageSharp.qml +32 -0
  320. package/ui/PreviewLines.qml +106 -0
  321. package/ui/PreviewMarkdown.qml +706 -0
  322. package/ui/PreviewMedia.qml +250 -0
  323. package/ui/PreviewPdf.qml +482 -0
  324. package/ui/PreviewScroll.qml +201 -0
  325. package/ui/PreviewSwap.qml +335 -0
  326. package/ui/PreviewText.qml +149 -0
  327. package/ui/ProtocolChip.qml +18 -0
  328. package/ui/QuickLookArchive.qml +41 -0
  329. package/ui/QuickLookBar.qml +103 -0
  330. package/ui/QuickLookPrepare.qml +355 -0
  331. package/ui/QuickLookSwap.qml +10 -0
  332. package/ui/QuickLookWarm.qml +65 -0
  333. package/ui/RailDrop.qml +155 -0
  334. package/ui/RailHeading.qml +19 -0
  335. package/ui/RailPlaces.qml +38 -0
  336. package/ui/RailTrashRow.qml +67 -0
  337. package/ui/RenameField.qml +353 -0
  338. package/ui/RendererRetry.qml +11 -0
  339. package/ui/ResizeHandle.qml +52 -0
  340. package/ui/Reveal.qml +54 -0
  341. package/ui/Row.qml +476 -0
  342. package/ui/RowDrag.qml +213 -0
  343. package/ui/RowDropTarget.qml +27 -0
  344. package/ui/RunCard.qml +286 -0
  345. package/ui/Scripts.qml +65 -0
  346. package/ui/SearchStrip.qml +232 -0
  347. package/ui/SelectionBand.qml +140 -0
  348. package/ui/SelectionPreview.qml +370 -0
  349. package/ui/SettingsFavourite.qml +122 -0
  350. package/ui/SettingsGroup.qml +96 -0
  351. package/ui/SettingsHint.qml +12 -0
  352. package/ui/SettingsMetrics.qml +29 -0
  353. package/ui/SettingsPane.qml +178 -0
  354. package/ui/SettingsPanel.qml +547 -0
  355. package/ui/SettingsRail.qml +128 -0
  356. package/ui/SettingsRow.qml +409 -0
  357. package/ui/SettingsRuler.qml +85 -0
  358. package/ui/SettingsSegment.qml +85 -0
  359. package/ui/ShareBrowser.qml +113 -0
  360. package/ui/ShareLink.qml +67 -0
  361. package/ui/ShelfPins.qml +101 -0
  362. package/ui/Sidebar.qml +728 -0
  363. package/ui/SidebarRow.qml +358 -0
  364. package/ui/Spinner.qml +60 -0
  365. package/ui/StableModel.qml +89 -0
  366. package/ui/StateMessage.qml +84 -0
  367. package/ui/StatusBar.qml +512 -0
  368. package/ui/StatusFileName.qml +27 -0
  369. package/ui/TabBar.qml +673 -0
  370. package/ui/TabDragGeometry.qml +60 -0
  371. package/ui/TagMenuMark.qml +52 -0
  372. package/ui/TagRailSection.qml +53 -0
  373. package/ui/TagSlot.qml +40 -0
  374. package/ui/TagState.qml +150 -0
  375. package/ui/TagSwatch.qml +28 -0
  376. package/ui/Taildrop.qml +86 -0
  377. package/ui/TailscaleMark.qml +50 -0
  378. package/ui/TerminalService.qml +69 -0
  379. package/ui/TerminalTab.qml +48 -0
  380. package/ui/TerminalTabs.qml +27 -0
  381. package/ui/Theme.qml +460 -0
  382. package/ui/ThemeColors.qml +43 -0
  383. package/ui/TransferCard.qml +239 -0
  384. package/ui/TrashConfirm.qml +129 -0
  385. package/ui/TrashDropHandler.qml +11 -0
  386. package/ui/TrashHost.qml +202 -0
  387. package/ui/TrashMonitor.qml +30 -0
  388. package/ui/TrashToolbar.qml +19 -0
  389. package/ui/TrashView.qml +492 -0
  390. package/ui/UnlockDialog.qml +450 -0
  391. package/ui/UnlockHost.qml +206 -0
  392. package/ui/UpdateCheck.qml +97 -0
  393. package/ui/UserDirs.qml +25 -0
  394. package/ui/ViewState.qml +565 -0
  395. package/ui/ViewportScrollBar.qml +195 -0
  396. package/ui/ViewportScrollBars.qml +25 -0
  397. package/ui/WebPreview.qml +33 -0
  398. package/ui/WebPreviewView.qml +26 -0
  399. package/ui/WindowBody.qml +829 -0
  400. package/ui/WindowDrag.qml +35 -0
  401. package/ui/boot/Commons/AudioNodes.qml +50 -0
  402. package/ui/boot/Commons/AudioNodesModel.js +96 -0
  403. package/ui/boot/Commons/Border.qml +243 -0
  404. package/ui/boot/Commons/BorderGeometry.js +373 -0
  405. package/ui/boot/Commons/Color.qml +258 -0
  406. package/ui/boot/Commons/I18n.qml +118 -0
  407. package/ui/boot/Commons/InputDevices.qml +112 -0
  408. package/ui/boot/Commons/InputMethodState.qml +38 -0
  409. package/ui/boot/Commons/IpcRegistry.qml +77 -0
  410. package/ui/boot/Commons/Numbers.js +19 -0
  411. package/ui/boot/Commons/Plural.js +91 -0
  412. package/ui/boot/Commons/ShellIpc.qml +12 -0
  413. package/ui/boot/Commons/Style.qml +561 -0
  414. package/ui/boot/Commons/Translations.qml +100 -0
  415. package/ui/boot/Commons/UntypedInput.qml +152 -0
  416. package/ui/boot/Commons/Util.qml +188 -0
  417. package/ui/boot/Commons/qmldir +13 -0
  418. package/ui/boot/LICENSE-omarchy +20 -0
  419. package/ui/boot/Ui/BackgroundMedia.qml +49 -0
  420. package/ui/boot/Ui/BarIconButton.qml +106 -0
  421. package/ui/boot/Ui/BarIconContent.qml +38 -0
  422. package/ui/boot/Ui/BarIndicator.qml +53 -0
  423. package/ui/boot/Ui/BarWidget.qml +50 -0
  424. package/ui/boot/Ui/BorderOverlay.qml +54 -0
  425. package/ui/boot/Ui/BorderSurface.qml +40 -0
  426. package/ui/boot/Ui/Button.qml +224 -0
  427. package/ui/boot/Ui/ButtonGroup.qml +131 -0
  428. package/ui/boot/Ui/ConfirmDialog.qml +134 -0
  429. package/ui/boot/Ui/CursorSurface.qml +42 -0
  430. package/ui/boot/Ui/Dropdown.qml +245 -0
  431. package/ui/boot/Ui/FilterInput.qml +26 -0
  432. package/ui/boot/Ui/IconContentBounds.qml +141 -0
  433. package/ui/boot/Ui/KeyboardPanel.qml +453 -0
  434. package/ui/boot/Ui/MultiSelect.qml +624 -0
  435. package/ui/boot/Ui/NumberField.qml +86 -0
  436. package/ui/boot/Ui/OpticalGlyph.qml +68 -0
  437. package/ui/boot/Ui/OverlayWindow.qml +102 -0
  438. package/ui/boot/Ui/Panel.qml +60 -0
  439. package/ui/boot/Ui/PanelActionButton.qml +105 -0
  440. package/ui/boot/Ui/PanelController.qml +16 -0
  441. package/ui/boot/Ui/PanelHero.qml +112 -0
  442. package/ui/boot/Ui/PanelKeyCatcher.qml +100 -0
  443. package/ui/boot/Ui/PanelSectionHeader.qml +31 -0
  444. package/ui/boot/Ui/PanelSeparator.qml +19 -0
  445. package/ui/boot/Ui/PanelSlider.qml +156 -0
  446. package/ui/boot/Ui/PanelToolTip.qml +50 -0
  447. package/ui/boot/Ui/PluginBarApi.qml +89 -0
  448. package/ui/boot/Ui/PointerMoveGate.qml +54 -0
  449. package/ui/boot/Ui/PopupCard.qml +181 -0
  450. package/ui/boot/Ui/ScreenMoveRemap.qml +43 -0
  451. package/ui/boot/Ui/SearchableDropdown.qml +354 -0
  452. package/ui/boot/Ui/SizedImage.qml +125 -0
  453. package/ui/boot/Ui/SpeedTestOverlay.qml +412 -0
  454. package/ui/boot/Ui/TextField.qml +58 -0
  455. package/ui/boot/Ui/Toggle.qml +118 -0
  456. package/ui/boot/Ui/ToggleSwitch.qml +115 -0
  457. package/ui/boot/Ui/WidgetButton.qml +172 -0
  458. package/ui/boot/Ui/qmldir +41 -0
  459. package/ui/boot/fleatab.qml +50 -0
  460. package/ui/boot/picker.qml +39 -0
  461. package/ui/boot/shell.qml +131 -0
  462. package/ui/boot/tabtearoff.qml +51 -0
  463. package/ui/js/Anchor.js +379 -0
  464. package/ui/js/AnchorHold.js +162 -0
  465. package/ui/js/Archive.js +157 -0
  466. package/ui/js/ArchiveCard.js +44 -0
  467. package/ui/js/ArchiveOps.js +44 -0
  468. package/ui/js/BackReturn.js +118 -0
  469. package/ui/js/BulkRename.js +100 -0
  470. package/ui/js/Buttons.js +54 -0
  471. package/ui/js/ChromeKeys.js +116 -0
  472. package/ui/js/ClipMarks.js +73 -0
  473. package/ui/js/ClipSelection.js +67 -0
  474. package/ui/js/Clipboard.js +179 -0
  475. package/ui/js/Cloud.js +97 -0
  476. package/ui/js/CodeRuns.js +72 -0
  477. package/ui/js/Collide.js +212 -0
  478. package/ui/js/ColumnFit.js +28 -0
  479. package/ui/js/ColumnMenu.js +111 -0
  480. package/ui/js/Columns.js +298 -0
  481. package/ui/js/ColumnsCarry.js +103 -0
  482. package/ui/js/Compare.js +74 -0
  483. package/ui/js/Contrast.js +157 -0
  484. package/ui/js/ControlReader.js +42 -0
  485. package/ui/js/Convert.js +52 -0
  486. package/ui/js/CopyAs.js +52 -0
  487. package/ui/js/Crumbs.js +178 -0
  488. package/ui/js/Csv.js +231 -0
  489. package/ui/js/Density.js +44 -0
  490. package/ui/js/Devices.js +440 -0
  491. package/ui/js/DirSizes.js +180 -0
  492. package/ui/js/Drag.js +360 -0
  493. package/ui/js/DragOut.js +166 -0
  494. package/ui/js/DropDev.js +52 -0
  495. package/ui/js/Dropbox.js +41 -0
  496. package/ui/js/Eject.js +217 -0
  497. package/ui/js/Errors.js +188 -0
  498. package/ui/js/ExtThumbs.js +115 -0
  499. package/ui/js/Facts.js +402 -0
  500. package/ui/js/FigureDate.js +14 -0
  501. package/ui/js/Filter.js +285 -0
  502. package/ui/js/Find.js +46 -0
  503. package/ui/js/Flash.js +184 -0
  504. package/ui/js/FlashCard.js +79 -0
  505. package/ui/js/FlashEndings.js +125 -0
  506. package/ui/js/FlashPane.js +116 -0
  507. package/ui/js/FleaBin.js +12 -0
  508. package/ui/js/Focus.js +504 -0
  509. package/ui/js/FolderSorts.js +108 -0
  510. package/ui/js/FolderViews.js +44 -0
  511. package/ui/js/Format.js +314 -0
  512. package/ui/js/Fuzzy.js +141 -0
  513. package/ui/js/GlassTag.js +72 -0
  514. package/ui/js/Grid.js +33 -0
  515. package/ui/js/GridGeometry.js +90 -0
  516. package/ui/js/GridNames.js +153 -0
  517. package/ui/js/GvfsBridge.js +200 -0
  518. package/ui/js/HostClipboard.js +29 -0
  519. package/ui/js/Icons.js +218 -0
  520. package/ui/js/Input.js +50 -0
  521. package/ui/js/Jump.js +200 -0
  522. package/ui/js/KeyName.js +64 -0
  523. package/ui/js/Keymap.js +401 -0
  524. package/ui/js/Kinds.js +164 -0
  525. package/ui/js/LICENSES/ISC-lucide.txt +43 -0
  526. package/ui/js/LangMarkPaths.js +47 -0
  527. package/ui/js/LangMarks.js +120 -0
  528. package/ui/js/Lists.js +11 -0
  529. package/ui/js/LocalSend.js +39 -0
  530. package/ui/js/LockedMenu.js +63 -0
  531. package/ui/js/MakeDefault.js +186 -0
  532. package/ui/js/MarkBox.js +7 -0
  533. package/ui/js/Markdown.js +119 -0
  534. package/ui/js/MarkdownLists.js +86 -0
  535. package/ui/js/MarkdownMaths.js +58 -0
  536. package/ui/js/MarkdownPictures.js +32 -0
  537. package/ui/js/MarkdownPrepared.js +139 -0
  538. package/ui/js/MarkdownTableFit.js +34 -0
  539. package/ui/js/Marks.js +148 -0
  540. package/ui/js/Marquee.js +96 -0
  541. package/ui/js/Match.js +93 -0
  542. package/ui/js/Material.js +109 -0
  543. package/ui/js/MdBlocks.js +437 -0
  544. package/ui/js/MdBreak.js +71 -0
  545. package/ui/js/MdChunks.js +70 -0
  546. package/ui/js/MdContainer.js +137 -0
  547. package/ui/js/MdDocument.js +337 -0
  548. package/ui/js/MdEmph.js +97 -0
  549. package/ui/js/MdEntity.js +108 -0
  550. package/ui/js/MdEntityTable.js +223 -0
  551. package/ui/js/MdEscape.js +59 -0
  552. package/ui/js/MdFront.js +37 -0
  553. package/ui/js/MdHold.js +32 -0
  554. package/ui/js/MdHtml.js +307 -0
  555. package/ui/js/MdHtmlBlock.js +290 -0
  556. package/ui/js/MdHtmlHeading.js +53 -0
  557. package/ui/js/MdHtmlImage.js +179 -0
  558. package/ui/js/MdInline.js +154 -0
  559. package/ui/js/MdItems.js +212 -0
  560. package/ui/js/MdLeaf.js +309 -0
  561. package/ui/js/MdLink.js +196 -0
  562. package/ui/js/MdMath.js +67 -0
  563. package/ui/js/MdParagraphs.js +138 -0
  564. package/ui/js/MdRefs.js +232 -0
  565. package/ui/js/MdResolve.js +226 -0
  566. package/ui/js/MdRun.js +300 -0
  567. package/ui/js/MdUrl.js +226 -0
  568. package/ui/js/Menu.js +514 -0
  569. package/ui/js/MenuContext.js +85 -0
  570. package/ui/js/MenuFit.js +13 -0
  571. package/ui/js/MenuRefresh.js +74 -0
  572. package/ui/js/MenuWheel.js +35 -0
  573. package/ui/js/Messages.js +186 -0
  574. package/ui/js/Motion.js +16 -0
  575. package/ui/js/Mounts.js +320 -0
  576. package/ui/js/MouseNav.js +13 -0
  577. package/ui/js/Nav.js +329 -0
  578. package/ui/js/NetFs.js +26 -0
  579. package/ui/js/OpenWith.js +83 -0
  580. package/ui/js/Ops.js +585 -0
  581. package/ui/js/Palette.js +33 -0
  582. package/ui/js/PathBar.js +260 -0
  583. package/ui/js/Permissions.js +179 -0
  584. package/ui/js/Phones.js +112 -0
  585. package/ui/js/Picker.js +353 -0
  586. package/ui/js/PlaceMenu.js +96 -0
  587. package/ui/js/Places.js +265 -0
  588. package/ui/js/PreviewAsk.js +21 -0
  589. package/ui/js/PreviewKeys.js +155 -0
  590. package/ui/js/PreviewSettle.js +29 -0
  591. package/ui/js/PreviewSwap.js +101 -0
  592. package/ui/js/PropertyFacts.js +144 -0
  593. package/ui/js/Protocols.js +296 -0
  594. package/ui/js/QuickLookKinds.js +27 -0
  595. package/ui/js/QuickLookRect.js +24 -0
  596. package/ui/js/RailDrop.js +51 -0
  597. package/ui/js/RailKeys.js +87 -0
  598. package/ui/js/RailMenu.js +133 -0
  599. package/ui/js/Recent.js +135 -0
  600. package/ui/js/RecentMode.js +156 -0
  601. package/ui/js/Reload.js +60 -0
  602. package/ui/js/Renderer.js +9 -0
  603. package/ui/js/RunFile.js +143 -0
  604. package/ui/js/Scripts.js +28 -0
  605. package/ui/js/Scroll.js +304 -0
  606. package/ui/js/ScrollOff.js +69 -0
  607. package/ui/js/Search.js +478 -0
  608. package/ui/js/Selection.js +97 -0
  609. package/ui/js/Settings.js +476 -0
  610. package/ui/js/SettingsAbout.js +97 -0
  611. package/ui/js/SettingsShelf.js +52 -0
  612. package/ui/js/SheetKeys.js +42 -0
  613. package/ui/js/SheetQuery.js +281 -0
  614. package/ui/js/ShelfPile.js +27 -0
  615. package/ui/js/SlowClick.js +53 -0
  616. package/ui/js/SlowOp.js +6 -0
  617. package/ui/js/Sort.js +134 -0
  618. package/ui/js/Startup.js +63 -0
  619. package/ui/js/StateWords.js +17 -0
  620. package/ui/js/Status.js +238 -0
  621. package/ui/js/Swap.js +166 -0
  622. package/ui/js/TabMove.js +39 -0
  623. package/ui/js/Tabs.js +751 -0
  624. package/ui/js/Tags.js +134 -0
  625. package/ui/js/Taildrop.js +128 -0
  626. package/ui/js/Tap.js +180 -0
  627. package/ui/js/TextSize.js +107 -0
  628. package/ui/js/Thumbs.js +158 -0
  629. package/ui/js/Transfer.js +172 -0
  630. package/ui/js/Trash.js +84 -0
  631. package/ui/js/TrashDates.js +47 -0
  632. package/ui/js/TrashDrop.js +64 -0
  633. package/ui/js/UiState.js +438 -0
  634. package/ui/js/Unlock.js +152 -0
  635. package/ui/js/Update.js +130 -0
  636. package/ui/js/UserDirs.js +56 -0
  637. package/ui/qmldir +230 -0
@@ -0,0 +1,139 @@
1
+ .pragma library
2
+
3
+ .import "Lists.js" as Lists
4
+ .import "Kinds.js" as Kinds
5
+ .import "ExtThumbs.js" as ExtThumbs
6
+ .import "Contrast.js" as Contrast
7
+ .import "Format.js" as Format
8
+
9
+ // The one parsed Markdown document Quick Look takes without parsing, keyed by its text so an edited file misses and one past MAX_BYTES is never held.
10
+ var entry = null
11
+ var MAX_BYTES = 65536
12
+
13
+ // Sample input: the row { n: "a.md", d: false } answers true; { n: "a.md", d: true }, { n: "a.txt", d: false } and null answer false.
14
+ // Whether the cursor row is a Markdown file by name, the one trigger Quick Look's warm and its ahead-of-Space build share.
15
+ function isMarkdownRow(row) {
16
+ return row !== null && row !== undefined && !row.d && Kinds.isMarkdown(row.n)
17
+ }
18
+
19
+ // Sample input: a 900 byte regular "a.md" row on class "" with the class known answers true; a named pipe row, class "network" or an unknown class answers false.
20
+ // Only a regular local file under MAX_BYTES in a folder whose class has landed is read ahead or inside the key; cifs, nfs and listed FUSE shares classify "network" in extclass.rs.
21
+ function readsInline(row, storageClass, storageKnown) {
22
+ if (!row || row.d || !storageKnown || ExtThumbs.present(storageClass) || !Kinds.isMarkdown(row.n))
23
+ return false
24
+ return (row.p & Format.S_IFMT) === Format.S_IFREG && row.s > 0 && row.s <= MAX_BYTES
25
+ }
26
+
27
+ // A picture at most this big is decoded ahead of the open, and a document is asked about at most this many.
28
+ var PICTURE_MAX_BYTES = 262144
29
+ var PICTURE_LIMIT = 8
30
+ var FILE_SCHEME_LENGTH = 7
31
+ // The stat child that sizes the pictures is dropped after this long, so a hung mount holds nothing past it.
32
+ var PICTURE_SIZE_DEADLINE_MS = 1500
33
+
34
+ // Sample input: "file:///d/b%20c.png" answers "/d/b c.png"; "file:///d/100%.png" (a stray percent) answers "".
35
+ function pathOfUrl(url) {
36
+ try {
37
+ return decodeURIComponent(String(url).slice(FILE_SCHEME_LENGTH))
38
+ } catch (e) {
39
+ return ""
40
+ }
41
+ }
42
+
43
+ // Sample input: path "/d/img/a.png" in dir "/d" answers true; "/mnt/nas/a.png" and "/d/../e/a.png" answer false.
44
+ // Only a picture under the document's folder shares the storage class readsInline cleared, so a stat never reaches another mount.
45
+ function insideDir(path, dir) {
46
+ return dir !== "" && path.indexOf(dir + "/") === 0 && path.split("/").indexOf("..") < 0
47
+ }
48
+
49
+ // Sample input: blocks [{ type: "image", url: "file:///d/a.png" }, { type: "images", items: [{ url: "file:///d/b%20c.png" }, { url: "file:///d/a.png" }] }, { type: "run" }] in dir "/d" answer ["file:///d/a.png", "file:///d/b%20c.png"].
50
+ // The local pictures a parsed document draws at its top level under its own folder, each once, in reading order, at most limit of them.
51
+ function pictureUrls(blocks, limit, dir) {
52
+ var urls = []
53
+ function add(url) {
54
+ if (typeof url === "string" && url.indexOf("file://") === 0 && urls.length < limit && urls.indexOf(url) < 0
55
+ && insideDir(pathOfUrl(url), dir))
56
+ urls.push(url)
57
+ }
58
+ for (var i = 0; i < blocks.length; i++) {
59
+ var b = blocks[i]
60
+ if (b.type === "image") {
61
+ add(b.url)
62
+ } else if (b.type === "images" && b.items !== undefined) {
63
+ for (var j = 0; j < b.items.length; j++)
64
+ add(b.items[j].url)
65
+ }
66
+ }
67
+ return urls
68
+ }
69
+
70
+ // Sample input: urls ["file:///d/a.png", "file:///d/big.png", "file:///d/gone.png"] with the stat text "2048\t/d/a.png\n900000\t/d/big.png\n" answer ["file:///d/a.png"].
71
+ // The pictures stat sized at PICTURE_MAX_BYTES or less; a name stat did not print (a missing file) or a bigger one keeps the open's own load.
72
+ function smallPictures(urls, statText) {
73
+ var sizes = {}
74
+ var lines = String(statText).split("\n")
75
+ for (var i = 0; i < lines.length; i++) {
76
+ var tab = lines[i].indexOf("\t")
77
+ if (tab > 0)
78
+ sizes[lines[i].slice(tab + 1)] = Number(lines[i].slice(0, tab))
79
+ }
80
+ return urls.filter(function (url) {
81
+ var size = sizes[pathOfUrl(url)]
82
+ return size !== undefined && size > 0 && size <= PICTURE_MAX_BYTES
83
+ })
84
+ }
85
+
86
+ // The most formulas a rested document typesets ahead, so a document full of them never queues a render per rest.
87
+ var FORMULA_LIMIT = 8
88
+
89
+ // Sample input: [{ type: "run", maths: ["x", "x"] }, { type: "figure", kind: "math", source: "y" }, { type: "quote", parts: [{ type: "run", maths: ["z"] }] }] answer [{ source: "x", display: false }, { source: "y", display: true }, { source: "z", display: false }].
90
+ // The distinct maths a prepared document draws, in reading order and at most limit of them: inline formulas and display figures, a quote's or a list item's parts included.
91
+ function formulasIn(blocks, limit) {
92
+ var out = []
93
+ var seen = {}
94
+ function add(source, display) {
95
+ var key = (display ? "d" : "i") + source
96
+ if (out.length < limit && seen[key] === undefined) {
97
+ seen[key] = true
98
+ out.push({ source: source, display: display })
99
+ }
100
+ }
101
+ function walk(list) {
102
+ for (var i = 0; i < list.length; i++) {
103
+ var b = list[i]
104
+ if (!b)
105
+ continue
106
+ if (Lists.isList(b)) {
107
+ walk(b)
108
+ continue
109
+ }
110
+ if (b.type === "figure" && b.kind === "math")
111
+ add(b.source, true)
112
+ for (var k = 0; b.maths !== undefined && k < b.maths.length; k++)
113
+ add(b.maths[k], false)
114
+ if (b.parts !== undefined)
115
+ walk(b.parts)
116
+ }
117
+ }
118
+ walk(blocks)
119
+ return out
120
+ }
121
+
122
+ // QML color components read 0..1, so the hex a style attribute needs is assembled from them, never coerced from the colour.
123
+ // Sample input: a colour with r 0.0627, g 0.0745, b 0.0745 answers "#101313".
124
+ function hexOf(c) {
125
+ return Contrast.hexOf([c.r, c.g, c.b])
126
+ }
127
+
128
+ function store(path, text, dir, chrome, ink, blocks) {
129
+ if (text.length > MAX_BYTES) return
130
+ entry = { path: path, text: text, dir: dir, chrome: chrome, ink: ink, blocks: blocks }
131
+ }
132
+
133
+ // The blocks parsed from exactly this text with exactly these inputs, or null.
134
+ function take(path, text, dir, chrome, ink) {
135
+ var e = entry
136
+ if (e === null || e.path !== path || e.dir !== dir || e.chrome !== chrome || e.ink !== ink || e.text !== text)
137
+ return null
138
+ return e.blocks
139
+ }
@@ -0,0 +1,34 @@
1
+ .pragma library
2
+
3
+ // MarkdownTableFit: how a table shares the width its block gives it, a pure function of column widths in pixels.
4
+
5
+ // Sample input: fit([100, 400], [50, 100], 300, 10) is [71, 228]: each column keeps its longest word, the rest goes by want.
6
+ // A table that fits keeps its natural widths; past that no column falls under its longest word or least (one narrower keeps its natural), so a hopeless one is wider than avail.
7
+ function fit(natural, minimum, avail, least) {
8
+ function heldAt(c) {
9
+ return natural[c] < least ? natural[c] : Math.max(least, Math.min(minimum[c], natural[c]))
10
+ }
11
+ function capped(w, c) {
12
+ return Math.max(Math.min(least, natural[c]), Math.floor(w))
13
+ }
14
+ var total = 0
15
+ var floor = 0
16
+ for (var i = 0; i < natural.length; i++) {
17
+ total += natural[i]
18
+ floor += heldAt(i)
19
+ }
20
+ if (total <= avail)
21
+ return natural.slice()
22
+ var widths = []
23
+ if (floor <= avail) {
24
+ for (var c = 0; c < natural.length; c++) {
25
+ var held = heldAt(c)
26
+ widths.push(held + (avail - floor) * (natural[c] - held) / (total - floor))
27
+ }
28
+ } else {
29
+ // Even the longest words do not fit: every column holds its longest word whole and the table scrolls sideways.
30
+ for (var h = 0; h < natural.length; h++)
31
+ widths.push(heldAt(h))
32
+ }
33
+ return widths.map(capped)
34
+ }
package/ui/js/Marks.js ADDED
@@ -0,0 +1,148 @@
1
+ .pragma library
2
+
3
+ .import "Filter.js" as Filter
4
+
5
+ // Marking rows: ctrl+A, the shift range in both its keyboard and its pointer form, and ctrl+click.
6
+ // Split out of ui/js/Filter.js, which narrows the listing; these move the cursor and the marks over
7
+ // whatever that narrowing left drawn, which is why every one of them reads through it.
8
+
9
+ // Ctrl+A takes what is drawn, never what is listed: under a filter that is the matches alone.
10
+ function selectAll(pane) {
11
+ if (pane.shown === null) {
12
+ pane.selection.all(pane.total)
13
+ return
14
+ }
15
+ pane.selection.clear()
16
+ for (var i = 0; i < pane.shown.length; i++) {
17
+ pane.selection.toggle(pane.shown[i])
18
+ }
19
+ }
20
+
21
+ // A gesture continues while nothing else moved the cursor since the last extend left it;
22
+ // any other cursor move, and any mark made outside the gesture, ends it through shiftState.
23
+ function continuing(pane) {
24
+ var state = pane.selection.shiftState()
25
+ return state !== null && pane.cursorIndex === state.last && (pane.cursorSeq || 0) === (state.seq || 0)
26
+ }
27
+
28
+ // Invert flips the drawn marks; a row no filter draws is never selected.
29
+ function inverted(total, shown, selected) {
30
+ var drawn = shown === null ? range(total) : shown.slice()
31
+ var has = {}
32
+ for (var s = 0; s < selected.length; s++)
33
+ has[selected[s]] = true
34
+ var out = []
35
+ for (var i = 0; i < drawn.length; i++) {
36
+ if (has[drawn[i]] !== true)
37
+ out.push(drawn[i])
38
+ }
39
+ return out
40
+ }
41
+
42
+ function range(total) {
43
+ var out = []
44
+ for (var r = 0; r < total; r++)
45
+ out.push(r)
46
+ return out
47
+ }
48
+
49
+ // The pane's own invert, through the same drawn set selectAll reads.
50
+ function invert(pane) {
51
+ var next = inverted(pane.total, pane.shown, pane.selectedIndices())
52
+ pane.selection.clear()
53
+ for (var i = 0; i < next.length; i++)
54
+ pane.selection.toggle(next[i])
55
+ pane.selectionVersion += 1
56
+ }
57
+
58
+ // A range starts at the cursor, or where it stood before the wheel pulled it onto the viewport.
59
+ function latchAnchor(pane) {
60
+ var from = Filter.pulledFrom(pane)
61
+ pane.selectionAnchor = from >= 0 ? from : pane.cursorIndex
62
+ }
63
+
64
+ // Shift+J and Shift+K, the whole gesture: the cursor moves through what is drawn and the selection
65
+ // is the base the gesture started from plus the drawn rows between the anchor and the cursor, so
66
+ // several blocks can be marked and the gesture's own range still grows and shrinks.
67
+ function extend(pane, delta) {
68
+ if (!continuing(pane)) {
69
+ pane.selection.shiftBegin(pane.selectedIndices(), pane.cursorIndex, pane.cursorSeq || 0)
70
+ latchAnchor(pane)
71
+ }
72
+ Filter.moveCursor(pane, delta)
73
+ extendTo(pane, pane.selectionAnchor)
74
+ pane.selection.shiftMoved(pane.cursorIndex, pane.cursorSeq || 0)
75
+ pane.selectionVersion += 1
76
+ }
77
+
78
+ // Shift+click, the absolute twin of extend() above: the anchor latches through latchAnchor before the
79
+ // click, which a plain click or ctrl+click already sets, and consecutive shift+clicks share one base.
80
+ // A click carries context 0 so the list never moves under the pointer.
81
+ function extendToRow(pane, index) {
82
+ if (!continuing(pane)) {
83
+ pane.selection.shiftBegin(pane.selectedIndices(), pane.cursorIndex, pane.cursorSeq || 0)
84
+ latchAnchor(pane)
85
+ }
86
+ Filter.setCursor(pane, index, 0)
87
+ extendTo(pane, pane.selectionAnchor)
88
+ pane.selection.shiftMoved(pane.cursorIndex, pane.cursorSeq || 0)
89
+ pane.selectionVersion += 1
90
+ }
91
+
92
+ // Ctrl+click, v's mouse twin. An empty set means the cursor row is selected, so it joins first.
93
+ // A click carries context 0 so the list never moves under the pointer.
94
+ function toggleRow(pane, index) {
95
+ if (pane.selection.count() === 0 && pane.cursorIndex !== index) {
96
+ pane.selection.toggle(pane.cursorIndex)
97
+ }
98
+ Filter.setCursor(pane, index, 0)
99
+ pane.selection.toggle(index)
100
+ pane.selectionAnchor = index
101
+ pane.selectionVersion += 1
102
+ }
103
+
104
+ // A lone selection follows a plain move so delete takes the cursor row; deliberate marks drop lone.
105
+ function follow(pane) {
106
+ if (!pane.selection.follows() || pane.cursorIndex === pane.selectedIndices()[0])
107
+ return
108
+ var keep = pane.selection.isLanded ? pane.selection.isLanded() : false
109
+ pane.selection.only(pane.cursorIndex, keep)
110
+ pane.selectionAnchor = pane.cursorIndex
111
+ pane.selectionVersion += 1
112
+ }
113
+
114
+ // v on a lone following row keeps it as a deliberate mark instead of toggling it off.
115
+ function toggleSelect(pane) {
116
+ if (!pane.selection.promote(pane.cursorIndex)) pane.selection.toggle(pane.cursorIndex)
117
+ pane.selectionAnchor = pane.cursorIndex
118
+ pane.selectionVersion += 1
119
+ }
120
+
121
+ // The drawn rows between cursor and anchor; a shrinking gesture keeps its base.
122
+ function extendTo(pane, anchor) {
123
+ var state = pane.selection.shiftState()
124
+ if (state === null) {
125
+ if (pane.shown === null) {
126
+ pane.selection.extendTo(pane.cursorIndex, anchor)
127
+ return
128
+ }
129
+ pane.selection.clear()
130
+ var single = Filter.between(pane.shown, pane.cursorIndex, anchor)
131
+ for (var i = 0; i < single.length; i++) {
132
+ pane.selection.toggle(single[i])
133
+ }
134
+ return
135
+ }
136
+ var range
137
+ if (pane.shown === null) {
138
+ range = []
139
+ var lo = Math.min(pane.cursorIndex, anchor)
140
+ var hi = Math.max(pane.cursorIndex, anchor)
141
+ for (var r = lo; r <= hi; r++) {
142
+ range.push(r)
143
+ }
144
+ } else {
145
+ range = Filter.between(pane.shown, pane.cursorIndex, anchor)
146
+ }
147
+ pane.selection.shiftApply(range)
148
+ }
@@ -0,0 +1,96 @@
1
+ .pragma library
2
+ .import "Selection.js" as Selection
3
+
4
+ // Cell coordinates avoid inspecting or instantiating delegates outside the viewport.
5
+ function cells(x1, y1, x2, y2, width, height, columns, count) {
6
+ var left = Math.min(x1, x2), right = Math.max(x1, x2)
7
+ var top = Math.min(y1, y2), bottom = Math.max(y1, y2)
8
+ if (width <= 0 || height <= 0 || count <= 0 || left === right || top === bottom
9
+ || right <= 0 || bottom <= 0 || left >= columns * width)
10
+ return null
11
+ var box = { left: Math.max(0, Math.floor(left / width)),
12
+ right: Math.min(columns - 1, Math.ceil(right / width) - 1),
13
+ top: Math.max(0, Math.floor(top / height)),
14
+ bottom: Math.min(Math.ceil(count / columns) - 1, Math.ceil(bottom / height) - 1) }
15
+ return box.top <= box.bottom ? box : null
16
+ }
17
+
18
+ function same(a, b) {
19
+ return a === b || (a !== null && b !== null && a.left === b.left && a.right === b.right
20
+ && a.top === b.top && a.bottom === b.bottom)
21
+ }
22
+
23
+ // Visit only strips entering or leaving the rectangle; a one-row move never scans all old marks.
24
+ function difference(box, other, columns, count, backwardsX, backwardsY, visit) {
25
+ if (box === null) return
26
+ var strips = [box]
27
+ if (other !== null && other.left <= box.right && other.right >= box.left
28
+ && other.top <= box.bottom && other.bottom >= box.top) {
29
+ var top = Math.max(box.top, other.top), bottom = Math.min(box.bottom, other.bottom)
30
+ strips = [
31
+ {left: box.left, right: box.right, top: box.top, bottom: top - 1},
32
+ {left: box.left, right: Math.min(box.right, other.left - 1), top: top, bottom: bottom},
33
+ {left: Math.max(box.left, other.right + 1), right: box.right, top: top, bottom: bottom},
34
+ {left: box.left, right: box.right, top: bottom + 1, bottom: box.bottom}
35
+ ]
36
+ strips.sort(function (a, b) {
37
+ return (backwardsY ? b.bottom - a.bottom : a.top - b.top)
38
+ || (backwardsX ? b.right - a.right : a.left - b.left)
39
+ })
40
+ }
41
+ var rowStep = backwardsY ? -1 : 1
42
+ var columnStep = backwardsX ? -1 : 1
43
+ for (var s = 0; s < strips.length; s++) {
44
+ var strip = strips[s]
45
+ if (strip.left > strip.right) continue
46
+ for (var row = backwardsY ? strip.bottom : strip.top;
47
+ row >= strip.top && row <= strip.bottom; row += rowStep) {
48
+ for (var column = backwardsX ? strip.right : strip.left;
49
+ column >= strip.left && column <= strip.right; column += columnStep) {
50
+ var index = row * columns + column
51
+ if (index < count) visit(index)
52
+ }
53
+ }
54
+ }
55
+ }
56
+
57
+ function begin(pane, additive) {
58
+ var selection = Selection.create()
59
+ if (additive) {
60
+ var saved = pane.selectedIndices()
61
+ for (var i = 0; i < saved.length; i++) selection.toggle(saved[i])
62
+ }
63
+ var state = { before: pane.selection, cursor: pane.cursorIndex, anchor: pane.selectionAnchor,
64
+ additive: additive, box: null, last: -1 }
65
+ pane.selection = selection
66
+ pane.selectionVersion++
67
+ return state
68
+ }
69
+
70
+ function update(pane, state, box, columns, count, backwardsX, backwardsY, listingIndex) {
71
+ if (same(state.box, box)) return
72
+ difference(state.box, box, columns, count, false, false, function (viewIndex) {
73
+ var index = listingIndex(viewIndex)
74
+ if (index >= 0 && !(state.additive && state.before.has(index))) pane.selection.toggle(index)
75
+ })
76
+ difference(box, state.box, columns, count, backwardsX, backwardsY, function (viewIndex) {
77
+ var index = listingIndex(viewIndex)
78
+ if (index < 0) return
79
+ if (!pane.selection.has(index)) pane.selection.toggle(index)
80
+ state.last = index
81
+ })
82
+ state.box = box
83
+ pane.selectionVersion++
84
+ }
85
+
86
+ function finish(pane, state, cancelled) {
87
+ if (cancelled) {
88
+ pane.selection = state.before
89
+ pane.cursorIndex = state.cursor
90
+ pane.selectionAnchor = state.anchor
91
+ pane.selectionVersion++
92
+ } else if (state.last >= 0) {
93
+ pane.setCursor(state.last, 0)
94
+ pane.selectionAnchor = state.last
95
+ }
96
+ }
package/ui/js/Match.js ADDED
@@ -0,0 +1,93 @@
1
+ .pragma library
2
+
3
+ // A search row's name is its path relative to the search root, so the display splits it here and
4
+ // the wire never carries a second shape; see docs/protocol.md "search".
5
+ function base(path) {
6
+ var i = String(path).lastIndexOf("/")
7
+ return i < 0 ? String(path) : String(path).substring(i + 1)
8
+ }
9
+
10
+ // A Trash row's storage name is an IO identity, never its visible caption.
11
+ function rowName(row, locating) {
12
+ if (!row) return ""
13
+ if (row.trash) return row.trash.name !== undefined ? String(row.trash.name) : base(row.trash.original || row.n)
14
+ return locating ? base(row.n) : row.n
15
+ }
16
+
17
+ // The location column: the parent path relative to the scope, empty for a match in the root itself.
18
+ function location(path) {
19
+ var i = String(path).lastIndexOf("/")
20
+ return i < 0 ? "" : String(path).substring(0, i)
21
+ }
22
+
23
+ // Where to paint the accent run inside a name, mirroring the backend's own case-insensitive match.
24
+ // corner: a character whose lowercase form is a different length (Turkish dotted capital I) can
25
+ // shift the run by one; the name still renders whole, and the backend alone decides what matched.
26
+ function run(hay, needle) {
27
+ var h = String(hay)
28
+ var n = String(needle)
29
+ if (n.length === 0) {
30
+ return { start: -1, length: 0 }
31
+ }
32
+ // flea-qml: a query with a glob character is a shell glob over the whole name, so `*.js` is the
33
+ // names ending in .js; the run is then the whole name. Plain text stays a substring, as upstream.
34
+ var glob = globPattern(n)
35
+ if (glob !== null)
36
+ return glob.test(h) ? { start: 0, length: h.length } : { start: -1, length: 0 }
37
+ var at = h.toLowerCase().indexOf(n.toLowerCase())
38
+ return at < 0 ? { start: -1, length: 0 } : { start: at, length: n.length }
39
+ }
40
+
41
+ // flea-qml: `*` any run, `?` one character, `[abc]` `[a-z]` `[!a]` `[^a]` a class, `{js,ts}` one of
42
+ // the words, and `\` takes the next character literally; letter case is ignored, as the plain
43
+ // filter ignores it. A `[` or `{` with no close is that character itself. Null for a query with no
44
+ // glob character. Sample input: "*.{js,ts}" matches "app.js" and "types.ts", not "app.json".
45
+ var globCache = { source: null, regex: null }
46
+ function globPattern(query) {
47
+ if (!/[*?[{]/.test(query))
48
+ return null
49
+ if (globCache.source === query)
50
+ return globCache.regex
51
+ var out = "", depth = 0
52
+ for (var i = 0; i < query.length; i++) {
53
+ var c = query.charAt(i)
54
+ if (c === "\\" && i + 1 < query.length) {
55
+ out += escapeRegex(query.charAt(++i))
56
+ } else if (c === "*") {
57
+ out += ".*"
58
+ } else if (c === "?") {
59
+ out += "."
60
+ } else if (c === "[") {
61
+ var close = query.indexOf("]", i + 2)
62
+ if (close < 0) { out += "\\["; continue }
63
+ var body = query.substring(i + 1, close)
64
+ var negate = body.charAt(0) === "!" || body.charAt(0) === "^"
65
+ if (negate) body = body.substring(1)
66
+ out += "[" + (negate ? "^" : "") + body.replace(/[\\\]]/g, "\\$&") + "]"
67
+ i = close
68
+ } else if (c === "{" && query.indexOf("}", i) > i) {
69
+ out += "(?:"
70
+ depth++
71
+ } else if (c === "," && depth > 0) {
72
+ out += "|"
73
+ } else if (c === "}" && depth > 0) {
74
+ out += ")"
75
+ depth--
76
+ } else {
77
+ out += escapeRegex(c)
78
+ }
79
+ }
80
+ var regex = null
81
+ try {
82
+ regex = new RegExp("^" + out + "$", "i")
83
+ } catch (e) {
84
+ // A pattern the engine refuses matches nothing rather than everything.
85
+ regex = /(?!)/
86
+ }
87
+ globCache = { source: query, regex: regex }
88
+ return regex
89
+ }
90
+
91
+ function escapeRegex(c) {
92
+ return /[.*+?^${}()|[\]\\\/]/.test(c) ? "\\" + c : c
93
+ }
@@ -0,0 +1,109 @@
1
+ .pragma library
2
+ .import "Contrast.js" as Contrast
3
+
4
+ // Omarchy Glassy dims its blurred backdrop to 0.75; channels and alpha use whole 8-bit steps.
5
+ var STEPS = 255
6
+ var MIN_ALPHA = Math.ceil(0.75 * STEPS)
7
+ var INK_STEP = 1.25
8
+ // Twenty bisections resolve lightness more finely than one 8-bit colour channel.
9
+ var LIGHTNESS_SEARCH_STEPS = 20
10
+ // Half an 8-bit channel step repairs rounding without skipping the first passing colour.
11
+ var ROUNDING_REPAIR_STEPS = 512
12
+
13
+ function ground(plane, a, backdrop) {
14
+ return Contrast.hexOf(Contrast.over(String(plane), a / STEPS, backdrop))
15
+ }
16
+
17
+ function worst(ink, c, a, planes) {
18
+ var least = Infinity
19
+ var grounds = planes || [c.background, c.surface]
20
+ var brightness = c.blurBrightness === undefined ? 0.75 : c.blurBrightness
21
+ var white = Contrast.hexOf([brightness, brightness, brightness])
22
+ var backdrops = [white, "#000000"]
23
+ for (var p = 0; p < grounds.length; p++)
24
+ for (var b = 0; b < backdrops.length; b++)
25
+ least = Math.min(least, Contrast.ratio(String(ink), ground(grounds[p], a, backdrops[b])))
26
+ return least
27
+ }
28
+
29
+ function direction(c) {
30
+ var fg = Contrast.parse(String(c.foreground)), bg = Contrast.parse(String(c.background))
31
+ return Contrast.luminance(fg[0], fg[1], fg[2]) > Contrast.luminance(bg[0], bg[1], bg[2]) ? [1, 1, 1] : [0, 0, 0]
32
+ }
33
+
34
+ // The R3 lightness walk, including its rounding repair, applied to the live palette rather than a theme-name table.
35
+ function inkHolds(ink, c, a, need, quiet) {
36
+ if (worst(ink, c, a) < need) return false
37
+ if (quiet === undefined) return true
38
+ var x = Contrast.parse(String(ink)), q = Contrast.parse(String(quiet))
39
+ var lx = Contrast.luminance(x[0], x[1], x[2]), lq = Contrast.luminance(q[0], q[1], q[2])
40
+ return direction(c)[0] === 1 ? lx >= lq : lx <= lq
41
+ }
42
+
43
+ function liftInk(ink, c, a, need, quiet) {
44
+ if (inkHolds(ink, c, a, need, quiet)) return String(ink)
45
+ var from = Contrast.parse(String(ink)), to = direction(c), lo = 0, hi = 1
46
+ for (var i = 0; i < LIGHTNESS_SEARCH_STEPS; i++) {
47
+ var mid = (lo + hi) / 2
48
+ if (inkHolds(Contrast.hexOf(Contrast.mix(from, to, mid)), c, a, need, quiet)) hi = mid
49
+ else lo = mid
50
+ }
51
+ for (var t = hi; t <= 1; t += 1 / ROUNDING_REPAIR_STEPS) {
52
+ var hex = Contrast.hexOf(Contrast.mix(from, to, t))
53
+ if (inkHolds(hex, c, a, need, quiet)) return hex
54
+ }
55
+ return Contrast.hexOf(to)
56
+ }
57
+
58
+ function quieter(ink, primary, c) {
59
+ var x = Contrast.parse(String(ink)), fg = Contrast.parse(String(primary))
60
+ var lx = Contrast.luminance(x[0], x[1], x[2]), lf = Contrast.luminance(fg[0], fg[1], fg[2])
61
+ return (direction(c)[0] === 1 ? lx < lf : lx > lf) && Contrast.ratio(String(ink), String(primary)) >= INK_STEP
62
+ }
63
+
64
+ function primaryHolds(primary, c, a, need, muted, metadata) {
65
+ return worst(primary, c, a) >= need && quieter(muted, primary, c) && quieter(metadata, primary, c)
66
+ }
67
+
68
+ // A mode may lift primary ink too, so legible secondary ink never becomes the primary rung.
69
+ function primaryInk(c, a, need, muted, metadata) {
70
+ if (primaryHolds(c.foreground, c, a, need, muted, metadata)) return String(c.foreground)
71
+ var from = Contrast.parse(String(c.foreground)), to = direction(c), lo = 0, hi = 1
72
+ for (var i = 0; i < LIGHTNESS_SEARCH_STEPS; i++) {
73
+ var mid = (lo + hi) / 2
74
+ if (primaryHolds(Contrast.hexOf(Contrast.mix(from, to, mid)), c, a, need, muted, metadata)) hi = mid
75
+ else lo = mid
76
+ }
77
+ for (var t = hi; t <= 1; t += 1 / ROUNDING_REPAIR_STEPS) {
78
+ var hex = Contrast.hexOf(Contrast.mix(from, to, t))
79
+ if (primaryHolds(hex, c, a, need, muted, metadata)) return hex
80
+ }
81
+ return Contrast.hexOf(to)
82
+ }
83
+
84
+ function inks(c, a, need) {
85
+ var muted = liftInk(c.muted, c, a, need), metadata = liftInk(c.metadata, c, a, need)
86
+ var meta = Contrast.parse(metadata), fg = Contrast.parse(String(c.foreground))
87
+ var lm = Contrast.luminance(meta[0], meta[1], meta[2]), lf = Contrast.luminance(fg[0], fg[1], fg[2])
88
+ // Darkening a light palette's foreground put metadata beyond primary, or on it in White; reuse its muted rung.
89
+ if (direction(c)[0] === 1 ? lm >= lf : lm <= lf) metadata = muted
90
+ var primary = primaryInk(c, a, need, muted, metadata)
91
+ return {foreground: primary, muted: muted, metadata: metadata}
92
+ }
93
+
94
+ // One alpha for every main plane in A, raised only if its ink cannot hold the two text rungs.
95
+ function floor(c, need) {
96
+ for (var a = MIN_ALPHA; a < STEPS; a++) {
97
+ var ink = inks(c, a, need)
98
+ if (primaryHolds(ink.foreground, c, a, need, ink.muted, ink.metadata)
99
+ && worst(ink.muted, c, a) >= need && worst(ink.metadata, c, a) >= need) return a
100
+ }
101
+ return STEPS
102
+ }
103
+
104
+ // B keeps the unlifted listing text legible on its own background plane, never thinner than A.
105
+ function listFloor(c, need) {
106
+ var a = STEPS
107
+ while (a > 0 && Math.min(worst(c.muted, c, a - 1, [c.background]), worst(c.metadata, c, a - 1, [c.background])) >= need) a--
108
+ return a
109
+ }