@heycys/gallery 0.0.0-stage → 0.1.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 (806) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +50 -2
  3. package/THIRD-PARTY-NOTICES.md +3303 -0
  4. package/assets/writing-preferences.md +107 -0
  5. package/bin/gallery.mjs +10 -0
  6. package/browser/editor/components/bookmark/icons.mjs +6 -0
  7. package/browser/editor/components/bookmark/index.mjs +80 -0
  8. package/browser/editor/components/bookmark/page.mjs +147 -0
  9. package/browser/editor/components/builders.mjs +19 -0
  10. package/browser/editor/components/callout/index.mjs +64 -0
  11. package/browser/editor/components/code/index.mjs +327 -0
  12. package/browser/editor/components/code/page.mjs +561 -0
  13. package/browser/editor/components/colors.mjs +50 -0
  14. package/browser/editor/components/columns/index.mjs +104 -0
  15. package/browser/editor/components/columns/page.mjs +310 -0
  16. package/browser/editor/components/details/index.mjs +73 -0
  17. package/browser/editor/components/details/page.mjs +86 -0
  18. package/browser/editor/components/dialog/index.mjs +84 -0
  19. package/browser/editor/components/dialog/page.mjs +201 -0
  20. package/browser/editor/components/divider/index.mjs +48 -0
  21. package/browser/editor/components/embed/icons.mjs +11 -0
  22. package/browser/editor/components/embed/index.mjs +123 -0
  23. package/browser/editor/components/embed/page.mjs +309 -0
  24. package/browser/editor/components/figure/index.mjs +87 -0
  25. package/browser/editor/components/figure/page.mjs +42 -0
  26. package/browser/editor/components/file/icons.mjs +14 -0
  27. package/browser/editor/components/file/index.mjs +77 -0
  28. package/browser/editor/components/file/page.mjs +114 -0
  29. package/browser/editor/components/flowchart/add.mjs +123 -0
  30. package/browser/editor/components/flowchart/index.mjs +246 -0
  31. package/browser/editor/components/flowchart/page.mjs +453 -0
  32. package/browser/editor/components/heading/index.mjs +53 -0
  33. package/browser/editor/components/heading/page.mjs +6 -0
  34. package/browser/editor/components/highlight/index.mjs +63 -0
  35. package/browser/editor/components/icon/index.mjs +57 -0
  36. package/browser/editor/components/icon/page.mjs +286 -0
  37. package/browser/editor/components/icons.mjs +48 -0
  38. package/browser/editor/components/image/crop.mjs +189 -0
  39. package/browser/editor/components/image/index.mjs +104 -0
  40. package/browser/editor/components/image/page.mjs +385 -0
  41. package/browser/editor/components/image/viewer.mjs +213 -0
  42. package/browser/editor/components/installed/index.mjs +179 -0
  43. package/browser/editor/components/installed/page.mjs +523 -0
  44. package/browser/editor/components/installed/served.mjs +35 -0
  45. package/browser/editor/components/kit.mjs +67 -0
  46. package/browser/editor/components/list/index.mjs +194 -0
  47. package/browser/editor/components/list/join.mjs +68 -0
  48. package/browser/editor/components/list/numbers.mjs +107 -0
  49. package/browser/editor/components/list/page.mjs +632 -0
  50. package/browser/editor/components/math/index.mjs +88 -0
  51. package/browser/editor/components/math/page.mjs +236 -0
  52. package/browser/editor/components/math/tex-logo.mjs +6 -0
  53. package/browser/editor/components/media/icons.mjs +19 -0
  54. package/browser/editor/components/media/page.mjs +192 -0
  55. package/browser/editor/components/media/parts.mjs +60 -0
  56. package/browser/editor/components/media/size.mjs +20 -0
  57. package/browser/editor/components/media/toolbar.mjs +37 -0
  58. package/browser/editor/components/media/write.mjs +7 -0
  59. package/browser/editor/components/pages.mjs +46 -0
  60. package/browser/editor/components/paragraph/index.mjs +43 -0
  61. package/browser/editor/components/paragraph/page.mjs +52 -0
  62. package/browser/editor/components/placeholder-bar.mjs +17 -0
  63. package/browser/editor/components/placeholder.mjs +128 -0
  64. package/browser/editor/components/quote/index.mjs +33 -0
  65. package/browser/editor/components/registry.mjs +859 -0
  66. package/browser/editor/components/rows.mjs +16 -0
  67. package/browser/editor/components/section/index.mjs +42 -0
  68. package/browser/editor/components/section/page.mjs +141 -0
  69. package/browser/editor/components/set-apart.mjs +24 -0
  70. package/browser/editor/components/sheets/index.mjs +137 -0
  71. package/browser/editor/components/sheets/page.mjs +227 -0
  72. package/browser/editor/components/sheets/pills.mjs +226 -0
  73. package/browser/editor/components/table/grid.mjs +73 -0
  74. package/browser/editor/components/table/index.mjs +308 -0
  75. package/browser/editor/components/table/page.mjs +683 -0
  76. package/browser/editor/components/table/slots.mjs +41 -0
  77. package/browser/editor/components/widget/index.mjs +50 -0
  78. package/browser/editor/page/annotate/anchors.mjs +230 -0
  79. package/browser/editor/page/annotate/card.mjs +102 -0
  80. package/browser/editor/page/annotate/index.mjs +1656 -0
  81. package/browser/editor/page/at-menu/index.mjs +317 -0
  82. package/browser/editor/page/autosave.mjs +1023 -0
  83. package/browser/editor/page/beside.mjs +21 -0
  84. package/browser/editor/page/block-info.mjs +63 -0
  85. package/browser/editor/page/block-menu/colors.mjs +84 -0
  86. package/browser/editor/page/block-menu/index.mjs +217 -0
  87. package/browser/editor/page/blocks.mjs +255 -0
  88. package/browser/editor/page/caret.mjs +682 -0
  89. package/browser/editor/page/changes/bar.mjs +102 -0
  90. package/browser/editor/page/changes/ghost.mjs +206 -0
  91. package/browser/editor/page/changes/gone-words.mjs +94 -0
  92. package/browser/editor/page/changes/index.mjs +447 -0
  93. package/browser/editor/page/changes/words.mjs +27 -0
  94. package/browser/editor/page/chip-fills.mjs +126 -0
  95. package/browser/editor/page/clipboard/import/colors.mjs +192 -0
  96. package/browser/editor/page/clipboard/import/html.mjs +792 -0
  97. package/browser/editor/page/clipboard/import/inline.mjs +232 -0
  98. package/browser/editor/page/clipboard/import/languages.mjs +42 -0
  99. package/browser/editor/page/clipboard/import/markdown.mjs +760 -0
  100. package/browser/editor/page/clipboard/import/math.mjs +100 -0
  101. package/browser/editor/page/clipboard/import/office.mjs +245 -0
  102. package/browser/editor/page/clipboard/import/read.mjs +120 -0
  103. package/browser/editor/page/clipboard/import/rich.mjs +29 -0
  104. package/browser/editor/page/clipboard/import/to-blocks.mjs +290 -0
  105. package/browser/editor/page/clipboard/index.mjs +816 -0
  106. package/browser/editor/page/clipboard/own/blocks.mjs +211 -0
  107. package/browser/editor/page/clipboard/own/chart-keys.mjs +58 -0
  108. package/browser/editor/page/clipboard/own/describe.mjs +124 -0
  109. package/browser/editor/page/clipboard/own/export.mjs +167 -0
  110. package/browser/editor/page/clipboard/own/ids.mjs +39 -0
  111. package/browser/editor/page/clipboard/own/index.mjs +13 -0
  112. package/browser/editor/page/clipboard/own/rules.mjs +44 -0
  113. package/browser/editor/page/clipboard/own/selection.mjs +159 -0
  114. package/browser/editor/page/clipboard/own/writers.mjs +315 -0
  115. package/browser/editor/page/columns/index.mjs +360 -0
  116. package/browser/editor/page/commit.mjs +1813 -0
  117. package/browser/editor/page/conflicts.mjs +249 -0
  118. package/browser/editor/page/convert.mjs +831 -0
  119. package/browser/editor/page/core.mjs +1693 -0
  120. package/browser/editor/page/drag/drop.mjs +307 -0
  121. package/browser/editor/page/drag/index.mjs +351 -0
  122. package/browser/editor/page/drag/preview.mjs +126 -0
  123. package/browser/editor/page/edge-scroll.mjs +50 -0
  124. package/browser/editor/page/editor.mjs +1780 -0
  125. package/browser/editor/page/emoji-picker/emoji-tab.mjs +287 -0
  126. package/browser/editor/page/emoji-picker/glyph-html.mjs +26 -0
  127. package/browser/editor/page/emoji-picker/grid.mjs +81 -0
  128. package/browser/editor/page/emoji-picker/icon-tab.mjs +217 -0
  129. package/browser/editor/page/emoji-picker/icons.mjs +31 -0
  130. package/browser/editor/page/emoji-picker/index.mjs +166 -0
  131. package/browser/editor/page/emoji-picker/styles.mjs +161 -0
  132. package/browser/editor/page/emoji-picker/support.mjs +204 -0
  133. package/browser/editor/page/emoji-picker/upload.mjs +236 -0
  134. package/browser/editor/page/export-report.mjs +23 -0
  135. package/browser/editor/page/fills.mjs +62 -0
  136. package/browser/editor/page/find/index.mjs +107 -0
  137. package/browser/editor/page/flags.mjs +70 -0
  138. package/browser/editor/page/fold/index.mjs +348 -0
  139. package/browser/editor/page/fold/rule.mjs +125 -0
  140. package/browser/editor/page/folded.mjs +23 -0
  141. package/browser/editor/page/format-bar/bar.mjs +449 -0
  142. package/browser/editor/page/format-bar/brush.mjs +77 -0
  143. package/browser/editor/page/format-bar/colors.mjs +46 -0
  144. package/browser/editor/page/format-bar/index.mjs +404 -0
  145. package/browser/editor/page/formula/index.mjs +236 -0
  146. package/browser/editor/page/formula/panel.mjs +336 -0
  147. package/browser/editor/page/formula/symbols.mjs +156 -0
  148. package/browser/editor/page/frame.mjs +74 -0
  149. package/browser/editor/page/frames.mjs +196 -0
  150. package/browser/editor/page/geometry.mjs +402 -0
  151. package/browser/editor/page/gesture.mjs +45 -0
  152. package/browser/editor/page/handle/index.mjs +650 -0
  153. package/browser/editor/page/handle-sizes.mjs +14 -0
  154. package/browser/editor/page/hints/index.mjs +84 -0
  155. package/browser/editor/page/history.mjs +401 -0
  156. package/browser/editor/page/insert/index.mjs +256 -0
  157. package/browser/editor/page/kept.mjs +38 -0
  158. package/browser/editor/page/links/address.mjs +40 -0
  159. package/browser/editor/page/links/index.mjs +866 -0
  160. package/browser/editor/page/links/pages.mjs +131 -0
  161. package/browser/editor/page/links/views.mjs +369 -0
  162. package/browser/editor/page/long-runs.mjs +75 -0
  163. package/browser/editor/page/look.mjs +77 -0
  164. package/browser/editor/page/made.mjs +24 -0
  165. package/browser/editor/page/margin.mjs +373 -0
  166. package/browser/editor/page/markdown/index.mjs +88 -0
  167. package/browser/editor/page/markdown/rules.mjs +33 -0
  168. package/browser/editor/page/marks.mjs +377 -0
  169. package/browser/editor/page/media-menu/index.mjs +158 -0
  170. package/browser/editor/page/menu.mjs +544 -0
  171. package/browser/editor/page/merge.mjs +124 -0
  172. package/browser/editor/page/notices.mjs +142 -0
  173. package/browser/editor/page/offered.mjs +32 -0
  174. package/browser/editor/page/outline/folds.mjs +53 -0
  175. package/browser/editor/page/outline/index.mjs +783 -0
  176. package/browser/editor/page/outline/list.mjs +184 -0
  177. package/browser/editor/page/outline/read.mjs +201 -0
  178. package/browser/editor/page/outline/strip.mjs +287 -0
  179. package/browser/editor/page/outline/tree.mjs +248 -0
  180. package/browser/editor/page/overlay-layer.mjs +227 -0
  181. package/browser/editor/page/overlays.mjs +205 -0
  182. package/browser/editor/page/own.mjs +28 -0
  183. package/browser/editor/page/pads.mjs +71 -0
  184. package/browser/editor/page/page-objects.mjs +105 -0
  185. package/browser/editor/page/panel.mjs +65 -0
  186. package/browser/editor/page/placement.mjs +58 -0
  187. package/browser/editor/page/post.mjs +41 -0
  188. package/browser/editor/page/present-links.mjs +50 -0
  189. package/browser/editor/page/quiet.mjs +48 -0
  190. package/browser/editor/page/resize/index.mjs +327 -0
  191. package/browser/editor/page/select-all/index.mjs +262 -0
  192. package/browser/editor/page/selection/delete.mjs +61 -0
  193. package/browser/editor/page/selection/index.mjs +164 -0
  194. package/browser/editor/page/selection/marquee.mjs +174 -0
  195. package/browser/editor/page/session.mjs +168 -0
  196. package/browser/editor/page/slash-menu/index.mjs +291 -0
  197. package/browser/editor/page/storage.mjs +48 -0
  198. package/browser/editor/page/sync-state.mjs +267 -0
  199. package/browser/editor/page/table/aligns.mjs +29 -0
  200. package/browser/editor/page/table/cell-bar.mjs +141 -0
  201. package/browser/editor/page/table/cells.mjs +527 -0
  202. package/browser/editor/page/table/icons.mjs +40 -0
  203. package/browser/editor/page/table/index.mjs +990 -0
  204. package/browser/editor/page/table/lists.mjs +187 -0
  205. package/browser/editor/page/table/widths.mjs +313 -0
  206. package/browser/editor/page/tex.mjs +32 -0
  207. package/browser/editor/page/text-select/index.mjs +671 -0
  208. package/browser/editor/page/tooltip.mjs +98 -0
  209. package/browser/editor/page/type-grid.mjs +83 -0
  210. package/browser/editor/page/typing/code-edges.mjs +274 -0
  211. package/browser/editor/page/typing/index.mjs +282 -0
  212. package/browser/editor/page/typing/leave.mjs +68 -0
  213. package/browser/editor/page/ui.mjs +160 -0
  214. package/browser/shared/annotations.mjs +569 -0
  215. package/browser/shared/code-folds.mjs +14 -0
  216. package/browser/shared/code-languages.mjs +70 -0
  217. package/browser/shared/code-lines.mjs +30 -0
  218. package/browser/shared/colors.mjs +30 -0
  219. package/browser/shared/component-catalog.mjs +573 -0
  220. package/browser/shared/components/bookmark.mjs +26 -0
  221. package/browser/shared/components/callout.mjs +9 -0
  222. package/browser/shared/components/chart.mjs +20 -0
  223. package/browser/shared/components/code.mjs +37 -0
  224. package/browser/shared/components/columns.mjs +16 -0
  225. package/browser/shared/components/details.mjs +15 -0
  226. package/browser/shared/components/dialog.mjs +28 -0
  227. package/browser/shared/components/diff.mjs +18 -0
  228. package/browser/shared/components/divider.mjs +6 -0
  229. package/browser/shared/components/embed.mjs +25 -0
  230. package/browser/shared/components/figure.mjs +14 -0
  231. package/browser/shared/components/file.mjs +23 -0
  232. package/browser/shared/components/heading.mjs +6 -0
  233. package/browser/shared/components/highlight.mjs +9 -0
  234. package/browser/shared/components/icon.mjs +18 -0
  235. package/browser/shared/components/image.mjs +39 -0
  236. package/browser/shared/components/index.mjs +396 -0
  237. package/browser/shared/components/installed.mjs +232 -0
  238. package/browser/shared/components/list.mjs +146 -0
  239. package/browser/shared/components/math.mjs +49 -0
  240. package/browser/shared/components/mention.mjs +33 -0
  241. package/browser/shared/components/page.mjs +46 -0
  242. package/browser/shared/components/paragraph.mjs +9 -0
  243. package/browser/shared/components/quote.mjs +6 -0
  244. package/browser/shared/components/section.mjs +8 -0
  245. package/browser/shared/components/sheets.mjs +80 -0
  246. package/browser/shared/components/state.mjs +20 -0
  247. package/browser/shared/components/table.mjs +49 -0
  248. package/browser/shared/components/text.mjs +14 -0
  249. package/browser/shared/components/widget.mjs +10 -0
  250. package/browser/shared/copy-ids.mjs +72 -0
  251. package/browser/shared/css-references.mjs +110 -0
  252. package/browser/shared/document-look.mjs +178 -0
  253. package/browser/shared/emoji/custom.mjs +91 -0
  254. package/browser/shared/emoji/data/LICENSE-lucide.txt +43 -0
  255. package/browser/shared/emoji/data/LICENSE-mingcute.txt +202 -0
  256. package/browser/shared/emoji/data/LICENSE-tabler.txt +21 -0
  257. package/browser/shared/emoji/data/README.md +28 -0
  258. package/browser/shared/emoji/data/categories.json +1 -0
  259. package/browser/shared/emoji/data/icons.json +1 -0
  260. package/browser/shared/emoji/data/keywords-en.json +1 -0
  261. package/browser/shared/emoji/data/keywords-zh.json +1 -0
  262. package/browser/shared/emoji/data/names.json +1 -0
  263. package/browser/shared/emoji/data/positions.json +1 -0
  264. package/browser/shared/emoji/data/twemoji-index.json +1 -0
  265. package/browser/shared/emoji/data/twemoji-svg.bin +0 -0
  266. package/browser/shared/emoji/data.mjs +194 -0
  267. package/browser/shared/emoji/emoji.mjs +38 -0
  268. package/browser/shared/emoji/glyphs.mjs +134 -0
  269. package/browser/shared/emoji/icon-value.mjs +91 -0
  270. package/browser/shared/escape.mjs +20 -0
  271. package/browser/shared/export-wrap.mjs +89 -0
  272. package/browser/shared/files.mjs +33 -0
  273. package/browser/shared/html-tree.mjs +59 -0
  274. package/browser/shared/http.mjs +22 -0
  275. package/browser/shared/i18n/en.mjs +1223 -0
  276. package/browser/shared/i18n/index.mjs +132 -0
  277. package/browser/shared/ids.mjs +24 -0
  278. package/browser/shared/import-types.mjs +23 -0
  279. package/browser/shared/inline-spacing.mjs +97 -0
  280. package/browser/shared/layers.mjs +42 -0
  281. package/browser/shared/long-runs.mjs +39 -0
  282. package/browser/shared/media.mjs +162 -0
  283. package/browser/shared/new-names.mjs +67 -0
  284. package/browser/shared/number-reading.mjs +92 -0
  285. package/browser/shared/old-names.mjs +143 -0
  286. package/browser/shared/outline.mjs +194 -0
  287. package/browser/shared/page-address.mjs +140 -0
  288. package/browser/shared/page-links.mjs +86 -0
  289. package/browser/shared/paths.mjs +73 -0
  290. package/browser/shared/preferences.mjs +116 -0
  291. package/browser/shared/preview-server.mjs +247 -0
  292. package/browser/shared/qa-levels.mjs +93 -0
  293. package/browser/shared/reading-place.mjs +91 -0
  294. package/browser/shared/renamed-storage.mjs +220 -0
  295. package/browser/shared/reports.mjs +46 -0
  296. package/browser/shared/search.mjs +85 -0
  297. package/browser/shared/session.mjs +77 -0
  298. package/browser/shared/table-chart.mjs +113 -0
  299. package/browser/shared/table-hides.mjs +120 -0
  300. package/browser/shared/table-slots.mjs +75 -0
  301. package/browser/shared/words.mjs +23 -0
  302. package/browser/shared/workspace-look.mjs +91 -0
  303. package/browser/shared/workspace.mjs +535 -0
  304. package/browser/shared/writing-preferences.mjs +68 -0
  305. package/browser/shared/zoom.mjs +57 -0
  306. package/dist/chunk-2B5E4CDJ.mjs +2 -0
  307. package/dist/chunk-342HXE3Q.mjs +2 -0
  308. package/dist/chunk-3HIRPVLU.mjs +2 -0
  309. package/dist/chunk-43B75J5T.mjs +2 -0
  310. package/dist/chunk-4FS7Z7WR.mjs +2 -0
  311. package/dist/chunk-4K5KC6V2.mjs +2 -0
  312. package/dist/chunk-5L7RYZCL.mjs +2 -0
  313. package/dist/chunk-5MHMDLZD.mjs +4 -0
  314. package/dist/chunk-5ZKJ3H4P.mjs +8 -0
  315. package/dist/chunk-64K7IPLO.mjs +255 -0
  316. package/dist/chunk-6QXGZM36.mjs +8 -0
  317. package/dist/chunk-6RGJOMJP.mjs +16 -0
  318. package/dist/chunk-742D2WWJ.mjs +19 -0
  319. package/dist/chunk-7DTINW6U.mjs +48 -0
  320. package/dist/chunk-A55HN5OK.mjs +2 -0
  321. package/dist/chunk-AGDILNWB.mjs +2 -0
  322. package/dist/chunk-AJ73XJF3.mjs +2 -0
  323. package/dist/chunk-AUZGSZJH.mjs +13 -0
  324. package/dist/chunk-BFE45AKL.mjs +2 -0
  325. package/dist/chunk-BGGDRNYQ.mjs +10 -0
  326. package/dist/chunk-BXO2ZY5P.mjs +2 -0
  327. package/dist/chunk-C564NU2H.mjs +77 -0
  328. package/dist/chunk-CEH4MRCC.mjs +2 -0
  329. package/dist/chunk-CY2FNNAB.mjs +16 -0
  330. package/dist/chunk-DFUDV4LX.mjs +2 -0
  331. package/dist/chunk-DKXG4XDG.mjs +2 -0
  332. package/dist/chunk-E7LWZRXY.mjs +4 -0
  333. package/dist/chunk-EZQ34M3F.mjs +124 -0
  334. package/dist/chunk-EZY3WC6Z.mjs +15 -0
  335. package/dist/chunk-FDLXYYG4.mjs +4 -0
  336. package/dist/chunk-FUKQNOQS.mjs +9 -0
  337. package/dist/chunk-GB5SOYQJ.mjs +7 -0
  338. package/dist/chunk-GRAXKKG4.mjs +2 -0
  339. package/dist/chunk-HYMEEXKN.mjs +4 -0
  340. package/dist/chunk-IVDLMMBD.mjs +2 -0
  341. package/dist/chunk-JPOSLGOC.mjs +6 -0
  342. package/dist/chunk-JVHHHGEA.mjs +3 -0
  343. package/dist/chunk-L3QKH4OK.mjs +26 -0
  344. package/dist/chunk-LAE5NQ4B.mjs +2 -0
  345. package/dist/chunk-LCTHTZIL.mjs +960 -0
  346. package/dist/chunk-LEF6DRCK.mjs +59 -0
  347. package/dist/chunk-LKX55H76.mjs +2 -0
  348. package/dist/chunk-LS4F7JUM.mjs +2 -0
  349. package/dist/chunk-MAFIGVXY.mjs +2 -0
  350. package/dist/chunk-NO5NJCHO.mjs +2 -0
  351. package/dist/chunk-NQPVAU63.mjs +2 -0
  352. package/dist/chunk-NSKUTQ5J.mjs +5 -0
  353. package/dist/chunk-O35FIXRB.mjs +2 -0
  354. package/dist/chunk-P2CAZPDP.mjs +3 -0
  355. package/dist/chunk-PL6GHLGD.mjs +15 -0
  356. package/dist/chunk-QAIHRH3I.mjs +13 -0
  357. package/dist/chunk-QJIR2BLP.mjs +6 -0
  358. package/dist/chunk-QR6A54KJ.mjs +3 -0
  359. package/dist/chunk-QUPLVPB2.mjs +7 -0
  360. package/dist/chunk-R7BNENLY.mjs +4 -0
  361. package/dist/chunk-S6O4UHLC.mjs +2 -0
  362. package/dist/chunk-SGJWQKEI.mjs +2 -0
  363. package/dist/chunk-SYGN7GLU.mjs +2 -0
  364. package/dist/chunk-TMYZB6AV.mjs +2 -0
  365. package/dist/chunk-TX6JH7TR.mjs +2 -0
  366. package/dist/chunk-TYK6VNAB.mjs +10 -0
  367. package/dist/chunk-U3SSPL4K.mjs +8 -0
  368. package/dist/chunk-U6KNPJPR.mjs +2 -0
  369. package/dist/chunk-UALRNVSE.mjs +4 -0
  370. package/dist/chunk-UH4SIXTR.mjs +2 -0
  371. package/dist/chunk-UMHUSOPJ.mjs +2 -0
  372. package/dist/chunk-V3HXVQEM.mjs +2 -0
  373. package/dist/chunk-V5JTW2LH.mjs +27 -0
  374. package/dist/chunk-V5VXUJKG.mjs +2 -0
  375. package/dist/chunk-V6XZ4VIR.mjs +2 -0
  376. package/dist/chunk-VBXMADMP.mjs +2 -0
  377. package/dist/chunk-VNV55RUA.mjs +2 -0
  378. package/dist/chunk-VPD2PS35.mjs +2 -0
  379. package/dist/chunk-W3BGBJQW.mjs +2 -0
  380. package/dist/chunk-W4VKN3GF.mjs +7 -0
  381. package/dist/chunk-W5BXXPDJ.mjs +3 -0
  382. package/dist/chunk-W7XHE4CT.mjs +2 -0
  383. package/dist/chunk-XNROSH2T.mjs +4 -0
  384. package/dist/chunk-XUNHRCOG.mjs +6 -0
  385. package/dist/chunk-Y34NR5JL.mjs +2 -0
  386. package/dist/chunk-Y6RLRPG3.mjs +3 -0
  387. package/dist/chunk-YEY3RSFQ.mjs +2 -0
  388. package/dist/cli.mjs +2 -0
  389. package/dist/server.mjs +2 -0
  390. package/dist/worker.mjs +5 -0
  391. package/kit/charts.js +355 -0
  392. package/kit/code.js +164 -0
  393. package/kit/dialogs.js +157 -0
  394. package/kit/math.js +2004 -0
  395. package/kit/report.css +2932 -0
  396. package/kit/runtime.js +1782 -0
  397. package/kit/sheets.js +123 -0
  398. package/kit/state.js +217 -0
  399. package/kit/tables.js +1499 -0
  400. package/kit/tokens.js +29 -0
  401. package/kit/ui.js +658 -0
  402. package/package.json +41 -4
  403. package/release.json +25 -0
  404. package/sdk/column-widths.d.ts +56 -0
  405. package/sdk/doc-charts.d.ts +82 -0
  406. package/sdk/doc-code.d.ts +28 -0
  407. package/sdk/doc-dialogs.d.ts +4 -0
  408. package/sdk/doc-kit.d.ts +147 -0
  409. package/sdk/doc-math.d.ts +3 -0
  410. package/sdk/doc-sheets.d.ts +15 -0
  411. package/sdk/doc-state.d.ts +41 -0
  412. package/sdk/doc-tables.d.ts +24 -0
  413. package/sdk/doc-tokens.d.ts +22 -0
  414. package/sdk/index.d.ts +30 -0
  415. package/skill/SKILL.md +150 -0
  416. package/skill/agents/openai.yaml +5 -0
  417. package/skill/references/building-components.md +367 -0
  418. package/skill/references/example-report.html +356 -0
  419. package/skill/references/writing-html.md +187 -0
  420. package/skill/sdk/column-widths.d.ts +56 -0
  421. package/skill/sdk/doc-charts.d.ts +82 -0
  422. package/skill/sdk/doc-code.d.ts +28 -0
  423. package/skill/sdk/doc-dialogs.d.ts +4 -0
  424. package/skill/sdk/doc-kit.d.ts +147 -0
  425. package/skill/sdk/doc-math.d.ts +3 -0
  426. package/skill/sdk/doc-sheets.d.ts +15 -0
  427. package/skill/sdk/doc-state.d.ts +41 -0
  428. package/skill/sdk/doc-tables.d.ts +24 -0
  429. package/skill/sdk/doc-tokens.d.ts +22 -0
  430. package/skill/sdk/index.d.ts +30 -0
  431. package/starter/doc.html +21 -0
  432. package/starter/doc.json +5 -0
  433. package/vendor/d3.v7.9.0.min.js +2 -0
  434. package/vendor/katex/auto-render.min.js +1 -0
  435. package/vendor/katex/contrib/mhchem.min.js +1 -0
  436. package/vendor/katex/fonts/KaTeX_AMS-Regular.woff2 +0 -0
  437. package/vendor/katex/fonts/KaTeX_Caligraphic-Bold.woff2 +0 -0
  438. package/vendor/katex/fonts/KaTeX_Caligraphic-Regular.woff2 +0 -0
  439. package/vendor/katex/fonts/KaTeX_Fraktur-Bold.woff2 +0 -0
  440. package/vendor/katex/fonts/KaTeX_Fraktur-Regular.woff2 +0 -0
  441. package/vendor/katex/fonts/KaTeX_Main-Bold.woff2 +0 -0
  442. package/vendor/katex/fonts/KaTeX_Main-BoldItalic.woff2 +0 -0
  443. package/vendor/katex/fonts/KaTeX_Main-Italic.woff2 +0 -0
  444. package/vendor/katex/fonts/KaTeX_Main-Regular.woff2 +0 -0
  445. package/vendor/katex/fonts/KaTeX_Math-BoldItalic.woff2 +0 -0
  446. package/vendor/katex/fonts/KaTeX_Math-Italic.woff2 +0 -0
  447. package/vendor/katex/fonts/KaTeX_SansSerif-Bold.woff2 +0 -0
  448. package/vendor/katex/fonts/KaTeX_SansSerif-Italic.woff2 +0 -0
  449. package/vendor/katex/fonts/KaTeX_SansSerif-Regular.woff2 +0 -0
  450. package/vendor/katex/fonts/KaTeX_Script-Regular.woff2 +0 -0
  451. package/vendor/katex/fonts/KaTeX_Size1-Regular.woff2 +0 -0
  452. package/vendor/katex/fonts/KaTeX_Size2-Regular.woff2 +0 -0
  453. package/vendor/katex/fonts/KaTeX_Size3-Regular.woff2 +0 -0
  454. package/vendor/katex/fonts/KaTeX_Size4-Regular.woff2 +0 -0
  455. package/vendor/katex/fonts/KaTeX_Typewriter-Regular.woff2 +0 -0
  456. package/vendor/katex/katex.min.css +1 -0
  457. package/vendor/katex/katex.min.js +1 -0
  458. package/vendor/pdfjs/LICENSE +177 -0
  459. package/vendor/pdfjs/cmaps/78-EUC-H.bcmap +0 -0
  460. package/vendor/pdfjs/cmaps/78-EUC-V.bcmap +0 -0
  461. package/vendor/pdfjs/cmaps/78-H.bcmap +0 -0
  462. package/vendor/pdfjs/cmaps/78-RKSJ-H.bcmap +0 -0
  463. package/vendor/pdfjs/cmaps/78-RKSJ-V.bcmap +0 -0
  464. package/vendor/pdfjs/cmaps/78-V.bcmap +0 -0
  465. package/vendor/pdfjs/cmaps/78ms-RKSJ-H.bcmap +0 -0
  466. package/vendor/pdfjs/cmaps/78ms-RKSJ-V.bcmap +0 -0
  467. package/vendor/pdfjs/cmaps/83pv-RKSJ-H.bcmap +0 -0
  468. package/vendor/pdfjs/cmaps/90ms-RKSJ-H.bcmap +0 -0
  469. package/vendor/pdfjs/cmaps/90ms-RKSJ-V.bcmap +0 -0
  470. package/vendor/pdfjs/cmaps/90msp-RKSJ-H.bcmap +0 -0
  471. package/vendor/pdfjs/cmaps/90msp-RKSJ-V.bcmap +0 -0
  472. package/vendor/pdfjs/cmaps/90pv-RKSJ-H.bcmap +0 -0
  473. package/vendor/pdfjs/cmaps/90pv-RKSJ-V.bcmap +0 -0
  474. package/vendor/pdfjs/cmaps/Add-H.bcmap +0 -0
  475. package/vendor/pdfjs/cmaps/Add-RKSJ-H.bcmap +0 -0
  476. package/vendor/pdfjs/cmaps/Add-RKSJ-V.bcmap +0 -0
  477. package/vendor/pdfjs/cmaps/Add-V.bcmap +0 -0
  478. package/vendor/pdfjs/cmaps/Adobe-CNS1-0.bcmap +0 -0
  479. package/vendor/pdfjs/cmaps/Adobe-CNS1-1.bcmap +0 -0
  480. package/vendor/pdfjs/cmaps/Adobe-CNS1-2.bcmap +0 -0
  481. package/vendor/pdfjs/cmaps/Adobe-CNS1-3.bcmap +0 -0
  482. package/vendor/pdfjs/cmaps/Adobe-CNS1-4.bcmap +0 -0
  483. package/vendor/pdfjs/cmaps/Adobe-CNS1-5.bcmap +0 -0
  484. package/vendor/pdfjs/cmaps/Adobe-CNS1-6.bcmap +0 -0
  485. package/vendor/pdfjs/cmaps/Adobe-CNS1-UCS2.bcmap +0 -0
  486. package/vendor/pdfjs/cmaps/Adobe-GB1-0.bcmap +0 -0
  487. package/vendor/pdfjs/cmaps/Adobe-GB1-1.bcmap +0 -0
  488. package/vendor/pdfjs/cmaps/Adobe-GB1-2.bcmap +0 -0
  489. package/vendor/pdfjs/cmaps/Adobe-GB1-3.bcmap +0 -0
  490. package/vendor/pdfjs/cmaps/Adobe-GB1-4.bcmap +0 -0
  491. package/vendor/pdfjs/cmaps/Adobe-GB1-5.bcmap +0 -0
  492. package/vendor/pdfjs/cmaps/Adobe-GB1-UCS2.bcmap +0 -0
  493. package/vendor/pdfjs/cmaps/Adobe-Japan1-0.bcmap +0 -0
  494. package/vendor/pdfjs/cmaps/Adobe-Japan1-1.bcmap +0 -0
  495. package/vendor/pdfjs/cmaps/Adobe-Japan1-2.bcmap +0 -0
  496. package/vendor/pdfjs/cmaps/Adobe-Japan1-3.bcmap +0 -0
  497. package/vendor/pdfjs/cmaps/Adobe-Japan1-4.bcmap +0 -0
  498. package/vendor/pdfjs/cmaps/Adobe-Japan1-5.bcmap +0 -0
  499. package/vendor/pdfjs/cmaps/Adobe-Japan1-6.bcmap +0 -0
  500. package/vendor/pdfjs/cmaps/Adobe-Japan1-UCS2.bcmap +0 -0
  501. package/vendor/pdfjs/cmaps/Adobe-Korea1-0.bcmap +0 -0
  502. package/vendor/pdfjs/cmaps/Adobe-Korea1-1.bcmap +0 -0
  503. package/vendor/pdfjs/cmaps/Adobe-Korea1-2.bcmap +0 -0
  504. package/vendor/pdfjs/cmaps/Adobe-Korea1-UCS2.bcmap +0 -0
  505. package/vendor/pdfjs/cmaps/B5-H.bcmap +0 -0
  506. package/vendor/pdfjs/cmaps/B5-V.bcmap +0 -0
  507. package/vendor/pdfjs/cmaps/B5pc-H.bcmap +0 -0
  508. package/vendor/pdfjs/cmaps/B5pc-V.bcmap +0 -0
  509. package/vendor/pdfjs/cmaps/CNS-EUC-H.bcmap +0 -0
  510. package/vendor/pdfjs/cmaps/CNS-EUC-V.bcmap +0 -0
  511. package/vendor/pdfjs/cmaps/CNS1-H.bcmap +0 -0
  512. package/vendor/pdfjs/cmaps/CNS1-V.bcmap +0 -0
  513. package/vendor/pdfjs/cmaps/CNS2-H.bcmap +0 -0
  514. package/vendor/pdfjs/cmaps/CNS2-V.bcmap +3 -0
  515. package/vendor/pdfjs/cmaps/ETHK-B5-H.bcmap +0 -0
  516. package/vendor/pdfjs/cmaps/ETHK-B5-V.bcmap +0 -0
  517. package/vendor/pdfjs/cmaps/ETen-B5-H.bcmap +0 -0
  518. package/vendor/pdfjs/cmaps/ETen-B5-V.bcmap +0 -0
  519. package/vendor/pdfjs/cmaps/ETenms-B5-H.bcmap +3 -0
  520. package/vendor/pdfjs/cmaps/ETenms-B5-V.bcmap +0 -0
  521. package/vendor/pdfjs/cmaps/EUC-H.bcmap +0 -0
  522. package/vendor/pdfjs/cmaps/EUC-V.bcmap +0 -0
  523. package/vendor/pdfjs/cmaps/Ext-H.bcmap +0 -0
  524. package/vendor/pdfjs/cmaps/Ext-RKSJ-H.bcmap +0 -0
  525. package/vendor/pdfjs/cmaps/Ext-RKSJ-V.bcmap +0 -0
  526. package/vendor/pdfjs/cmaps/Ext-V.bcmap +0 -0
  527. package/vendor/pdfjs/cmaps/GB-EUC-H.bcmap +0 -0
  528. package/vendor/pdfjs/cmaps/GB-EUC-V.bcmap +0 -0
  529. package/vendor/pdfjs/cmaps/GB-H.bcmap +4 -0
  530. package/vendor/pdfjs/cmaps/GB-V.bcmap +0 -0
  531. package/vendor/pdfjs/cmaps/GBK-EUC-H.bcmap +0 -0
  532. package/vendor/pdfjs/cmaps/GBK-EUC-V.bcmap +0 -0
  533. package/vendor/pdfjs/cmaps/GBK2K-H.bcmap +0 -0
  534. package/vendor/pdfjs/cmaps/GBK2K-V.bcmap +0 -0
  535. package/vendor/pdfjs/cmaps/GBKp-EUC-H.bcmap +0 -0
  536. package/vendor/pdfjs/cmaps/GBKp-EUC-V.bcmap +0 -0
  537. package/vendor/pdfjs/cmaps/GBT-EUC-H.bcmap +0 -0
  538. package/vendor/pdfjs/cmaps/GBT-EUC-V.bcmap +0 -0
  539. package/vendor/pdfjs/cmaps/GBT-H.bcmap +0 -0
  540. package/vendor/pdfjs/cmaps/GBT-V.bcmap +0 -0
  541. package/vendor/pdfjs/cmaps/GBTpc-EUC-H.bcmap +0 -0
  542. package/vendor/pdfjs/cmaps/GBTpc-EUC-V.bcmap +0 -0
  543. package/vendor/pdfjs/cmaps/GBpc-EUC-H.bcmap +0 -0
  544. package/vendor/pdfjs/cmaps/GBpc-EUC-V.bcmap +0 -0
  545. package/vendor/pdfjs/cmaps/H.bcmap +0 -0
  546. package/vendor/pdfjs/cmaps/HKdla-B5-H.bcmap +0 -0
  547. package/vendor/pdfjs/cmaps/HKdla-B5-V.bcmap +0 -0
  548. package/vendor/pdfjs/cmaps/HKdlb-B5-H.bcmap +0 -0
  549. package/vendor/pdfjs/cmaps/HKdlb-B5-V.bcmap +0 -0
  550. package/vendor/pdfjs/cmaps/HKgccs-B5-H.bcmap +0 -0
  551. package/vendor/pdfjs/cmaps/HKgccs-B5-V.bcmap +0 -0
  552. package/vendor/pdfjs/cmaps/HKm314-B5-H.bcmap +0 -0
  553. package/vendor/pdfjs/cmaps/HKm314-B5-V.bcmap +0 -0
  554. package/vendor/pdfjs/cmaps/HKm471-B5-H.bcmap +0 -0
  555. package/vendor/pdfjs/cmaps/HKm471-B5-V.bcmap +0 -0
  556. package/vendor/pdfjs/cmaps/HKscs-B5-H.bcmap +0 -0
  557. package/vendor/pdfjs/cmaps/HKscs-B5-V.bcmap +0 -0
  558. package/vendor/pdfjs/cmaps/Hankaku.bcmap +0 -0
  559. package/vendor/pdfjs/cmaps/Hiragana.bcmap +0 -0
  560. package/vendor/pdfjs/cmaps/KSC-EUC-H.bcmap +0 -0
  561. package/vendor/pdfjs/cmaps/KSC-EUC-V.bcmap +0 -0
  562. package/vendor/pdfjs/cmaps/KSC-H.bcmap +0 -0
  563. package/vendor/pdfjs/cmaps/KSC-Johab-H.bcmap +0 -0
  564. package/vendor/pdfjs/cmaps/KSC-Johab-V.bcmap +0 -0
  565. package/vendor/pdfjs/cmaps/KSC-V.bcmap +0 -0
  566. package/vendor/pdfjs/cmaps/KSCms-UHC-H.bcmap +0 -0
  567. package/vendor/pdfjs/cmaps/KSCms-UHC-HW-H.bcmap +0 -0
  568. package/vendor/pdfjs/cmaps/KSCms-UHC-HW-V.bcmap +0 -0
  569. package/vendor/pdfjs/cmaps/KSCms-UHC-V.bcmap +0 -0
  570. package/vendor/pdfjs/cmaps/KSCpc-EUC-H.bcmap +0 -0
  571. package/vendor/pdfjs/cmaps/KSCpc-EUC-V.bcmap +0 -0
  572. package/vendor/pdfjs/cmaps/Katakana.bcmap +0 -0
  573. package/vendor/pdfjs/cmaps/LICENSE +36 -0
  574. package/vendor/pdfjs/cmaps/NWP-H.bcmap +0 -0
  575. package/vendor/pdfjs/cmaps/NWP-V.bcmap +0 -0
  576. package/vendor/pdfjs/cmaps/RKSJ-H.bcmap +0 -0
  577. package/vendor/pdfjs/cmaps/RKSJ-V.bcmap +0 -0
  578. package/vendor/pdfjs/cmaps/Roman.bcmap +0 -0
  579. package/vendor/pdfjs/cmaps/UniCNS-UCS2-H.bcmap +0 -0
  580. package/vendor/pdfjs/cmaps/UniCNS-UCS2-V.bcmap +0 -0
  581. package/vendor/pdfjs/cmaps/UniCNS-UTF16-H.bcmap +0 -0
  582. package/vendor/pdfjs/cmaps/UniCNS-UTF16-V.bcmap +0 -0
  583. package/vendor/pdfjs/cmaps/UniCNS-UTF32-H.bcmap +0 -0
  584. package/vendor/pdfjs/cmaps/UniCNS-UTF32-V.bcmap +0 -0
  585. package/vendor/pdfjs/cmaps/UniCNS-UTF8-H.bcmap +0 -0
  586. package/vendor/pdfjs/cmaps/UniCNS-UTF8-V.bcmap +0 -0
  587. package/vendor/pdfjs/cmaps/UniGB-UCS2-H.bcmap +0 -0
  588. package/vendor/pdfjs/cmaps/UniGB-UCS2-V.bcmap +0 -0
  589. package/vendor/pdfjs/cmaps/UniGB-UTF16-H.bcmap +0 -0
  590. package/vendor/pdfjs/cmaps/UniGB-UTF16-V.bcmap +0 -0
  591. package/vendor/pdfjs/cmaps/UniGB-UTF32-H.bcmap +0 -0
  592. package/vendor/pdfjs/cmaps/UniGB-UTF32-V.bcmap +0 -0
  593. package/vendor/pdfjs/cmaps/UniGB-UTF8-H.bcmap +0 -0
  594. package/vendor/pdfjs/cmaps/UniGB-UTF8-V.bcmap +0 -0
  595. package/vendor/pdfjs/cmaps/UniJIS-UCS2-H.bcmap +0 -0
  596. package/vendor/pdfjs/cmaps/UniJIS-UCS2-HW-H.bcmap +0 -0
  597. package/vendor/pdfjs/cmaps/UniJIS-UCS2-HW-V.bcmap +0 -0
  598. package/vendor/pdfjs/cmaps/UniJIS-UCS2-V.bcmap +0 -0
  599. package/vendor/pdfjs/cmaps/UniJIS-UTF16-H.bcmap +0 -0
  600. package/vendor/pdfjs/cmaps/UniJIS-UTF16-V.bcmap +0 -0
  601. package/vendor/pdfjs/cmaps/UniJIS-UTF32-H.bcmap +0 -0
  602. package/vendor/pdfjs/cmaps/UniJIS-UTF32-V.bcmap +0 -0
  603. package/vendor/pdfjs/cmaps/UniJIS-UTF8-H.bcmap +0 -0
  604. package/vendor/pdfjs/cmaps/UniJIS-UTF8-V.bcmap +0 -0
  605. package/vendor/pdfjs/cmaps/UniJIS2004-UTF16-H.bcmap +0 -0
  606. package/vendor/pdfjs/cmaps/UniJIS2004-UTF16-V.bcmap +0 -0
  607. package/vendor/pdfjs/cmaps/UniJIS2004-UTF32-H.bcmap +0 -0
  608. package/vendor/pdfjs/cmaps/UniJIS2004-UTF32-V.bcmap +0 -0
  609. package/vendor/pdfjs/cmaps/UniJIS2004-UTF8-H.bcmap +0 -0
  610. package/vendor/pdfjs/cmaps/UniJIS2004-UTF8-V.bcmap +0 -0
  611. package/vendor/pdfjs/cmaps/UniJISPro-UCS2-HW-V.bcmap +0 -0
  612. package/vendor/pdfjs/cmaps/UniJISPro-UCS2-V.bcmap +0 -0
  613. package/vendor/pdfjs/cmaps/UniJISPro-UTF8-V.bcmap +0 -0
  614. package/vendor/pdfjs/cmaps/UniJISX0213-UTF32-H.bcmap +0 -0
  615. package/vendor/pdfjs/cmaps/UniJISX0213-UTF32-V.bcmap +0 -0
  616. package/vendor/pdfjs/cmaps/UniJISX02132004-UTF32-H.bcmap +0 -0
  617. package/vendor/pdfjs/cmaps/UniJISX02132004-UTF32-V.bcmap +0 -0
  618. package/vendor/pdfjs/cmaps/UniKS-UCS2-H.bcmap +0 -0
  619. package/vendor/pdfjs/cmaps/UniKS-UCS2-V.bcmap +0 -0
  620. package/vendor/pdfjs/cmaps/UniKS-UTF16-H.bcmap +0 -0
  621. package/vendor/pdfjs/cmaps/UniKS-UTF16-V.bcmap +0 -0
  622. package/vendor/pdfjs/cmaps/UniKS-UTF32-H.bcmap +0 -0
  623. package/vendor/pdfjs/cmaps/UniKS-UTF32-V.bcmap +0 -0
  624. package/vendor/pdfjs/cmaps/UniKS-UTF8-H.bcmap +0 -0
  625. package/vendor/pdfjs/cmaps/UniKS-UTF8-V.bcmap +0 -0
  626. package/vendor/pdfjs/cmaps/V.bcmap +0 -0
  627. package/vendor/pdfjs/cmaps/WP-Symbol.bcmap +0 -0
  628. package/vendor/pdfjs/legacy/build/pdf.min.mjs +27 -0
  629. package/vendor/pdfjs/legacy/build/pdf.worker.min.mjs +27 -0
  630. package/vendor/pdfjs/standard_fonts/FoxitDingbats.pfb +0 -0
  631. package/vendor/pdfjs/standard_fonts/FoxitFixed.pfb +0 -0
  632. package/vendor/pdfjs/standard_fonts/FoxitFixedBold.pfb +0 -0
  633. package/vendor/pdfjs/standard_fonts/FoxitFixedBoldItalic.pfb +0 -0
  634. package/vendor/pdfjs/standard_fonts/FoxitFixedItalic.pfb +0 -0
  635. package/vendor/pdfjs/standard_fonts/FoxitSerif.pfb +0 -0
  636. package/vendor/pdfjs/standard_fonts/FoxitSerifBold.pfb +0 -0
  637. package/vendor/pdfjs/standard_fonts/FoxitSerifBoldItalic.pfb +0 -0
  638. package/vendor/pdfjs/standard_fonts/FoxitSerifItalic.pfb +0 -0
  639. package/vendor/pdfjs/standard_fonts/FoxitSymbol.pfb +0 -0
  640. package/vendor/pdfjs/standard_fonts/LICENSE_FOXIT +27 -0
  641. package/vendor/pdfjs/standard_fonts/LICENSE_LIBERATION +363 -0
  642. package/vendor/pdfjs/standard_fonts/LiberationSans-Bold.ttf +0 -0
  643. package/vendor/pdfjs/standard_fonts/LiberationSans-BoldItalic.ttf +0 -0
  644. package/vendor/pdfjs/standard_fonts/LiberationSans-Italic.ttf +0 -0
  645. package/vendor/pdfjs/standard_fonts/LiberationSans-Regular.ttf +0 -0
  646. package/vendor/types/@types/d3/LICENSE +21 -0
  647. package/vendor/types/@types/d3/index.d.ts +39 -0
  648. package/vendor/types/@types/d3/package.json +81 -0
  649. package/vendor/types/@types/d3-array/LICENSE +21 -0
  650. package/vendor/types/@types/d3-array/index.d.ts +1118 -0
  651. package/vendor/types/@types/d3-array/package.json +56 -0
  652. package/vendor/types/@types/d3-axis/LICENSE +21 -0
  653. package/vendor/types/@types/d3-axis/index.d.ts +293 -0
  654. package/vendor/types/@types/d3-axis/package.json +47 -0
  655. package/vendor/types/@types/d3-brush/LICENSE +21 -0
  656. package/vendor/types/@types/d3-brush/index.d.ts +255 -0
  657. package/vendor/types/@types/d3-brush/package.json +42 -0
  658. package/vendor/types/@types/d3-chord/LICENSE +21 -0
  659. package/vendor/types/@types/d3-chord/index.d.ts +471 -0
  660. package/vendor/types/@types/d3-chord/package.json +40 -0
  661. package/vendor/types/@types/d3-color/LICENSE +21 -0
  662. package/vendor/types/@types/d3-color/index.d.ts +669 -0
  663. package/vendor/types/@types/d3-color/package.json +55 -0
  664. package/vendor/types/@types/d3-contour/LICENSE +21 -0
  665. package/vendor/types/@types/d3-contour/index.d.ts +222 -0
  666. package/vendor/types/@types/d3-contour/package.json +38 -0
  667. package/vendor/types/@types/d3-delaunay/LICENSE +21 -0
  668. package/vendor/types/@types/d3-delaunay/index.d.ts +316 -0
  669. package/vendor/types/@types/d3-delaunay/package.json +30 -0
  670. package/vendor/types/@types/d3-dispatch/LICENSE +21 -0
  671. package/vendor/types/@types/d3-dispatch/index.d.ts +96 -0
  672. package/vendor/types/@types/d3-dispatch/package.json +51 -0
  673. package/vendor/types/@types/d3-drag/LICENSE +21 -0
  674. package/vendor/types/@types/d3-drag/index.d.ts +395 -0
  675. package/vendor/types/@types/d3-drag/package.json +42 -0
  676. package/vendor/types/@types/d3-dsv/LICENSE +21 -0
  677. package/vendor/types/@types/d3-dsv/index.d.ts +482 -0
  678. package/vendor/types/@types/d3-dsv/package.json +45 -0
  679. package/vendor/types/@types/d3-ease/LICENSE +21 -0
  680. package/vendor/types/@types/d3-ease/index.d.ts +316 -0
  681. package/vendor/types/@types/d3-ease/package.json +40 -0
  682. package/vendor/types/@types/d3-fetch/LICENSE +21 -0
  683. package/vendor/types/@types/d3-fetch/index.d.ts +282 -0
  684. package/vendor/types/@types/d3-fetch/package.json +37 -0
  685. package/vendor/types/@types/d3-force/LICENSE +21 -0
  686. package/vendor/types/@types/d3-force/index.d.ts +899 -0
  687. package/vendor/types/@types/d3-force/package.json +45 -0
  688. package/vendor/types/@types/d3-format/LICENSE +21 -0
  689. package/vendor/types/@types/d3-format/index.d.ts +337 -0
  690. package/vendor/types/@types/d3-format/package.json +45 -0
  691. package/vendor/types/@types/d3-geo/LICENSE +21 -0
  692. package/vendor/types/@types/d3-geo/index.d.ts +1371 -0
  693. package/vendor/types/@types/d3-geo/package.json +48 -0
  694. package/vendor/types/@types/d3-hierarchy/LICENSE +21 -0
  695. package/vendor/types/@types/d3-hierarchy/index.d.ts +928 -0
  696. package/vendor/types/@types/d3-hierarchy/package.json +50 -0
  697. package/vendor/types/@types/d3-interpolate/LICENSE +21 -0
  698. package/vendor/types/@types/d3-interpolate/index.d.ts +387 -0
  699. package/vendor/types/@types/d3-interpolate/package.json +47 -0
  700. package/vendor/types/@types/d3-path/LICENSE +21 -0
  701. package/vendor/types/@types/d3-path/index.d.ts +108 -0
  702. package/vendor/types/@types/d3-path/package.json +41 -0
  703. package/vendor/types/@types/d3-polygon/LICENSE +21 -0
  704. package/vendor/types/@types/d3-polygon/index.d.ts +41 -0
  705. package/vendor/types/@types/d3-polygon/package.json +40 -0
  706. package/vendor/types/@types/d3-quadtree/LICENSE +21 -0
  707. package/vendor/types/@types/d3-quadtree/index.d.ts +204 -0
  708. package/vendor/types/@types/d3-quadtree/package.json +45 -0
  709. package/vendor/types/@types/d3-random/LICENSE +21 -0
  710. package/vendor/types/@types/d3-random/index.d.ts +313 -0
  711. package/vendor/types/@types/d3-random/package.json +41 -0
  712. package/vendor/types/@types/d3-scale/LICENSE +21 -0
  713. package/vendor/types/@types/d3-scale/index.d.ts +2669 -0
  714. package/vendor/types/@types/d3-scale/package.json +53 -0
  715. package/vendor/types/@types/d3-scale-chromatic/LICENSE +21 -0
  716. package/vendor/types/@types/d3-scale-chromatic/index.d.ts +520 -0
  717. package/vendor/types/@types/d3-scale-chromatic/package.json +46 -0
  718. package/vendor/types/@types/d3-selection/LICENSE +21 -0
  719. package/vendor/types/@types/d3-selection/index.d.ts +1210 -0
  720. package/vendor/types/@types/d3-selection/package.json +56 -0
  721. package/vendor/types/@types/d3-shape/LICENSE +21 -0
  722. package/vendor/types/@types/d3-shape/index.d.ts +2792 -0
  723. package/vendor/types/@types/d3-shape/package.json +53 -0
  724. package/vendor/types/@types/d3-time/LICENSE +21 -0
  725. package/vendor/types/@types/d3-time/index.d.ts +697 -0
  726. package/vendor/types/@types/d3-time/package.json +46 -0
  727. package/vendor/types/@types/d3-time-format/LICENSE +21 -0
  728. package/vendor/types/@types/d3-time-format/index.d.ts +202 -0
  729. package/vendor/types/@types/d3-time-format/package.json +40 -0
  730. package/vendor/types/@types/d3-timer/LICENSE +21 -0
  731. package/vendor/types/@types/d3-timer/index.d.ts +68 -0
  732. package/vendor/types/@types/d3-timer/package.json +45 -0
  733. package/vendor/types/@types/d3-transition/LICENSE +21 -0
  734. package/vendor/types/@types/d3-transition/index.d.ts +664 -0
  735. package/vendor/types/@types/d3-transition/package.json +47 -0
  736. package/vendor/types/@types/d3-zoom/LICENSE +21 -0
  737. package/vendor/types/@types/d3-zoom/index.d.ts +611 -0
  738. package/vendor/types/@types/d3-zoom/package.json +48 -0
  739. package/vendor/types/@types/geojson/LICENSE +21 -0
  740. package/vendor/types/@types/geojson/index.d.ts +202 -0
  741. package/vendor/types/@types/geojson/package.json +46 -0
  742. package/vendor/typescript/LICENSE.txt +55 -0
  743. package/vendor/typescript/lib.decorators.d.ts +384 -0
  744. package/vendor/typescript/lib.decorators.legacy.d.ts +22 -0
  745. package/vendor/typescript/lib.dom.d.ts +39429 -0
  746. package/vendor/typescript/lib.dom.iterable.d.ts +571 -0
  747. package/vendor/typescript/lib.es2015.collection.d.ts +147 -0
  748. package/vendor/typescript/lib.es2015.core.d.ts +597 -0
  749. package/vendor/typescript/lib.es2015.d.ts +28 -0
  750. package/vendor/typescript/lib.es2015.generator.d.ts +77 -0
  751. package/vendor/typescript/lib.es2015.iterable.d.ts +605 -0
  752. package/vendor/typescript/lib.es2015.promise.d.ts +81 -0
  753. package/vendor/typescript/lib.es2015.proxy.d.ts +128 -0
  754. package/vendor/typescript/lib.es2015.reflect.d.ts +144 -0
  755. package/vendor/typescript/lib.es2015.symbol.d.ts +46 -0
  756. package/vendor/typescript/lib.es2015.symbol.wellknown.d.ts +326 -0
  757. package/vendor/typescript/lib.es2016.array.include.d.ts +116 -0
  758. package/vendor/typescript/lib.es2016.d.ts +21 -0
  759. package/vendor/typescript/lib.es2016.intl.d.ts +31 -0
  760. package/vendor/typescript/lib.es2017.arraybuffer.d.ts +21 -0
  761. package/vendor/typescript/lib.es2017.d.ts +26 -0
  762. package/vendor/typescript/lib.es2017.date.d.ts +31 -0
  763. package/vendor/typescript/lib.es2017.intl.d.ts +44 -0
  764. package/vendor/typescript/lib.es2017.object.d.ts +49 -0
  765. package/vendor/typescript/lib.es2017.sharedmemory.d.ts +135 -0
  766. package/vendor/typescript/lib.es2017.string.d.ts +45 -0
  767. package/vendor/typescript/lib.es2017.typedarrays.d.ts +53 -0
  768. package/vendor/typescript/lib.es2018.asyncgenerator.d.ts +77 -0
  769. package/vendor/typescript/lib.es2018.asynciterable.d.ts +53 -0
  770. package/vendor/typescript/lib.es2018.d.ts +24 -0
  771. package/vendor/typescript/lib.es2018.intl.d.ts +83 -0
  772. package/vendor/typescript/lib.es2018.promise.d.ts +30 -0
  773. package/vendor/typescript/lib.es2018.regexp.d.ts +37 -0
  774. package/vendor/typescript/lib.es2019.array.d.ts +79 -0
  775. package/vendor/typescript/lib.es2019.d.ts +24 -0
  776. package/vendor/typescript/lib.es2019.intl.d.ts +23 -0
  777. package/vendor/typescript/lib.es2019.object.d.ts +33 -0
  778. package/vendor/typescript/lib.es2019.string.d.ts +37 -0
  779. package/vendor/typescript/lib.es2019.symbol.d.ts +24 -0
  780. package/vendor/typescript/lib.es2020.bigint.d.ts +765 -0
  781. package/vendor/typescript/lib.es2020.d.ts +27 -0
  782. package/vendor/typescript/lib.es2020.date.d.ts +42 -0
  783. package/vendor/typescript/lib.es2020.intl.d.ts +474 -0
  784. package/vendor/typescript/lib.es2020.number.d.ts +28 -0
  785. package/vendor/typescript/lib.es2020.promise.d.ts +47 -0
  786. package/vendor/typescript/lib.es2020.sharedmemory.d.ts +99 -0
  787. package/vendor/typescript/lib.es2020.string.d.ts +44 -0
  788. package/vendor/typescript/lib.es2020.symbol.wellknown.d.ts +41 -0
  789. package/vendor/typescript/lib.es2021.d.ts +23 -0
  790. package/vendor/typescript/lib.es2021.intl.d.ts +166 -0
  791. package/vendor/typescript/lib.es2021.promise.d.ts +48 -0
  792. package/vendor/typescript/lib.es2021.string.d.ts +33 -0
  793. package/vendor/typescript/lib.es2021.weakref.d.ts +78 -0
  794. package/vendor/typescript/lib.es2022.array.d.ts +121 -0
  795. package/vendor/typescript/lib.es2022.d.ts +25 -0
  796. package/vendor/typescript/lib.es2022.error.d.ts +75 -0
  797. package/vendor/typescript/lib.es2022.intl.d.ts +145 -0
  798. package/vendor/typescript/lib.es2022.object.d.ts +26 -0
  799. package/vendor/typescript/lib.es2022.regexp.d.ts +39 -0
  800. package/vendor/typescript/lib.es2022.string.d.ts +25 -0
  801. package/vendor/typescript/lib.es5.d.ts +4601 -0
  802. package/vendor/typescript/package.json +4 -0
  803. package/vendor/typescript/typescript.js +446 -0
  804. package/web/assets/index-Bh74DfsV.css +1 -0
  805. package/web/assets/index-UW0RyFFt.js +13 -0
  806. package/web/index.html +14 -0
@@ -0,0 +1,866 @@
1
+ import { Z } from "../../../shared/layers.mjs";
2
+ import { can, isMention, limitText, mentionOf, newEmptyLink, ownHTML } from "../core.mjs";
3
+ import { editable, followPress, pointRange, select } from "../caret.mjs";
4
+ import { joinMarks, rangeAt, rangeOffsets } from "../marks.mjs";
5
+ import { wholeAddress } from "../clipboard/own/export.mjs";
6
+ import { ICONS, createMenu } from "../menu.mjs";
7
+ import { own } from "../overlays.mjs";
8
+ import { placeBox } from "../placement.mjs";
9
+ import { tooltip } from "../tooltip.mjs";
10
+ import { addStyle, copyAddress, element, fadeIn, mount, swallowNext } from "../ui.mjs";
11
+ import { typedHref } from "./address.mjs";
12
+ import { findPages, heldList, pageRows, placeIn, readPages, titleIn, trashed } from "./pages.mjs";
13
+ import { DIALOG_TRIGGER } from "../../components/dialog/index.mjs";
14
+ import { DIALOG_ICON } from "../../components/icons.mjs";
15
+ import { VIEWS, closeOffer, closeViews, hasViews, hrefOf, isPageChip, offerViews, openViews, pageChip, refetch, viewNodes, viewOf, viewsHold } from "./views.mjs";
16
+ import { t } from "../../../shared/i18n/index.mjs";
17
+ import { referencedFile } from "../../../shared/media.mjs";
18
+ import { decoded, elsewhere, fileLink, fromFile, fullAddress, pageAddress, workbenchHash } from "../../../shared/page-address.mjs";
19
+ import { inTrash } from "../../../shared/page-links.mjs";
20
+
21
+ // Links in the text (docs/editor.md, "Browser side"): the link card that adds, changes or removes a
22
+ // link, and following a link while editing. The card (as Notion's link editor): a field for the
23
+ // address (a blue ring while it has the focus), a button that copies it and one that takes the link
24
+ // away; for a link to a web page, after a line, the view it is shown in with ▾ (Feishu's 链接视图 ▾:
25
+ // its views, views.mjs). Ctrl+K or the format bar's link button opens it below the selected text,
26
+ // the field taking the focus while the text stays marked (the selection's own color, drawn over
27
+ // it); resting on a link in the text for 0.6s opens it below the link, the focus staying where it
28
+ // was, unless something else is open that a press would close. What is typed in the field looks for
29
+ // a page (pages.mjs), its results under the field, in the card; what is pasted looks for nothing, so
30
+ // that an address pasted stays one. ↑/↓ move in them, and a row clicked or Enter links to its page.
31
+ // Enter takes the row the keys moved to, else what reads as a whole address, else the first row, and
32
+ // with no row says so, the card staying; a press anywhere else keeps what the field says when that is
33
+ // an address, and gives up words that are none; an emptied field takes the link away; Esc gives up. A
34
+ // link to a document shows the document's title, the card keeping the link's own address beside
35
+ // it: left as it is, nothing changes, and 复制 copies the address that opens it from anywhere. Resting
36
+ // is a pointer's that moved onto the link: one that came under a still pointer opens nothing. A card
37
+ // opened by resting goes again 0.3s after the pointer leaves the link and the card (and its views),
38
+ // unless its field was clicked. A
39
+ // plain click on a link opens it, as for a reader: in a new tab, in front of the page (one to a file
40
+ // of the report's folder, which the text writes assets/… as the file does, where the preview hands
41
+ // the file out), a link to a detail card (href="#dialog id") by opening the card, one to a block of
42
+ // the page (#<block id>) by going to it or saying it is gone, one to a document of the workspace or
43
+ // a block of one, in any form an address takes (shared/page-address.mjs), by going there in this
44
+ // tab (`go`, the editor's), one with no address not at all; an address on another port is asked of
45
+ // the list, a document's if it holds it (shared/page-address.mjs addressOn), there on this server,
46
+ // another program's if not, in a new tab as any web address (followElsewhere); a middle click, or Ctrl
47
+ // or ⌘ held, opens it in a tab of its own, a middle click behind the page, which the browser leaves to
48
+ // links outside editable text. The press stays the browser's, so a drag
49
+ // in a link selects its text, and the click that ends it opens nothing, nor does a Shift click (a
50
+ // drag from which selects on as over any text), the second click of a double click, or the press
51
+ // that closes something open: this card being filled in, a formula's editor, a menu or a picker. Its
52
+ // words are edited by going in with the arrow keys; an input method over text that starts in a link
53
+ // keeps the link (compositionEnded). A link outside editable text opens in a new tab too, the page
54
+ // staying (followOutside). A link shown with its icon (图标视图) is a whole, as a formula is: a click
55
+ // opens it, and only resting brings its card; its field changed, the page is read again; taken away,
56
+ // its title stays as text. The "/" menu's 链接 puts a gray 链接 where it goes (as 公式 puts 新公式:
57
+ // core.mjs newEmptyLink, components/placeholder.mjs), tinted while the card asks for the address: Enter makes the link, its address its text, and
58
+ // offers its views at its end (显示为); a press elsewhere makes it too; nothing given, or Esc, leaves
59
+ // the gray 链接 there, a link left empty (written so, shown to no reader), a whole as a character is;
60
+ // a click on it asks for its address again. The "/" menu's 页面 does the same with a gray 页面, for a
61
+ // page block: the same element, a document's address (views.mjs pageChip), its title and icon what
62
+ // the server draws (render/page-chips.mjs); nothing but a click on it, which opens the document, and
63
+ // no card on resting, so that it is deleted to go elsewhere. The card asks in its way: the pages are
64
+ // listed at once, Enter takes the page an address names (another address says it is no page, the
65
+ // card staying), else the row highlighted, and with no row makes a page of the words under this one
66
+ // (a new subpage: 写作偏好, ?solo, has none); a press elsewhere keeps the page an address
67
+ // names and nothing else, leaving the gray 页面. A detail card's entry (a link to it, the kit's chip)
68
+ // has a card of its own instead: 打开 and 移除 (no address: an id is no reader's business; no name:
69
+ // the entry's words are it). Nothing is committed while the card is open (linkPending). connectLinks()
70
+ // gives them what they need from the editor.
71
+
72
+ const STYLE = `
73
+ .ge-link {
74
+ position: fixed; left: 0; top: 0; z-index: ${Z.card}; display: flex; flex-wrap: wrap; align-items: center; gap: 2px; width: 246px; max-width: calc(100vw - 16px); padding: 6px;
75
+ border-radius: 10px; background: var(--ge-bg); color: var(--ge-tx);
76
+ box-shadow: var(--ge-shadow);
77
+ font: 14px/1.2 ui-sans-serif, -apple-system, BlinkMacSystemFont, "Segoe UI", "PingFang SC", "Microsoft YaHei", sans-serif;
78
+ }
79
+ .ge-link[data-views] { width: 346px; }
80
+ .ge-link-field { display: flex; align-items: center; flex: 1; min-width: 0; height: 28px; margin-right: 4px; padding: 3px 6px; border-radius: 6px; background: var(--ge-field); box-shadow: 0 0 0 1px var(--ge-edge); cursor: text; }
81
+ .ge-link-field:focus-within { box-shadow: inset 0 0 0 1px var(--ge-focus), 0 0 0 1px var(--ge-focus); }
82
+ .ge-link-field input { flex: 1; min-width: 0; padding: 0; border: 0; outline: none; background: transparent; color: inherit; font: inherit; line-height: 20px; }
83
+ .ge-link-field input::placeholder { color: var(--ge-tx3); }
84
+ .ge-link-tool { display: flex; align-items: center; justify-content: center; flex: none; width: 28px; height: 28px; padding: 0; border: 0; border-radius: 6px; background: transparent; color: var(--ge-ico); cursor: pointer; transition: background 20ms ease-in; }
85
+ .ge-link-tool:hover, .ge-link-view:hover, .ge-link-view[aria-expanded="true"] { background: var(--ge-hover); }
86
+ .ge-link-tool:active, .ge-link-view:active { background: var(--ge-press); }
87
+ .ge-link-tool svg { display: block; width: 20px; height: 20px; fill: none; stroke: currentColor; stroke-width: 1.25; stroke-linecap: round; stroke-linejoin: round; }
88
+ .ge-link-sep { flex: none; width: 1px; height: 20px; margin: 0 4px; background: var(--ge-line); }
89
+ .ge-link-view { display: flex; align-items: center; gap: 2px; flex: none; height: 28px; padding: 0 4px 0 8px; border: 0; border-radius: 6px; background: transparent; color: inherit; font: inherit; white-space: nowrap; cursor: pointer; transition: background 20ms ease-in; }
90
+ .ge-link-view svg { display: block; width: 16px; height: 16px; fill: none; stroke: var(--ge-tx3); stroke-width: 1.5; stroke-linecap: round; stroke-linejoin: round; }
91
+ .ge-link-mark { position: fixed; left: 0; top: 0; z-index: ${Z.mark}; pointer-events: none; background: var(--ge-select); }
92
+ /* A link in editable text is one to click on, where the browser shows a text cursor. */
93
+ [data-ge-editing] a[href] { cursor: pointer; }
94
+ .ge-link[data-entry] { width: auto; padding: 4px; }
95
+ .ge-link-open { display: flex; align-items: center; gap: 6px; flex: none; height: 28px; padding: 0 8px 0 6px; border: 0; border-radius: 6px; background: transparent; color: inherit; font: inherit; cursor: pointer; transition: background 20ms ease-in; }
96
+ .ge-link-open svg { display: block; width: 18px; height: 18px; fill: none; stroke: var(--ge-ico); stroke-width: 1.25; stroke-linecap: round; stroke-linejoin: round; }
97
+ .ge-link-open:hover { background: var(--ge-hover); }
98
+ .ge-link-open:active { background: var(--ge-press); }
99
+ `;
100
+ const HOVER_DELAY = 600; // resting on a link this long opens its card
101
+ const LEAVE = 300; // a card opened by resting goes this long after the pointer leaves link and card
102
+ const DRAGGED = 4; // a pointer released this far from its press has dragged, not clicked
103
+ const CHEVRON = '<svg viewBox="0 0 16 16" aria-hidden="true"><path d="m4.5 6.25 3.5 3.5 3.5-3.5"/></svg>';
104
+
105
+ let use = null; // { say, recordStep, hideFormatBar, active, served(file), closing(), slug, own(): this page, as pages.mjs readPages takes it, reveal(id), go(place, href), subpage(title): a new page under this one, the answer's report, null where it has none }
106
+
107
+ export function connectLinks(editor) {
108
+ use = editor;
109
+ addStyle(STYLE);
110
+ // Resting on a link in the text opens its card, and only for a pointer that moved there, as on a
111
+ // 批注's marker: a link that came under a still pointer (the next page, shown where a link was just
112
+ // clicked; the page scrolled) hears an over and no move, and its card would stand over the lines
113
+ // below, in the way of the next click. Leaving the link and the card closes it (not while its views
114
+ // are open).
115
+ document.addEventListener("mouseover", (event) => {
116
+ const rested = use.active() && !event.buttons ? linkOf(event.target) : null;
117
+ const link = rested && !isPageChip(rested) ? rested : null; // a page block has no card
118
+ clearTimeout(hoverTimer);
119
+ reached = null;
120
+ if (linkBox && !linkBox.pinned && (linkBox.held || link === linkBox.link || linkBox.node.contains(event.target) || viewsHold(event.target))) return;
121
+ if (linkBox && !linkBox.pinned) hoverTimer = setTimeout(() => closeLink(false), LEAVE);
122
+ reached = link;
123
+ }, true);
124
+ document.addEventListener("mousemove", (event) => {
125
+ const moved = !pointer || pointer.x !== event.clientX || pointer.y !== event.clientY;
126
+ pointer = { x: event.clientX, y: event.clientY };
127
+ if (!moved || !reached || !use.active()) return;
128
+ const link = reached;
129
+ reached = null;
130
+ if (!linkBox?.pinned && linkBox?.link !== link) hoverTimer = setTimeout(() => { if (!use.closing()) openLinkAt(link); }, HOVER_DELAY);
131
+ }, { passive: true, capture: true });
132
+ // What a press came down on, for the click it ends in (opens), on the window to see what it closes
133
+ // before that goes; a press on a link leaves no card on its way to open over a drag.
134
+ addEventListener("pointerdown", (event) => {
135
+ press = { x: event.clientX, y: event.clientY, selection: selectionNow(), keeps: (Boolean(linkBox?.pinned) && !linkHolds(event.target)) || use.closing() };
136
+ if (linkOf(event.target)) {
137
+ clearTimeout(hoverTimer);
138
+ reached = null;
139
+ }
140
+ }, true);
141
+ // Shift on a link in the block of the caret: the selection reaches it and follows the pointer, as
142
+ // over any other text, where the browser moves the caret there.
143
+ document.addEventListener("mousedown", (event) => {
144
+ const host = use.active() && event.button === 0 && event.shiftKey && linkOf(event.target) ? editable(event.target) : null;
145
+ const selection = getSelection();
146
+ const at = host && editable(selection.anchorNode) === host ? pointRange(event.clientX, event.clientY) : null;
147
+ if (!at) return;
148
+ event.preventDefault();
149
+ const from = document.createRange();
150
+ from.setStart(selection.anchorNode, selection.anchorOffset);
151
+ selection.extend(at.startContainer, at.startOffset);
152
+ followPress(host, from);
153
+ }, true);
154
+ // A middle click, which a browser takes for a link only outside editable text: here for all of
155
+ // them (a chip is such a link, and would open twice), its press starting no scrolling by the pointer.
156
+ document.addEventListener("mousedown", (event) => {
157
+ if (event.button === 1 && use.active() && linkOf(event.target)) event.preventDefault();
158
+ }, true);
159
+ document.addEventListener("auxclick", (event) => {
160
+ const link = event.button === 1 && use.active() ? linkOf(event.target) : null;
161
+ if (!link) return;
162
+ event.preventDefault();
163
+ if (leadsAway(link)) follow(hrefOf(link), true);
164
+ }, true);
165
+ // A link shown with its icon is a whole: a press puts no caret in it, and selects nothing with Ctrl
166
+ // or ⌘ held. One left empty asks for its address at a click, here, ahead of the editor's listener,
167
+ // which follows those that have one.
168
+ const chipAt = (target) => {
169
+ const chip = use.active() ? target?.closest?.(".doc-link-mention[data-ge-atom]") : null;
170
+ return chip && editable(chip) ? chip : null;
171
+ };
172
+ document.addEventListener("mousedown", (event) => {
173
+ if (event.button === 0 && !event.shiftKey && chipAt(event.target)) event.preventDefault();
174
+ }, true);
175
+ document.addEventListener("click", (event) => {
176
+ const chip = event.ctrlKey || event.metaKey || event.shiftKey ? null : chipAt(event.target);
177
+ if (!chip?.hasAttribute("data-ge-empty")) return;
178
+ event.preventDefault();
179
+ if (linkBox?.fresh?.chip !== chip) openLinkAt(chip);
180
+ }, true);
181
+ document.addEventListener("click", followOutside);
182
+ document.addEventListener("compositionstart", compositionBegun, true);
183
+ document.addEventListener("compositionend", compositionEnded, true);
184
+ addEventListener("scroll", () => { if (linkBox) linkBox.paint(); }, { passive: true, capture: true });
185
+ addEventListener("resize", () => { if (linkBox) linkBox.paint(); });
186
+ }
187
+
188
+ // ---------- the link card ----------
189
+
190
+ // { node, host, range, link, input, marks, pinned, held (its views open), paint, fresh: the gray 链接 the
191
+ // card asks the address of ({ chip, before, made: the "/" menu's, new }) or null, shown: what the field
192
+ // was given for the link, reading: the reading of the list of pages, once it is asked for, workspace:
193
+ // what it read (pages.mjs readPages; null until then, and for a list that cannot be read), asksPage: it
194
+ // fills a page block, making: a new page is on its way, entered: an Enter waits for the list, pasted:
195
+ // what the field holds was pasted, place(): the card put by the text, tallest: the most it has been high }
196
+ let linkBox = null;
197
+ let results = null; // the pages found, under the field (a menu of the card's, made when first needed)
198
+ let hoverTimer = 0;
199
+ let reached = null; // the link the pointer came over, until a move starts the wait for its card
200
+ let pointer = null; // where the pointer last moved to: { x, y } (a move the browser makes up goes nowhere)
201
+ let pasted = null; // the list of pages being read for what was just pasted
202
+ let press = null; // the last press: { x, y, selection: where it found the selection (selectionNow), keeps: it closes something open, and does no more }
203
+
204
+ /**
205
+ * Close the card; `restore`: the selection goes back to the text it was opened on (after the gray
206
+ * 链接, which stays when given up).
207
+ */
208
+ export function closeLink(restore = true) {
209
+ clearTimeout(hoverTimer);
210
+ closeViews();
211
+ if (!linkBox) return;
212
+ const { node, host, range, marks, fresh } = linkBox;
213
+ results?.close();
214
+ node.remove();
215
+ marks.forEach((mark) => mark.remove());
216
+ linkBox = null;
217
+ if (!host.isConnected) return;
218
+ if (fresh) return leaveEmpty(host, fresh, restore);
219
+ if (restore) {
220
+ host.focus({ preventScroll: true });
221
+ select(range);
222
+ }
223
+ }
224
+
225
+ /** A press outside the card: what its field says is kept, when that is an address (words that are none are given up; a card opened by resting just goes). */
226
+ export function dismissLink() {
227
+ if (!linkBox || linkBox.making) return;
228
+ const typed = linkBox.input.value;
229
+ if (linkBox.asksPage) {
230
+ const page = listed(typedHref(typed.trim()));
231
+ return page ? keepPage(page, false) : closeLink(false);
232
+ }
233
+ if (linkBox.pinned && normalizeHref(typed) !== null) setLink(typed, false);
234
+ else closeLink(false);
235
+ }
236
+
237
+ // Ctrl+K: add a link to the selected text, or change or remove the link under the caret; `fresh`
238
+ // (the "/" menu's 链接): a new link at the caret, a gray 链接 there, its address asked for; with
239
+ // `page` (its 页面) a page block, the gray 页面.
240
+ export function openLink(host, { fresh = false, page = false } = {}) {
241
+ if (!can(host, "links")) {
242
+ use.say(limitText(host, "links"));
243
+ return;
244
+ }
245
+ const selection = getSelection();
246
+ if (!selection.rangeCount) return;
247
+ const range = selection.getRangeAt(0).cloneRange();
248
+ if (fresh) {
249
+ closeLink(false);
250
+ closeOffer();
251
+ const before = ownHTML(host);
252
+ range.deleteContents();
253
+ const chip = newEmptyLink(document, page);
254
+ range.insertNode(chip);
255
+ askAddress(host, chip, before, true);
256
+ return;
257
+ }
258
+ const link = linkAround(host, range);
259
+ if (!link && range.collapsed) {
260
+ use.say(t("先选中要加链接的文字,再按 Ctrl+K。"));
261
+ return;
262
+ }
263
+ if (link && range.collapsed) range.selectNode(link);
264
+ showCard(host, range, link, true);
265
+ }
266
+
267
+ // The card asking the address of a gray 链接 (`made`: just now, by the "/" menu; else one left empty,
268
+ // clicked), `host`'s html `before` it; the chip tinted meanwhile.
269
+ function askAddress(host, chip, before, made) {
270
+ chip.setAttribute("data-ge-link-edit", "");
271
+ const at = document.createRange();
272
+ at.selectNode(chip);
273
+ showCard(host, at, null, true, { chip, before, made });
274
+ }
275
+
276
+ // The gray 链接 given no address stays (one undo step when the "/" menu made it); `restore`: the
277
+ // caret after it.
278
+ function leaveEmpty(host, { chip, before, made }, restore) {
279
+ chip.removeAttribute("data-ge-link-edit");
280
+ if (!chip.isConnected) return;
281
+ if (made) use.recordStep(host, before);
282
+ if (restore) {
283
+ host.focus({ preventScroll: true });
284
+ const after = document.createRange();
285
+ after.setStartAfter(chip);
286
+ after.collapse(true);
287
+ select(after);
288
+ }
289
+ }
290
+
291
+ // Resting on a link: its card, below it; the focus stays where it is until the field is clicked. A
292
+ // link left empty (a click on it): its address asked for.
293
+ function openLinkAt(link) {
294
+ const host = editable(link);
295
+ if (!host || !link.isConnected || !can(host, "links")) return;
296
+ if (link.hasAttribute("data-ge-empty")) {
297
+ closeLink(false);
298
+ closeOffer();
299
+ return askAddress(host, link, ownHTML(host), false);
300
+ }
301
+ const range = document.createRange();
302
+ range.selectNode(link);
303
+ showCard(host, range, link, false);
304
+ }
305
+
306
+ // A button of the card; a press on it leaves the focus where it is (the field keeps it).
307
+ function tool(label, icon, action) {
308
+ const node = element("button", { type: "button", class: "ge-link-tool", "aria-label": label, html: icon });
309
+ node.addEventListener("mousedown", (event) => event.preventDefault());
310
+ node.addEventListener("click", action);
311
+ tooltip(node, label);
312
+ return node;
313
+ }
314
+
315
+ /**
316
+ * Open the detail card a link to it opens (dialogs.js), as a reader's `click` would; the card now
317
+ * under the pointer, or its backdrop, takes no second press of a double click.
318
+ */
319
+ export function openEntry(link, click) {
320
+ const card = targetOf(link);
321
+ if (!(card instanceof HTMLDialogElement)) return;
322
+ swallowNext(click, () => card.open);
323
+ if (globalThis.DocDialogs?.open) globalThis.DocDialogs.open(card, link);
324
+ else card.showModal?.();
325
+ }
326
+
327
+ // A detail card's entry: 打开 and 移除 (the words stay as text; the detail card is no longer saved,
328
+ // core.mjs nodeOf). Below the entry, the focus staying in the text.
329
+ function showEntry(host, range, link) {
330
+ const open = element("button", { type: "button", class: "ge-link-open", html: DIALOG_ICON }, element("span", {}, t("打开")));
331
+ open.addEventListener("mousedown", (event) => event.preventDefault());
332
+ open.addEventListener("click", (event) => {
333
+ closeLink(false);
334
+ openEntry(link, event);
335
+ });
336
+ const remove = tool(t("移除入口"), ICONS.trash, () => setLink(null));
337
+ const node = element("div", { class: "ge-link", role: "dialog", "aria-label": t("详情卡片"), "data-entry": "" }, open, remove);
338
+ tooltip(open, t("打开详情卡片"));
339
+ linkBox = { node, host, range, link, input: { value: hrefOf(link) }, marks: [], pinned: false, held: false, paint: () => {}, fresh: null };
340
+ mount(node);
341
+ fadeIn(node, 120);
342
+ const rect = range.getClientRects()[0] ?? host.getBoundingClientRect();
343
+ const { left, top } = placeBox(rect, { width: node.offsetWidth, height: node.offsetHeight }, { gap: 6 });
344
+ node.style.left = `${Math.round(left)}px`;
345
+ node.style.top = `${Math.round(top)}px`;
346
+ }
347
+
348
+ function showCard(host, range, link, focus, fresh = null) {
349
+ closeLink(false);
350
+ use.hideFormatBar();
351
+ if (link?.classList.contains(DIALOG_TRIGGER) && !fresh) return showEntry(host, range, link);
352
+ const asksPage = fresh?.chip.getAttribute("data-ge-empty") === "page";
353
+ const input = element("input", { type: "text", placeholder: asksPage ? t("输入页面标题") : t("输入链接或页面标题"), "aria-label": asksPage ? t("页面标题") : t("链接地址"), spellcheck: "false" });
354
+ // A link to a document shows its title, once the list is read.
355
+ const toPage = link ? wholeAddress(hrefOf(link)) : null;
356
+ input.value = link && !toPage ? hrefOf(link) : "";
357
+ const copy = tool(t("复制链接"), ICONS.copy, () => copyLink(input.value, link));
358
+ const remove = tool(t("移除链接"), ICONS.trash, () => setLink(null));
359
+ const views = link && hasViews(link) ? viewButton(link) : null;
360
+ const node = element("div", { class: "ge-link", role: "dialog", "aria-label": t("链接") }, element("label", { class: "ge-link-field" }, input), copy, remove);
361
+ if (views) {
362
+ node.setAttribute("data-views", "");
363
+ node.append(element("div", { class: "ge-link-sep", role: "separator" }), views);
364
+ }
365
+ input.addEventListener("keydown", (event) => {
366
+ if (event.isComposing || event.keyCode === 229) return; // an input method's: its letters filter, and its Enter commits them
367
+ if (box.making) event.preventDefault();
368
+ else if (results?.isOpen && results.arrow(event)) event.preventDefault();
369
+ else if (event.key === "Enter") {
370
+ event.preventDefault();
371
+ enterField(box);
372
+ } else if (event.key === "Escape") {
373
+ event.preventDefault();
374
+ event.stopPropagation();
375
+ closeLink();
376
+ }
377
+ });
378
+ // What is typed looks for a page (an input method's letters too, as they come), what is pasted does not.
379
+ input.addEventListener("input", (event) => {
380
+ box.pasted = event.inputType === "insertFromPaste";
381
+ if (!box.pasted) return search(box, event.isComposing);
382
+ results?.close();
383
+ place();
384
+ });
385
+ input.addEventListener("compositionend", () => search(box));
386
+ // Clicking into the field keeps the card until Enter or a press elsewhere.
387
+ input.addEventListener("focus", () => {
388
+ if (!linkBox) return;
389
+ linkBox.pinned = true;
390
+ clearTimeout(hoverTimer);
391
+ readList(linkBox);
392
+ linkBox.paint();
393
+ });
394
+ const marks = [];
395
+ // The text the card is about, marked as the selection is while the field has the focus (not the
396
+ // "/" menu's gray 链接, which shows where it goes).
397
+ const paint = () => {
398
+ marks.forEach((mark) => mark.remove());
399
+ marks.length = 0;
400
+ if (!linkBox?.pinned || linkBox.fresh || !range.startContainer.isConnected) return;
401
+ for (const rect of range.getClientRects()) {
402
+ if (rect.width < 1) continue;
403
+ const mark = mount(own(element("div", { class: "ge-link-mark" }), "link mark", { alive: () => marks.includes(mark) }));
404
+ Object.assign(mark.style, { transform: `translate(${rect.left}px, ${rect.top}px)`, width: `${rect.width}px`, height: `${rect.height}px` });
405
+ marks.push(mark);
406
+ }
407
+ };
408
+ const box = { node, host, range, link, input, marks, pinned: focus, held: false, paint, fresh, asksPage, making: false, entered: false, shown: input.value, reading: null, workspace: null, tallest: 0, place: () => {} };
409
+ linkBox = box;
410
+ mount(node);
411
+ fadeIn(node, 120);
412
+ // Below the text, its left edge with the text's (above it when there is no room below), where the
413
+ // pages found under the field stay clear of the window's end: by the most it has been high in this
414
+ // opening, so that the field does not move back and forth as rows come and go.
415
+ const rect = range.getClientRects()[0] ?? host.getBoundingClientRect();
416
+ const place = () => {
417
+ box.tallest = Math.max(box.tallest, node.offsetHeight);
418
+ const { left, top } = placeBox(rect, { width: node.offsetWidth, height: box.tallest }, { gap: 6 });
419
+ node.style.left = `${Math.round(left)}px`;
420
+ node.style.top = `${Math.round(top)}px`;
421
+ };
422
+ box.place = place;
423
+ place();
424
+ if (focus) {
425
+ input.focus();
426
+ input.select();
427
+ paint();
428
+ }
429
+ if (toPage) readList(box).then(() => {
430
+ if (linkBox !== box || input.value) return;
431
+ input.value = box.shown = titleIn(box.workspace ?? heldList(), fromFile(hrefOf(link), use.slug, location.origin)) || hrefOf(link);
432
+ if (document.activeElement === input) input.select();
433
+ });
434
+ }
435
+
436
+ // The list of pages, read once for each opening of the card (for what is typed in its field, or the
437
+ // title of the page it is about); what was typed before it came is looked for then.
438
+ function readList(box) {
439
+ box.reading ??= readPages(use.own()).then((list) => {
440
+ box.workspace = list;
441
+ if (linkBox === box && (box.asksPage || (box.input.value !== box.shown && !box.pasted))) search(box);
442
+ });
443
+ return box.reading;
444
+ }
445
+
446
+ // The pages the field's words find, in the card under it (a page block's, with no words the first of
447
+ // them): looked for as they are typed (`composing`: an input method's letters, which it may show with
448
+ // its syllables apart, as "/" reads them), the first highlighted unless the words read as an address,
449
+ // which Enter keeps.
450
+ function search(box, composing = false) {
451
+ if (linkBox !== box) return;
452
+ const written = box.input.value;
453
+ const query = (composing ? written.replace(/['\s]/g, "") : written).trim();
454
+ const found = box.workspace && (query || box.asksPage) ? findPages(box.workspace.pages, query) : [];
455
+ if (found.length === 0) {
456
+ results?.close();
457
+ return box.place();
458
+ }
459
+ results ??= createMenu();
460
+ const rows = pageRows(found, (page) => { if (linkBox === box) keepPage(page); });
461
+ const first = Boolean(query) && !normalizeHref(query);
462
+ if (results.isOpen) results.update(rows, undefined, { first });
463
+ else results.open(rows, null, { inside: box.node, label: t("页面"), highlight: first });
464
+ box.place();
465
+ }
466
+
467
+ // Enter in the field, once the list is read (a moment, at the very start, in which another Enter is
468
+ // nothing more): nothing changed for a link
469
+ // left as it was; else the row highlighted (the one the keys moved to, or the first of what is no
470
+ // address); else what reads as an address, or a page block's own rule; else it says so and the card stays.
471
+ async function enterField(box) {
472
+ if (box.entered) return;
473
+ box.entered = true;
474
+ readList(box);
475
+ await box.reading;
476
+ box.entered = false;
477
+ if (linkBox !== box) return;
478
+ const value = box.input.value.trim();
479
+ if (box.link && value === box.shown) return setLink(value);
480
+ if (!results?.isOpen) search(box); // what a paste did not look for
481
+ if (results?.isOpen && results.hasChoice) return void results.choose();
482
+ if (box.asksPage) return enterPage(box, value);
483
+ if (normalizeHref(value) === null && !unsafe(value)) return use.say(t("没有找到这个页面。"), "error");
484
+ setLink(value);
485
+ }
486
+
487
+ // Enter in a page block's field with no row to take: nothing typed is Esc; an address is the page it
488
+ // names, or no page of the workspace, said with the card staying; words found nothing, and make a
489
+ // new page of them under this one, the card holding what was typed until the answer comes. The page
490
+ // stays as it is, the caret too, and undo takes the block away, not the new page. What fails is said,
491
+ // the gray 页面 staying and the card open on the words.
492
+ async function enterPage(box, value) {
493
+ if (!value) return closeLink();
494
+ const address = typedHref(value);
495
+ const page = address && box.workspace ? placeIn(box.workspace, address) : null;
496
+ if (page) return keepPage(page);
497
+ if (address || !use.subpage) return use.say(address ? t("这个地址不是工作区里的页面。") : t("没有找到这个页面。"), "error");
498
+ box.making = box.input.readOnly = true;
499
+ try {
500
+ const report = await use.subpage(value);
501
+ if (linkBox !== box) return;
502
+ keepPage({ ...report, block: null }, document.activeElement === box.input);
503
+ use.say(t("已新建子页面:{0}", report.title));
504
+ } catch (error) {
505
+ box.making = box.input.readOnly = false;
506
+ use.say(error.message, "error");
507
+ }
508
+ }
509
+
510
+ // The card's view button: the link's view and ▾; a click opens its views below it (views.mjs), a
511
+ // pick closing the card and switching the link.
512
+ function viewButton(link) {
513
+ const button = element("button", { type: "button", class: "ge-link-view", "aria-haspopup": "menu", "aria-label": t("显示为"), html: `<span>${VIEWS[viewOf(link)].label}</span>${CHEVRON}` });
514
+ button.addEventListener("mousedown", (event) => event.preventDefault());
515
+ button.addEventListener("click", () => {
516
+ if (button.getAttribute("aria-expanded") === "true") return closeViews();
517
+ if (!linkBox) return;
518
+ linkBox.held = true;
519
+ clearTimeout(hoverTimer);
520
+ button.setAttribute("aria-expanded", "true");
521
+ const rect = button.getBoundingClientRect();
522
+ openViews(link, { left: rect.left, right: rect.right, top: rect.top, bottom: rect.bottom }, () => closeLink(false), () => {
523
+ button.setAttribute("aria-expanded", "false");
524
+ if (linkBox) linkBox.held = false;
525
+ });
526
+ });
527
+ tooltip(button, t("显示为"));
528
+ return button;
529
+ }
530
+
531
+ // What the link leads to, as an address that opens it from anywhere (a document's, a block's), else as it stands.
532
+ function copyLink(value, link) {
533
+ const href = fieldHref(value, link);
534
+ if (!href) return use.say(t("还没有链接地址。"));
535
+ copyAddress(wholeAddress(href) ?? href, use.say);
536
+ }
537
+
538
+ // The link the whole range sits in, if any.
539
+ export function linkAround(host, range) {
540
+ const start = range.commonAncestorContainer;
541
+ const anchor = (start.nodeType === 1 ? start : start.parentElement).closest("a");
542
+ return anchor && host.contains(anchor) ? anchor : null;
543
+ }
544
+
545
+ const unsafe = (value) => /^(javascript|vbscript|data):/i.test(value.replace(/[\u0000- ]/g, ""));
546
+
547
+ // The list a card goes by: its own, or the one held until that comes.
548
+ const listOf = () => linkBox?.workspace ?? heldList();
549
+
550
+ // A document that a card's address names in its list, or null (#<id> within a page stays a link to it).
551
+ const listed = (href) => (href && !href.startsWith("#") ? placeIn(listOf(), href) : null);
552
+
553
+ // The words for a link to `href`, where there is nothing to say of it but what it leads to: `page`'s
554
+ // title, the title of a page in the trash, else the address.
555
+ const wordsFor = (href, page) => page?.title ?? (href && titleIn(listOf(), href)) ?? href;
556
+
557
+ // The href of what is typed in the card (links/address.mjs typedHref), "" for an empty field, null
558
+ // for what is no address or is unsafe; the address of a document of the workspace as a file writes it
559
+ // (one on another server only if the list holds it, pages.mjs placeIn, for it may be another program's,
560
+ // and a click asks the list; so is a workbench's address, which only the list reads).
561
+ export function normalizeHref(value) {
562
+ const href = value.trim();
563
+ if (unsafe(href)) return null;
564
+ const typed = typedHref(href);
565
+ const place = listed(typed) ?? (use && elsewhere(typed, location.origin) ? null : pageAddress(typed));
566
+ return place ? fileLink(place, use?.slug) : typed;
567
+ }
568
+
569
+ // The href of what the card's field says for `link`: what the field was given for it stands.
570
+ const fieldHref = (value, link) => (link && value.trim() === linkBox?.shown ? hrefOf(link) : normalizeHref(value));
571
+
572
+ /** Keep what the card's field says (`null`: take the link away) and close the card; `restore`: the
573
+ * selection goes back to the text (not after a press elsewhere, which puts the caret there). */
574
+ export function setLink(value, restore = true) {
575
+ const href = value === null ? "" : fieldHref(value, linkBox.link);
576
+ if (href === null) {
577
+ use.say(t("不支持这种链接地址。"), "error");
578
+ return;
579
+ }
580
+ keep(href, restore, listed(href));
581
+ }
582
+
583
+ // A page chosen from the list (a row, Enter): the link leads to it.
584
+ const keepPage = (page, restore = true) => keep(fileLink(page, use.slug), restore, page);
585
+
586
+ // The link leads to `href` (`page`: the document of the list it is an address of), the card closing.
587
+ function keep(href, restore, page) {
588
+ const { host, range, link, fresh } = linkBox;
589
+ if (fresh) return setFresh(href, restore, page);
590
+ closeLink(restore);
591
+ if (link && href === hrefOf(link)) return; // nothing changed
592
+ // A link shown with its icon: taken away, its title stays; its address changed, read again.
593
+ if (link && isMention(link)) {
594
+ if (href) return void refetch(link, href, page);
595
+ const before = ownHTML(host);
596
+ link.replaceWith(mentionOf(link).title);
597
+ use.recordStep(host, before);
598
+ use.say(t("链接已移除。"));
599
+ return;
600
+ }
601
+ const before = ownHTML(host);
602
+ const entry = link?.classList.contains(DIALOG_TRIGGER);
603
+ if (link && !href) link.replaceWith(...link.childNodes);
604
+ else if (link) link.setAttribute("href", href);
605
+ else if (href) {
606
+ const anchor = document.createElement("a");
607
+ anchor.setAttribute("href", href);
608
+ const content = range.extractContents();
609
+ content.querySelectorAll("a").forEach((inner) => inner.replaceWith(...(isMention(inner) ? [mentionOf(inner).title] : inner.childNodes)));
610
+ anchor.append(content.textContent ? content : document.createTextNode(wordsFor(href, page))); // at a caret: its address, or a page's title
611
+ range.insertNode(anchor);
612
+ if (restore) {
613
+ const after = document.createRange();
614
+ after.setStartAfter(anchor);
615
+ select(after);
616
+ }
617
+ } else return;
618
+ use.recordStep(host, before);
619
+ use.say(href ? t("链接:{0}", wordsFor(href, page)) : entry ? t("入口已移除:页面上没有地方能打开这张详情卡片了 · Ctrl+Z 撤销") : t("链接已移除。"));
620
+ }
621
+
622
+ // The gray 链接 given its address: a link of it in its place, its words the address or a page's title
623
+ // (`page`), one undo step; Enter (restore) puts the caret after it and offers its views. Nothing
624
+ // given: it stays (leaveEmpty).
625
+ function setFresh(href, restore, page = null) {
626
+ const { host, fresh, asksPage } = linkBox;
627
+ linkBox.fresh = null; // closed as it is now
628
+ closeLink(false);
629
+ if (!host.isConnected || !fresh.chip.isConnected) return;
630
+ if (!href) return leaveEmpty(host, fresh, restore);
631
+ let link = asksPage ? pageChip(page) : null;
632
+ if (!link) {
633
+ link = document.createElement("a");
634
+ link.setAttribute("href", href);
635
+ link.textContent = wordsFor(href, page);
636
+ }
637
+ fresh.chip.replaceWith(link);
638
+ if (restore) {
639
+ host.focus({ preventScroll: true });
640
+ const after = document.createRange();
641
+ after.setStartAfter(link);
642
+ after.collapse(true);
643
+ select(after);
644
+ }
645
+ use.recordStep(host, fresh.before);
646
+ use.say(t("链接:{0}", wordsFor(href, page)));
647
+ if (restore) offerViews(link);
648
+ }
649
+
650
+ /** The open link card, if any (the editor's UI moves it into an open dialog). */
651
+ export const linkBoxNode = () => linkBox?.node ?? null;
652
+
653
+ /** The card and its views' menus (the editor's UI moves them into an open dialog). */
654
+ export const linkNodes = () => [linkBox?.node, ...viewNodes()].filter(Boolean);
655
+
656
+ /** Whether a press on `target` is one on the card or its views (no press elsewhere). */
657
+ export const linkHolds = (target) => Boolean(linkBox?.node.contains(target) || viewsHold(target));
658
+
659
+ /** Whether a gray 链接 or 页面 waits for its address (nothing is committed meanwhile). */
660
+ export const linkPending = () => Boolean(linkBox?.fresh);
661
+
662
+ // What an address of this computer names in the list the server gives: a page (pages.mjs placeIn), or
663
+ // null for any other address, or no answer.
664
+ async function listedPage(address) {
665
+ const list = await readPages(use.own());
666
+ return list && placeIn(list, address);
667
+ }
668
+
669
+ /**
670
+ * Whether a page alone in a tab may leave for a workbench's `hash`, which only the list reads: not for
671
+ * one that names no document, said as the workbench says it, the page staying. With no answer it goes,
672
+ * for the workbench to say.
673
+ */
674
+ export async function leadsToPage(hash) {
675
+ const list = await readPages(use.own());
676
+ if (!list || placeIn(list, `#${hash}`)) return true;
677
+ use.say(inTrash(list.trash, hash) ? t("这个页面已删除。") : t("没有找到这个页面。"));
678
+ return false;
679
+ }
680
+
681
+ /**
682
+ * A page block just pasted, shown as the server draws one (render/page-chips.mjs): the title its
683
+ * document has now and its icon, from the list. What the file says of it stays what was copied, and
684
+ * one the list does not hold stays as it came. The blocks of one paste read the list once.
685
+ */
686
+ export async function drawPasted(chip) {
687
+ if (!isPageChip(chip)) return;
688
+ pasted ??= readPages(use.own()).finally(() => { pasted = null; });
689
+ const list = await pasted;
690
+ const page = list && placeIn(list, fromFile(hrefOf(chip), use.slug, location.origin));
691
+ if (page && chip.isConnected) chip.replaceChildren(...pageChip(page).childNodes);
692
+ }
693
+
694
+ /**
695
+ * What an address of this computer is when it is a document's, in the list (a paste, which can wait: a
696
+ * workbench's address needs the list): the page and its block (placeIn) with `href`, the link this
697
+ * document's file writes to it; null for any other address, or no answer.
698
+ */
699
+ export async function pageLinkOf(address) {
700
+ const page = await listedPage(address);
701
+ return page && { ...page, href: fileLink(page, use.slug) };
702
+ }
703
+
704
+ // ---------- following links ----------
705
+
706
+ export const linkOf = (target) => target?.nodeType === 1 && editable(target) ? target.closest("a[href]") : null;
707
+
708
+ // What a link's #<id> says, or null for a link that is no such thing.
709
+ function anchorOf(link) {
710
+ const href = hrefOf(link);
711
+ return href.startsWith("#") && href.length > 1 ? decoded(href.slice(1)) : null;
712
+ }
713
+
714
+ const targetOf = (link) => {
715
+ const id = anchorOf(link);
716
+ return id === null ? null : document.getElementById(id);
717
+ };
718
+
719
+ // The document of the workspace, or block of one, that `address` is the address of, as `go` takes it,
720
+ // or null. A workbench's address comes with its hash, for only the list can say what that names.
721
+ function placeOf(address) {
722
+ const hash = workbenchHash(address);
723
+ const place = pageAddress(address);
724
+ return place || hash !== null ? { ...place, hash } : null;
725
+ }
726
+
727
+ // A new tab. A plain click brings it to the front; with Ctrl or ⌘ held the browser leaves it behind
728
+ // the page, as for any link.
729
+ const openTab = (url) => window.open(url, "_blank", "noopener");
730
+
731
+ // Where the selection stands.
732
+ function selectionNow() {
733
+ const { anchorNode, anchorOffset, focusNode, focusOffset } = getSelection();
734
+ return [anchorNode, anchorOffset, focusNode, focusOffset];
735
+ }
736
+
737
+ // Whether a click on a link in the text is one that opens it: not the end of a drag in it (a pointer
738
+ // moved, or a selection the press made: a selection it came down on stands until after the click,
739
+ // and a press on a whole touches none), not a Shift or Alt click, not the second click of a double
740
+ // click, not the press that closed something open.
741
+ function opens(event) {
742
+ if (event.shiftKey || event.altKey || event.detail > 1) return false;
743
+ if (!press || event.detail === 0) return true;
744
+ if (press.keeps || Math.hypot(event.clientX - press.x, event.clientY - press.y) > DRAGGED) return false;
745
+ return getSelection().isCollapsed || selectionNow().every((part, index) => part === press.selection[index]);
746
+ }
747
+
748
+ // An address of this computer on another server: on this one if the list holds its document in the
749
+ // words it has now, a link outliving the server it was copied from; else another program's, or another
750
+ // workspace's page of one folder name, opened as any web address. A tab
751
+ // of its own opens with the click, the list read after, for only what the click itself opens does the
752
+ // browser leave behind the page.
753
+ async function followElsewhere(address, tab) {
754
+ const opened = tab ? window.open("", "_blank") : null;
755
+ const list = await readPages(use.own());
756
+ const page = list && placeIn(list, address);
757
+ const here = page && fullAddress(location.origin, page, list.links);
758
+ if (opened) {
759
+ opened.opener = null;
760
+ opened.location.replace(here ?? address);
761
+ } else if (page) use.go(page, here);
762
+ else openTab(address);
763
+ }
764
+
765
+ // Go where `href`, a link of this page that is no anchor, leads, read as its file reads it, so that
766
+ // doc.html beside it is this document: a document's address there, with `tab` in a tab of its own, a
767
+ // workbench at its link, by the list held (an id, with none, opens it all the same); a file of the
768
+ // report's folder (assets/<file>) in a new tab, where the preview serves it, and any other address too.
769
+ function follow(href, tab) {
770
+ const address = fromFile(href, use.slug, location.origin);
771
+ if (!address) return;
772
+ if (elsewhere(address, location.origin)) return void followElsewhere(address, tab);
773
+ const place = placeOf(address);
774
+ const file = referencedFile(href);
775
+ if (place && !tab) use.go(place, address);
776
+ else if (place?.slug) openTab(fullAddress(location.origin, place, heldList().named));
777
+ else openTab(file ? use.served(file) : address);
778
+ }
779
+
780
+ // A page block whose document is not there: deleted when the trash holds it, else there never was
781
+ // one, as the workbench and a presentation say it.
782
+ async function sayGone(link) {
783
+ const slug = pageAddress(fromFile(hrefOf(link), use.slug))?.slug ?? "";
784
+ use.say((await trashed(slug)) ? t("这个页面已删除。") : t("没有找到这个页面。"));
785
+ }
786
+
787
+ // Whether a link in the text is one that leads away: not an anchor, nor a link with no address.
788
+ const leadsAway = (link) => hrefOf(link) !== "" && !hrefOf(link).startsWith("#");
789
+
790
+ /**
791
+ * Follow a link in the text being edited (its click): a detail card's opens it, an anchor's goes to
792
+ * its block or says it is gone, a document's goes there, any other opens in a new tab.
793
+ */
794
+ export function followLink(event, link) {
795
+ clearTimeout(hoverTimer);
796
+ event.preventDefault();
797
+ if (!opens(event)) return;
798
+ if (link.hasAttribute("data-doc-gone")) sayGone(link);
799
+ else if (targetOf(link) instanceof HTMLDialogElement) openEntry(link, event);
800
+ else if (anchorOf(link) !== null) use.reveal(anchorOf(link));
801
+ else if (leadsAway(link)) follow(hrefOf(link), event.ctrlKey || event.metaKey);
802
+ }
803
+
804
+ // A click on a link of the page outside editable text (a block the page does not edit, a card an
805
+ // Agent wrote, a figure drawn in SVG, whose links have an object for an href, and may write it
806
+ // xlink:href) while editing, last of all (the document, as it bubbles; what took the click is left
807
+ // alone), by the rules of a link in the text: a document's goes there and a web address to a new tab,
808
+ // or it would take the page with it, and in a workbench the frame (not by the press that closed
809
+ // something open); a link to a block of the page goes to it; a link with no address goes nowhere,
810
+ // where it would load the page again. What the browser or the kit does with a click stays theirs: a
811
+ // link to save (a file block's), one of a target of its own (a bookmark's card), any other anchor,
812
+ // any click with a key held.
813
+ function followOutside(event) {
814
+ if (!use.active() || event.defaultPrevented || event.button !== 0 || event.ctrlKey || event.metaKey || event.shiftKey || event.altKey) return;
815
+ const link = event.target.closest?.("main a[*|href]");
816
+ if (!link || link.matches("[download], [target]")) return;
817
+ if (link.matches("[*|href='']")) return event.preventDefault();
818
+ const href = link.href.baseVal ?? link.getAttribute("href");
819
+ const url = URL.parse(fromFile(href, use.slug, location.origin) ?? "");
820
+ if (!url || !/^https?:$/.test(url.protocol)) return;
821
+ const anchor = link.matches("[*|href^='#']") ? decoded(url.hash.slice(1)) : null;
822
+ if (anchor !== null && !document.querySelector(`[data-block-id="${CSS.escape(anchor)}"]`)) return;
823
+ event.preventDefault();
824
+ if (event.detail > 1 || press?.keeps) return;
825
+ if (anchor !== null) use.reveal(anchor);
826
+ else follow(href, false);
827
+ }
828
+
829
+ // ---------- an input method over a link ----------
830
+
831
+ // What replaces selected text takes the marks of its start (notion-lite's caretAnnotations), and what
832
+ // an input method puts in goes in as one. The browser takes a link for gone once its words are, and
833
+ // an entry's card with it: the link the selection starts in is kept here when a composition begins
834
+ // and put back around what it put in (a copy, as the one on the page may be gone by then).
835
+ let replacing = null; // { host, from: where the selection starts in its text, link: a copy of the link there }
836
+
837
+ function compositionBegun() {
838
+ replacing = null;
839
+ const selection = getSelection();
840
+ const range = selection.rangeCount && !selection.isCollapsed ? selection.getRangeAt(0) : null;
841
+ const host = range ? editable(range.startContainer) : null;
842
+ if (!host?.contains(range.endContainer)) return;
843
+ const [from] = rangeOffsets(host, range);
844
+ const { startContainer: first } = rangeAt(host, [from, from + 1]);
845
+ const link = (first.nodeType === 1 ? first : first.parentElement).closest("a[href]");
846
+ if (link && host.contains(link)) replacing = { host, from, link: link.cloneNode(false) };
847
+ }
848
+
849
+ function compositionEnded() {
850
+ const kept = replacing;
851
+ replacing = null;
852
+ const selection = getSelection();
853
+ if (!kept?.host.isConnected || !selection.rangeCount) return;
854
+ const { host, from, link } = kept;
855
+ const [, to] = rangeOffsets(host, selection.getRangeAt(0));
856
+ if (to <= from) return;
857
+ const words = rangeAt(host, [from, to]);
858
+ if (linkAround(host, words)) return; // the browser kept it
859
+ link.append(words.extractContents());
860
+ link.querySelectorAll("a").forEach((inner) => inner.replaceWith(...inner.childNodes));
861
+ words.insertNode(link);
862
+ link.parentNode.normalize();
863
+ joinMarks(link, link.nextSibling);
864
+ joinMarks(link.previousSibling, link);
865
+ select(rangeAt(host, [to, to]));
866
+ }