@omnitron-dev/prism 0.3.0 → 0.3.2

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 (413) hide show
  1. package/README.md +216 -2
  2. package/THIRD-PARTY-NOTICES.txt +26 -0
  3. package/dist/accessibility/index.js +2 -0
  4. package/dist/accessibility/index.js.map +1 -1
  5. package/dist/auth/index.d.ts +4 -0
  6. package/dist/auth/index.d.ts.map +1 -0
  7. package/dist/auth/index.js +4 -0
  8. package/dist/auth/index.js.map +1 -0
  9. package/dist/blocks/auth-block/guards.d.ts +3 -2
  10. package/dist/blocks/auth-block/guards.d.ts.map +1 -1
  11. package/dist/blocks/dashboard-block/dashboard-block.d.ts.map +1 -1
  12. package/dist/blocks/dashboard-block/types.d.ts +4 -2
  13. package/dist/blocks/dashboard-block/types.d.ts.map +1 -1
  14. package/dist/blocks/dashboard-block/use-dashboard-block.d.ts +2 -2
  15. package/dist/blocks/dashboard-block/use-dashboard-block.d.ts.map +1 -1
  16. package/dist/blocks/data-grid-block/data-grid-block.d.ts.map +1 -1
  17. package/dist/blocks/data-grid-block/types.d.ts +3 -0
  18. package/dist/blocks/data-grid-block/types.d.ts.map +1 -1
  19. package/dist/blocks/index.js +80 -253
  20. package/dist/blocks/index.js.map +1 -1
  21. package/dist/chunk-2AB7VGPW.js +447 -0
  22. package/dist/chunk-2AB7VGPW.js.map +1 -0
  23. package/dist/{chunk-WFD54GQQ.js → chunk-2E67PQ4T.js} +14 -573
  24. package/dist/chunk-2E67PQ4T.js.map +1 -0
  25. package/dist/chunk-2KG2NI73.js +84 -0
  26. package/dist/chunk-2KG2NI73.js.map +1 -0
  27. package/dist/chunk-2UYRW6X3.js +44 -0
  28. package/dist/chunk-2UYRW6X3.js.map +1 -0
  29. package/dist/chunk-36C5H56C.js +208 -0
  30. package/dist/chunk-36C5H56C.js.map +1 -0
  31. package/dist/chunk-36FOXX25.js +73 -0
  32. package/dist/chunk-36FOXX25.js.map +1 -0
  33. package/dist/chunk-3VSM7NZG.js +562 -0
  34. package/dist/chunk-3VSM7NZG.js.map +1 -0
  35. package/dist/chunk-4B2LTPK2.js +826 -0
  36. package/dist/chunk-4B2LTPK2.js.map +1 -0
  37. package/dist/chunk-4HUGZJKU.js +108 -0
  38. package/dist/chunk-4HUGZJKU.js.map +1 -0
  39. package/dist/chunk-4Q5L7LDG.js +74 -0
  40. package/dist/chunk-4Q5L7LDG.js.map +1 -0
  41. package/dist/{chunk-BRDWQVRT.js → chunk-4R7EZ7GQ.js} +3 -2
  42. package/dist/chunk-4R7EZ7GQ.js.map +1 -0
  43. package/dist/chunk-6IANOSMD.js +185 -0
  44. package/dist/chunk-6IANOSMD.js.map +1 -0
  45. package/dist/chunk-7ATBURW2.js +206 -0
  46. package/dist/chunk-7ATBURW2.js.map +1 -0
  47. package/dist/{chunk-6AHI4GSV.js → chunk-AATAOOSF.js} +4 -3
  48. package/dist/chunk-AATAOOSF.js.map +1 -0
  49. package/dist/chunk-AKLRKCYH.js +128 -0
  50. package/dist/chunk-AKLRKCYH.js.map +1 -0
  51. package/dist/chunk-CT46KJOR.js +133 -0
  52. package/dist/chunk-CT46KJOR.js.map +1 -0
  53. package/dist/{chunk-YQW43BDH.js → chunk-D4GFAJAZ.js} +1168 -6354
  54. package/dist/chunk-D4GFAJAZ.js.map +1 -0
  55. package/dist/chunk-D5J3KW6Q.js +106 -0
  56. package/dist/chunk-D5J3KW6Q.js.map +1 -0
  57. package/dist/chunk-DEPJRTVT.js +3 -0
  58. package/dist/{chunk-FU52GL2E.js.map → chunk-DEPJRTVT.js.map} +1 -1
  59. package/dist/{chunk-S6SEGBX6.js → chunk-DHTYHUYI.js} +85 -107
  60. package/dist/chunk-DHTYHUYI.js.map +1 -0
  61. package/dist/chunk-E7WM2RXA.js +249 -0
  62. package/dist/chunk-E7WM2RXA.js.map +1 -0
  63. package/dist/chunk-F6RZ7LW6.js +1271 -0
  64. package/dist/chunk-F6RZ7LW6.js.map +1 -0
  65. package/dist/chunk-FOGY3HA4.js +217 -0
  66. package/dist/chunk-FOGY3HA4.js.map +1 -0
  67. package/dist/chunk-G2GANYMW.js +139 -0
  68. package/dist/chunk-G2GANYMW.js.map +1 -0
  69. package/dist/chunk-I6DILPFE.js +293 -0
  70. package/dist/chunk-I6DILPFE.js.map +1 -0
  71. package/dist/chunk-IRYU3NTG.js +573 -0
  72. package/dist/chunk-IRYU3NTG.js.map +1 -0
  73. package/dist/chunk-JTIUGPW5.js +284 -0
  74. package/dist/chunk-JTIUGPW5.js.map +1 -0
  75. package/dist/{chunk-GUFHFEPZ.js → chunk-JZBSPDED.js} +2 -2
  76. package/dist/{chunk-GUFHFEPZ.js.map → chunk-JZBSPDED.js.map} +1 -1
  77. package/dist/chunk-KPY7TA4D.js +191 -0
  78. package/dist/chunk-KPY7TA4D.js.map +1 -0
  79. package/dist/{chunk-OBJ244BO.js → chunk-LFWKGNCX.js} +50 -656
  80. package/dist/chunk-LFWKGNCX.js.map +1 -0
  81. package/dist/chunk-LH4ZZZYB.js +37 -0
  82. package/dist/chunk-LH4ZZZYB.js.map +1 -0
  83. package/dist/chunk-NFJ7CPG3.js +13 -0
  84. package/dist/chunk-NFJ7CPG3.js.map +1 -0
  85. package/dist/chunk-NFPOIHD4.js +3 -0
  86. package/dist/{chunk-AYYFMTMI.js.map → chunk-NFPOIHD4.js.map} +1 -1
  87. package/dist/{chunk-XIXSSI3B.js → chunk-NJM5AVBM.js} +3 -2
  88. package/dist/chunk-NJM5AVBM.js.map +1 -0
  89. package/dist/{chunk-Z5OSPAOC.js → chunk-NSNM53WI.js} +196 -175
  90. package/dist/chunk-NSNM53WI.js.map +1 -0
  91. package/dist/chunk-NTREGTG7.js +31 -0
  92. package/dist/chunk-NTREGTG7.js.map +1 -0
  93. package/dist/{chunk-ADG4HZEP.js → chunk-OKJA6SJM.js} +4 -4
  94. package/dist/chunk-OKJA6SJM.js.map +1 -0
  95. package/dist/chunk-Q6JDNFSG.js +303 -0
  96. package/dist/chunk-Q6JDNFSG.js.map +1 -0
  97. package/dist/chunk-RPOGINR5.js +115 -0
  98. package/dist/chunk-RPOGINR5.js.map +1 -0
  99. package/dist/{chunk-ZTATTUH7.js → chunk-RSWVYIXK.js} +282 -683
  100. package/dist/chunk-RSWVYIXK.js.map +1 -0
  101. package/dist/chunk-SSEHL5VP.js +110 -0
  102. package/dist/chunk-SSEHL5VP.js.map +1 -0
  103. package/dist/chunk-TEIGUOWN.js +523 -0
  104. package/dist/chunk-TEIGUOWN.js.map +1 -0
  105. package/dist/{chunk-AYYFMTMI.js → chunk-TJ7DHXUX.js} +2 -2
  106. package/dist/chunk-TJ7DHXUX.js.map +1 -0
  107. package/dist/chunk-TZHWYT34.js +590 -0
  108. package/dist/chunk-TZHWYT34.js.map +1 -0
  109. package/dist/chunk-TZWHELY4.js +45 -0
  110. package/dist/chunk-TZWHELY4.js.map +1 -0
  111. package/dist/{chunk-BZOL7GMU.js → chunk-UEINJFLS.js} +7 -7
  112. package/dist/chunk-UEINJFLS.js.map +1 -0
  113. package/dist/chunk-URFQX3I6.js +129 -0
  114. package/dist/chunk-URFQX3I6.js.map +1 -0
  115. package/dist/chunk-VG6FOMOH.js +187 -0
  116. package/dist/chunk-VG6FOMOH.js.map +1 -0
  117. package/dist/chunk-VQVVHMPG.js +106 -0
  118. package/dist/chunk-VQVVHMPG.js.map +1 -0
  119. package/dist/{chunk-DRFNMZLG.js → chunk-VUKOT432.js} +3 -2
  120. package/dist/chunk-VUKOT432.js.map +1 -0
  121. package/dist/chunk-WD4N72DL.js +315 -0
  122. package/dist/chunk-WD4N72DL.js.map +1 -0
  123. package/dist/chunk-XBYMG4QK.js +119 -0
  124. package/dist/chunk-XBYMG4QK.js.map +1 -0
  125. package/dist/chunk-YHM6GIHV.js +3 -0
  126. package/dist/chunk-YHM6GIHV.js.map +1 -0
  127. package/dist/{chunk-SNZK5X6F.js → chunk-Z2AN43YU.js} +4 -2
  128. package/dist/chunk-Z2AN43YU.js.map +1 -0
  129. package/dist/chunk-ZNWHMQRM.js +171 -0
  130. package/dist/chunk-ZNWHMQRM.js.map +1 -0
  131. package/dist/{chunk-YSIG2XYH.js → chunk-ZRJYQN6Y.js} +2 -2
  132. package/dist/{chunk-YSIG2XYH.js.map → chunk-ZRJYQN6Y.js.map} +1 -1
  133. package/dist/{chunk-AD4W7HYC.js → chunk-ZYI3MHLE.js} +3 -2
  134. package/dist/chunk-ZYI3MHLE.js.map +1 -0
  135. package/dist/cli/index.js +66 -423
  136. package/dist/cli/index.js.map +1 -1
  137. package/dist/components/accordion/accordion.d.ts.map +1 -1
  138. package/dist/components/admin-filters/admin-data-table.d.ts +7 -1
  139. package/dist/components/admin-filters/admin-data-table.d.ts.map +1 -1
  140. package/dist/components/admin-filters/filter-toolbar.d.ts.map +1 -1
  141. package/dist/components/admin-filters/index.js +8 -0
  142. package/dist/components/admin-filters/index.js.map +1 -0
  143. package/dist/components/alert/alert.d.ts.map +1 -1
  144. package/dist/components/alert/index.js +5 -0
  145. package/dist/components/alert/index.js.map +1 -0
  146. package/dist/components/animate/index.js +5 -0
  147. package/dist/components/animate/index.js.map +1 -0
  148. package/dist/components/breadcrumbs/breadcrumbs.d.ts.map +1 -1
  149. package/dist/components/breadcrumbs/index.js +4 -0
  150. package/dist/components/breadcrumbs/index.js.map +1 -0
  151. package/dist/components/card/index.js +4 -0
  152. package/dist/components/card/index.js.map +1 -0
  153. package/dist/components/chart/chart.d.ts.map +1 -1
  154. package/dist/components/chart/index.css +52 -0
  155. package/dist/components/chart/index.css.map +1 -0
  156. package/dist/components/chart/index.js +5 -0
  157. package/dist/components/chart/index.js.map +1 -0
  158. package/dist/components/chart/types.d.ts +3 -1
  159. package/dist/components/chart/types.d.ts.map +1 -1
  160. package/dist/components/chart/use-chart.d.ts.map +1 -1
  161. package/dist/components/command-palette/command-palette.d.ts +3 -1
  162. package/dist/components/command-palette/command-palette.d.ts.map +1 -1
  163. package/dist/components/command-palette/index.js +4 -0
  164. package/dist/components/command-palette/index.js.map +1 -0
  165. package/dist/components/confirm-dialog/index.js +4 -0
  166. package/dist/components/confirm-dialog/index.js.map +1 -0
  167. package/dist/components/date-input/date-input.d.ts +28 -0
  168. package/dist/components/date-input/date-input.d.ts.map +1 -0
  169. package/dist/components/date-input/index.d.ts +3 -0
  170. package/dist/components/date-input/index.d.ts.map +1 -0
  171. package/dist/components/date-input/value.d.ts +9 -0
  172. package/dist/components/date-input/value.d.ts.map +1 -0
  173. package/dist/components/doc-layout/doc-sidebar.d.ts +4 -1
  174. package/dist/components/doc-layout/doc-sidebar.d.ts.map +1 -1
  175. package/dist/components/doc-layout/index.js +7 -0
  176. package/dist/components/doc-layout/index.js.map +1 -0
  177. package/dist/components/editor/editor.d.ts.map +1 -1
  178. package/dist/components/editor/icons/index.d.ts +32 -40
  179. package/dist/components/editor/icons/index.d.ts.map +1 -1
  180. package/dist/components/editor/index.js +4 -1
  181. package/dist/components/editor/index.js.map +1 -1
  182. package/dist/components/emoji-picker/index.js +2 -1
  183. package/dist/components/emoji-picker/index.js.map +1 -1
  184. package/dist/components/empty-content/empty-content.d.ts.map +1 -1
  185. package/dist/components/empty-content/index.js +4 -0
  186. package/dist/components/empty-content/index.js.map +1 -0
  187. package/dist/components/error-boundary/error-boundary.d.ts.map +1 -1
  188. package/dist/components/error-boundary/index.js +6 -0
  189. package/dist/components/error-boundary/index.js.map +1 -0
  190. package/dist/components/index.css +17 -10
  191. package/dist/components/index.css.map +1 -1
  192. package/dist/components/index.d.ts +5 -4
  193. package/dist/components/index.d.ts.map +1 -1
  194. package/dist/components/index.js +47 -11
  195. package/dist/components/index.js.map +1 -1
  196. package/dist/components/knowledge-graph/edge-labels.d.ts +14 -0
  197. package/dist/components/knowledge-graph/edge-labels.d.ts.map +1 -0
  198. package/dist/components/knowledge-graph/graph.d.ts +56 -0
  199. package/dist/components/knowledge-graph/graph.d.ts.map +1 -0
  200. package/dist/components/knowledge-graph/index.css +176 -0
  201. package/dist/components/knowledge-graph/index.css.map +1 -0
  202. package/dist/components/knowledge-graph/index.d.ts +3 -0
  203. package/dist/components/knowledge-graph/index.d.ts.map +1 -0
  204. package/dist/components/knowledge-graph/index.js +797 -0
  205. package/dist/components/knowledge-graph/index.js.map +1 -0
  206. package/dist/components/knowledge-graph/label-layout.d.ts +28 -0
  207. package/dist/components/knowledge-graph/label-layout.d.ts.map +1 -0
  208. package/dist/components/knowledge-graph/label-store.d.ts +15 -0
  209. package/dist/components/knowledge-graph/label-store.d.ts.map +1 -0
  210. package/dist/components/knowledge-graph/model.d.ts +92 -0
  211. package/dist/components/knowledge-graph/model.d.ts.map +1 -0
  212. package/dist/components/label/index.js +5 -0
  213. package/dist/components/label/index.js.map +1 -0
  214. package/dist/components/label/label.d.ts.map +1 -1
  215. package/dist/components/lightbox/lightbox.d.ts.map +1 -1
  216. package/dist/components/loading-screen/index.js +4 -0
  217. package/dist/components/loading-screen/index.js.map +1 -0
  218. package/dist/components/map/Map.d.ts +19 -43
  219. package/dist/components/map/Map.d.ts.map +1 -1
  220. package/dist/components/map/MapCoverageLayer.d.ts +1 -1
  221. package/dist/components/map/MapCoverageLayer.d.ts.map +1 -1
  222. package/dist/components/map/MapMarker.d.ts +1 -1
  223. package/dist/components/map/MapMarker.d.ts.map +1 -1
  224. package/dist/components/map/MapPlaceSearch.d.ts +33 -0
  225. package/dist/components/map/MapPlaceSearch.d.ts.map +1 -0
  226. package/dist/components/map/MapPointPicker.d.ts +21 -12
  227. package/dist/components/map/MapPointPicker.d.ts.map +1 -1
  228. package/dist/components/map/coordinates.d.ts +10 -0
  229. package/dist/components/map/coordinates.d.ts.map +1 -0
  230. package/dist/components/map/index.css +4 -0
  231. package/dist/components/map/index.css.map +1 -0
  232. package/dist/components/map/index.d.ts +7 -2
  233. package/dist/components/map/index.d.ts.map +1 -1
  234. package/dist/components/map/index.js +4 -0
  235. package/dist/components/map/index.js.map +1 -0
  236. package/dist/components/nav-card/nav-card.d.ts.map +1 -1
  237. package/dist/components/navigation-progress/index.js +4 -0
  238. package/dist/components/navigation-progress/index.js.map +1 -0
  239. package/dist/components/page-content/index.js +4 -0
  240. package/dist/components/page-content/index.js.map +1 -0
  241. package/dist/components/popover/index.js +4 -0
  242. package/dist/components/popover/index.js.map +1 -0
  243. package/dist/components/rail/rail.d.ts.map +1 -1
  244. package/dist/components/research/diagram-image.d.ts +11 -0
  245. package/dist/components/research/diagram-image.d.ts.map +1 -0
  246. package/dist/components/research/diagram.d.ts +8 -0
  247. package/dist/components/research/diagram.d.ts.map +1 -0
  248. package/dist/components/research/document.d.ts +33 -0
  249. package/dist/components/research/document.d.ts.map +1 -0
  250. package/dist/components/research/frontmatter.d.ts +15 -0
  251. package/dist/components/research/frontmatter.d.ts.map +1 -0
  252. package/dist/components/research/index.css +51 -0
  253. package/dist/components/research/index.css.map +1 -0
  254. package/dist/components/research/index.d.ts +3 -0
  255. package/dist/components/research/index.d.ts.map +1 -0
  256. package/dist/components/research/index.js +8 -0
  257. package/dist/components/research/index.js.map +1 -0
  258. package/dist/components/research/parse.d.ts +29 -0
  259. package/dist/components/research/parse.d.ts.map +1 -0
  260. package/dist/components/research-editor/block-commands.d.ts +20 -0
  261. package/dist/components/research-editor/block-commands.d.ts.map +1 -0
  262. package/dist/components/research-editor/block-controls.d.ts +13 -0
  263. package/dist/components/research-editor/block-controls.d.ts.map +1 -0
  264. package/dist/components/research-editor/editor.d.ts +75 -0
  265. package/dist/components/research-editor/editor.d.ts.map +1 -0
  266. package/dist/components/research-editor/extensions.d.ts +14 -0
  267. package/dist/components/research-editor/extensions.d.ts.map +1 -0
  268. package/dist/components/research-editor/index.css +332 -0
  269. package/dist/components/research-editor/index.css.map +1 -0
  270. package/dist/components/research-editor/index.d.ts +5 -0
  271. package/dist/components/research-editor/index.d.ts.map +1 -0
  272. package/dist/components/research-editor/index.js +1593 -0
  273. package/dist/components/research-editor/index.js.map +1 -0
  274. package/dist/components/research-editor/math-input.d.ts +32 -0
  275. package/dist/components/research-editor/math-input.d.ts.map +1 -0
  276. package/dist/components/research-editor/math-markup.d.ts +4 -0
  277. package/dist/components/research-editor/math-markup.d.ts.map +1 -0
  278. package/dist/components/research-editor/math-navigation.d.ts +6 -0
  279. package/dist/components/research-editor/math-navigation.d.ts.map +1 -0
  280. package/dist/components/research-editor/math-node.d.ts +11 -0
  281. package/dist/components/research-editor/math-node.d.ts.map +1 -0
  282. package/dist/components/research-editor/source.d.ts +19 -0
  283. package/dist/components/research-editor/source.d.ts.map +1 -0
  284. package/dist/components/scroll-to-top/index.js +4 -0
  285. package/dist/components/scroll-to-top/index.js.map +1 -0
  286. package/dist/components/scrollbar/scrollbar.d.ts +4 -2
  287. package/dist/components/scrollbar/scrollbar.d.ts.map +1 -1
  288. package/dist/components/search-input/index.js +7 -0
  289. package/dist/components/search-input/index.js.map +1 -0
  290. package/dist/components/search-input/search-input.d.ts +3 -11
  291. package/dist/components/search-input/search-input.d.ts.map +1 -1
  292. package/dist/components/skeleton/index.js +4 -0
  293. package/dist/components/skeleton/index.js.map +1 -0
  294. package/dist/components/snackbar/index.js +6 -0
  295. package/dist/components/snackbar/index.js.map +1 -0
  296. package/dist/components/stepper/index.js +4 -0
  297. package/dist/components/stepper/index.js.map +1 -0
  298. package/dist/components/table/index.d.ts +1 -0
  299. package/dist/components/table/index.d.ts.map +1 -1
  300. package/dist/components/table/index.js +5 -0
  301. package/dist/components/table/index.js.map +1 -0
  302. package/dist/components/table/table-viewport.d.ts +13 -0
  303. package/dist/components/table/table-viewport.d.ts.map +1 -0
  304. package/dist/components/table/table.d.ts +3 -1
  305. package/dist/components/table/table.d.ts.map +1 -1
  306. package/dist/components/tabs/index.js +6 -0
  307. package/dist/components/tabs/index.js.map +1 -0
  308. package/dist/components/tabs/tabs.d.ts +12 -1
  309. package/dist/components/tabs/tabs.d.ts.map +1 -1
  310. package/dist/components/tiptap-renderer/tiptap-renderer.d.ts +4 -3
  311. package/dist/components/tiptap-renderer/tiptap-renderer.d.ts.map +1 -1
  312. package/dist/core/index.d.ts +1 -1
  313. package/dist/core/index.d.ts.map +1 -1
  314. package/dist/core/index.js +12 -6
  315. package/dist/core/index.js.map +1 -1
  316. package/dist/core/provider.d.ts +7 -2
  317. package/dist/core/provider.d.ts.map +1 -1
  318. package/dist/forms/index.js +2 -0
  319. package/dist/forms/index.js.map +1 -1
  320. package/dist/forms/schema-provider.d.ts +3 -3
  321. package/dist/forms/schema-utils.d.ts +3 -3
  322. package/dist/hooks/index.js +14 -8
  323. package/dist/hooks/index.js.map +1 -1
  324. package/dist/hooks/use-config-from-query.d.ts +2 -0
  325. package/dist/hooks/use-config-from-query.d.ts.map +1 -1
  326. package/dist/hooks/use-image-dimensions.d.ts.map +1 -1
  327. package/dist/hooks/use-keyboard-shortcut.d.ts.map +1 -1
  328. package/dist/hooks/use-scroll-position.d.ts.map +1 -1
  329. package/dist/hooks/use-window-size.d.ts.map +1 -1
  330. package/dist/icons/context.d.ts +17 -0
  331. package/dist/icons/context.d.ts.map +1 -0
  332. package/dist/icons/controls.d.ts +51 -0
  333. package/dist/icons/controls.d.ts.map +1 -0
  334. package/dist/icons/index.d.ts +3 -0
  335. package/dist/icons/index.d.ts.map +1 -0
  336. package/dist/icons/index.js +5 -0
  337. package/dist/icons/index.js.map +1 -0
  338. package/dist/icons/theme.d.ts +4 -0
  339. package/dist/icons/theme.d.ts.map +1 -0
  340. package/dist/index.css +17 -10
  341. package/dist/index.css.map +1 -1
  342. package/dist/index.js +57 -20
  343. package/dist/index.js.map +1 -1
  344. package/dist/internal/research-parser.js +3 -0
  345. package/dist/internal/research-parser.js.map +1 -0
  346. package/dist/layouts/core/header-section.d.ts +1 -0
  347. package/dist/layouts/core/header-section.d.ts.map +1 -1
  348. package/dist/layouts/dashboard/labels.d.ts +12 -0
  349. package/dist/layouts/dashboard/labels.d.ts.map +1 -0
  350. package/dist/layouts/dashboard/layout.d.ts +9 -1
  351. package/dist/layouts/dashboard/layout.d.ts.map +1 -1
  352. package/dist/layouts/dashboard/sidenav.d.ts +7 -3
  353. package/dist/layouts/dashboard/sidenav.d.ts.map +1 -1
  354. package/dist/layouts/index.d.ts +5 -0
  355. package/dist/layouts/index.d.ts.map +1 -1
  356. package/dist/layouts/index.js +9 -3
  357. package/dist/layouts/index.js.map +1 -1
  358. package/dist/layouts/panel-layout.d.ts +35 -0
  359. package/dist/layouts/panel-layout.d.ts.map +1 -0
  360. package/dist/layouts/sidebar-toggle.d.ts +11 -0
  361. package/dist/layouts/sidebar-toggle.d.ts.map +1 -0
  362. package/dist/netron/index.js +2 -1
  363. package/dist/netron/index.js.map +1 -1
  364. package/dist/registry/index.js +1 -1
  365. package/dist/state/create-store.d.ts.map +1 -1
  366. package/dist/state/index.js +3 -2
  367. package/dist/state/index.js.map +1 -1
  368. package/dist/state/settings-version.d.ts.map +1 -1
  369. package/dist/state/stores/auth.d.ts +4 -16
  370. package/dist/state/stores/auth.d.ts.map +1 -1
  371. package/dist/state/stores/ui.d.ts +7 -105
  372. package/dist/state/stores/ui.d.ts.map +1 -1
  373. package/dist/theme/components/Button.d.ts.map +1 -1
  374. package/dist/theme/components/Chip.d.ts.map +1 -1
  375. package/dist/theme/components/Dialog.d.ts.map +1 -1
  376. package/dist/theme/components/FormControls.d.ts +3 -12
  377. package/dist/theme/components/FormControls.d.ts.map +1 -1
  378. package/dist/theme/components/TextField.d.ts.map +1 -1
  379. package/dist/theme/components/index.d.ts.map +1 -1
  380. package/dist/theme/components/theme-utils.d.ts +2 -2
  381. package/dist/theme/components/theme-utils.d.ts.map +1 -1
  382. package/dist/theme/create-theme.d.ts +5 -17
  383. package/dist/theme/create-theme.d.ts.map +1 -1
  384. package/dist/theme/index.js +8 -2
  385. package/dist/theme/index.js.map +1 -1
  386. package/dist/theme/mixins.d.ts +3 -1
  387. package/dist/theme/mixins.d.ts.map +1 -1
  388. package/dist/theme/palette/overrides.d.ts +24 -0
  389. package/dist/theme/palette/overrides.d.ts.map +1 -0
  390. package/dist/theme/semantic-surface.d.ts +8 -0
  391. package/dist/theme/semantic-surface.d.ts.map +1 -0
  392. package/dist/types/index.js +2 -2
  393. package/dist/ui/index.d.ts +18 -0
  394. package/dist/ui/index.d.ts.map +1 -0
  395. package/dist/ui/index.js +149 -0
  396. package/dist/ui/index.js.map +1 -0
  397. package/dist/utils/async-lock.d.ts.map +1 -1
  398. package/package.json +200 -47
  399. package/dist/chunk-6AHI4GSV.js.map +0 -1
  400. package/dist/chunk-AD4W7HYC.js.map +0 -1
  401. package/dist/chunk-ADG4HZEP.js.map +0 -1
  402. package/dist/chunk-BRDWQVRT.js.map +0 -1
  403. package/dist/chunk-BZOL7GMU.js.map +0 -1
  404. package/dist/chunk-DRFNMZLG.js.map +0 -1
  405. package/dist/chunk-FU52GL2E.js +0 -3
  406. package/dist/chunk-OBJ244BO.js.map +0 -1
  407. package/dist/chunk-S6SEGBX6.js.map +0 -1
  408. package/dist/chunk-SNZK5X6F.js.map +0 -1
  409. package/dist/chunk-WFD54GQQ.js.map +0 -1
  410. package/dist/chunk-XIXSSI3B.js.map +0 -1
  411. package/dist/chunk-YQW43BDH.js.map +0 -1
  412. package/dist/chunk-Z5OSPAOC.js.map +0 -1
  413. package/dist/chunk-ZTATTUH7.js.map +0 -1
@@ -0,0 +1,1593 @@
1
+ "use client";
2
+ import { ResearchDocument } from '../../chunk-Q6JDNFSG.js';
3
+ import { researchLimits, parseResearchMarkdown, splitFrontmatter, math } from '../../chunk-TEIGUOWN.js';
4
+ import '../../chunk-4B2LTPK2.js';
5
+ import { KeyboardIcon, CheckIcon, AddIcon, DragIcon } from '../../chunk-VQVVHMPG.js';
6
+ import '../../chunk-D5J3KW6Q.js';
7
+ import { createContext, useRef, useState, useEffect, useMemo, useImperativeHandle, useContext } from 'react';
8
+ import { getSchema, Node, Extension } from '@tiptap/core';
9
+ import { useEditor, useEditorState, EditorContent, ReactNodeViewRenderer, NodeViewWrapper } from '@tiptap/react';
10
+ import { PluginKey, NodeSelection, TextSelection, Plugin, Selection } from '@tiptap/pm/state';
11
+ import Box from '@mui/material/Box';
12
+ import Button2 from '@mui/material/Button';
13
+ import Dialog from '@mui/material/Dialog';
14
+ import DialogTitle from '@mui/material/DialogTitle';
15
+ import DialogContent from '@mui/material/DialogContent';
16
+ import DialogActions from '@mui/material/DialogActions';
17
+ import TextField2 from '@mui/material/TextField';
18
+ import Autocomplete, { createFilterOptions } from '@mui/material/Autocomplete';
19
+ import StarterKit from '@tiptap/starter-kit';
20
+ import TaskList from '@tiptap/extension-task-list';
21
+ import TaskItem from '@tiptap/extension-task-item';
22
+ import { TableKit } from '@tiptap/extension-table';
23
+ import { Decoration, DecorationSet } from '@tiptap/pm/view';
24
+ import { flushSync } from 'react-dom';
25
+ import { closeHistory } from '@tiptap/pm/history';
26
+ import katex from 'katex';
27
+ import IconButton from '@mui/material/IconButton';
28
+ import Tooltip from '@mui/material/Tooltip';
29
+ import GlobalStyles from '@mui/material/GlobalStyles';
30
+ import { useTheme } from '@mui/material/styles';
31
+ import DOMPurify from 'dompurify';
32
+ import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
33
+ import { fromMarkdown } from 'mdast-util-from-markdown';
34
+ import { toMarkdown } from 'mdast-util-to-markdown';
35
+ import { gfm } from 'micromark-extension-gfm';
36
+ import { gfmToMarkdown, gfmFromMarkdown } from 'mdast-util-gfm';
37
+ import { mathToMarkdown, mathFromMarkdown } from 'mdast-util-math';
38
+ import { directive } from 'micromark-extension-directive';
39
+ import { directiveFromMarkdown } from 'mdast-util-directive';
40
+ import { canSplit } from '@tiptap/pm/transform';
41
+ import Menu from '@mui/material/Menu';
42
+ import MenuItem from '@mui/material/MenuItem';
43
+
44
+ var layoutProperties = /* @__PURE__ */ new Set([
45
+ "color",
46
+ "background-color",
47
+ "opacity",
48
+ "height",
49
+ "width",
50
+ "min-width",
51
+ "max-width",
52
+ "min-height",
53
+ "max-height",
54
+ "top",
55
+ "bottom",
56
+ "left",
57
+ "right",
58
+ "vertical-align",
59
+ "margin",
60
+ "margin-top",
61
+ "margin-bottom",
62
+ "margin-left",
63
+ "margin-right",
64
+ "padding",
65
+ "padding-top",
66
+ "padding-bottom",
67
+ "padding-left",
68
+ "padding-right",
69
+ "border",
70
+ "border-top",
71
+ "border-bottom",
72
+ "border-left",
73
+ "border-right",
74
+ "border-color",
75
+ "border-width",
76
+ "border-style",
77
+ "border-radius",
78
+ "font-size",
79
+ "font-weight",
80
+ "font-style",
81
+ "line-height",
82
+ "letter-spacing",
83
+ "display",
84
+ "visibility",
85
+ "text-align",
86
+ "white-space",
87
+ "transform",
88
+ "transform-origin"
89
+ ]);
90
+ function sanitizeMathMarkup(html) {
91
+ const fragment = DOMPurify.sanitize(html, {
92
+ ADD_ATTR: ["contenteditable"],
93
+ ADD_TAGS: ["use"],
94
+ FORBID_TAGS: ["style", "link", "iframe", "object", "embed", "img", "image", "foreignObject"],
95
+ RETURN_DOM_FRAGMENT: true
96
+ });
97
+ for (const element of fragment.querySelectorAll("*")) {
98
+ for (const attribute of Array.from(element.attributes)) {
99
+ if (["href", "xlink:href", "src", "action", "formaction", "poster"].includes(attribute.name) && !(element.localName === "use" && /^#[\w-]+$/.test(attribute.value)))
100
+ element.removeAttribute(attribute.name);
101
+ }
102
+ }
103
+ for (const element of fragment.querySelectorAll("[style]")) {
104
+ const parsed = document.createElement("span").style;
105
+ parsed.cssText = element.getAttribute("style") ?? "";
106
+ const safe = document.createElement("span").style;
107
+ for (const name of Array.from(parsed)) {
108
+ if (layoutProperties.has(name)) safe.setProperty(name, parsed.getPropertyValue(name));
109
+ }
110
+ if (safe.cssText) element.setAttribute("style", safe.cssText);
111
+ else element.removeAttribute("style");
112
+ }
113
+ for (const element of fragment.querySelectorAll("[fill], [stroke]")) {
114
+ for (const name of ["fill", "stroke"]) {
115
+ const value = element.getAttribute(name);
116
+ if (value && /url|\\/i.test(value)) element.removeAttribute(name);
117
+ }
118
+ }
119
+ const wrapper = document.createElement("div");
120
+ wrapper.append(fragment);
121
+ return wrapper.innerHTML;
122
+ }
123
+ var defaultMathInputLabels = {
124
+ field: "Equation",
125
+ source: "LaTeX source",
126
+ keyboard: "Math keyboard",
127
+ done: "Return to document",
128
+ loading: "Loading equation editor\u2026",
129
+ unavailable: "Visual input unavailable. LaTeX editing is available.",
130
+ syntax: "Check the LaTeX syntax. The source is retained.",
131
+ limit: "Equation exceeds the configured limit."
132
+ };
133
+ var runtime;
134
+ var keyboardOwner;
135
+ function loadMathLive() {
136
+ return runtime ??= import('mathlive').then((module) => {
137
+ module.MathfieldElement.createHTML = sanitizeMathMarkup;
138
+ module.MathfieldElement.fontsDirectory = null;
139
+ module.MathfieldElement.soundsDirectory = null;
140
+ return module;
141
+ }).catch((error) => {
142
+ runtime = void 0;
143
+ throw error;
144
+ });
145
+ }
146
+ function MathInput(props) {
147
+ const labels = { ...defaultMathInputLabels, ...props.labels };
148
+ const theme = useTheme();
149
+ const host = useRef(null), field = useRef(void 0);
150
+ const editingSource = useRef(false);
151
+ const latest = useRef(props);
152
+ latest.current = props;
153
+ const [ready, setReady] = useState(false), [failed, setFailed] = useState(false);
154
+ const [source, setSource] = useState(false), [issue, setIssue] = useState();
155
+ function accept(value) {
156
+ const p = latest.current;
157
+ if (p.readOnly || value.length > (p.maxLength ?? 65536) || p.onChange(value) === false) {
158
+ if (!p.readOnly) setIssue("limit");
159
+ return false;
160
+ }
161
+ return true;
162
+ }
163
+ useEffect(() => {
164
+ let cancelled = false;
165
+ let dispose;
166
+ void loadMathLive().then(({ MathfieldElement }) => {
167
+ if (cancelled || !host.current) return;
168
+ const p = latest.current;
169
+ if (p.locale) MathfieldElement.locale = p.locale;
170
+ const mf = new MathfieldElement({
171
+ defaultMode: p.display ? "math" : "inline-math",
172
+ mathVirtualKeyboardPolicy: "manual",
173
+ ...p.options
174
+ });
175
+ field.current = mf;
176
+ mf.smartFence = false;
177
+ mf.removeExtraneousParentheses = false;
178
+ mf.readOnly = !!p.readOnly;
179
+ mf.setAttribute("aria-label", p.labels?.field ?? defaultMathInputLabels.field);
180
+ mf.setValue(p.value, { silenceNotifications: true });
181
+ const claimKeyboard = () => {
182
+ keyboardOwner = mf;
183
+ };
184
+ mf.addEventListener("focusin", claimKeyboard, true);
185
+ const input = (event) => {
186
+ event.stopPropagation();
187
+ const accepted = accept(mf.value);
188
+ if (!accepted) mf.setValue(latest.current.value, { silenceNotifications: true });
189
+ else setIssue(mf.errors.length ? "syntax" : void 0);
190
+ };
191
+ const move = (event) => {
192
+ if (!latest.current.onExit) return;
193
+ event.preventDefault();
194
+ latest.current.onExit(event.detail.direction);
195
+ };
196
+ const key = (event) => {
197
+ if (event.isComposing) return;
198
+ const currentProps = latest.current;
199
+ if (currentProps.onHistory && (event.metaKey || event.ctrlKey) && ["z", "y"].includes(event.key.toLowerCase())) {
200
+ event.preventDefault();
201
+ event.stopImmediatePropagation();
202
+ currentProps.onHistory(event.shiftKey || event.key.toLowerCase() === "y");
203
+ } else if (currentProps.onExit && (event.key === "Escape" || event.key === "Enter" && !event.shiftKey)) {
204
+ if (event.key === "Enter" && mf.mode === "latex") return;
205
+ event.preventDefault();
206
+ event.stopImmediatePropagation();
207
+ currentProps.onExit("forward");
208
+ }
209
+ };
210
+ const stop = (event) => {
211
+ event.stopPropagation();
212
+ if (event.type === "beforeinput" && latest.current.onHistory) {
213
+ const type = event.inputType;
214
+ if (type === "historyUndo" || type === "historyRedo") {
215
+ event.preventDefault();
216
+ latest.current.onHistory(type === "historyRedo");
217
+ }
218
+ }
219
+ };
220
+ for (const name of ["keydown", "keyup", "keypress", "beforeinput", "paste", "cut", "copy"])
221
+ mf.addEventListener(name, stop);
222
+ mf.addEventListener("input", input);
223
+ mf.addEventListener("move-out", move);
224
+ mf.addEventListener("keydown", key, true);
225
+ dispose = () => {
226
+ if (keyboardOwner === mf) {
227
+ window.mathVirtualKeyboard.hide({ animate: false });
228
+ keyboardOwner = void 0;
229
+ }
230
+ mf.removeEventListener("focusin", claimKeyboard, true);
231
+ for (const name of ["keydown", "keyup", "keypress", "beforeinput", "paste", "cut", "copy"])
232
+ mf.removeEventListener(name, stop);
233
+ mf.removeEventListener("input", input);
234
+ mf.removeEventListener("move-out", move);
235
+ mf.removeEventListener("keydown", key, true);
236
+ mf.remove();
237
+ field.current = void 0;
238
+ };
239
+ host.current.replaceChildren(mf);
240
+ mf.menuItems = [];
241
+ setReady(true);
242
+ if (mf.errors.length) {
243
+ setIssue("syntax");
244
+ editingSource.current = true;
245
+ setSource(true);
246
+ }
247
+ }).catch(() => {
248
+ dispose?.();
249
+ if (!cancelled) {
250
+ setFailed(true);
251
+ setSource(true);
252
+ }
253
+ });
254
+ return () => {
255
+ cancelled = true;
256
+ dispose?.();
257
+ };
258
+ }, []);
259
+ useEffect(() => {
260
+ const p = latest.current, mf = field.current;
261
+ if (ready && mf && p.autoFocus && !p.readOnly && !editingSource.current) {
262
+ keyboardOwner = mf;
263
+ mf.focus();
264
+ mf.position = p.entry === "start" ? 0 : -1;
265
+ }
266
+ }, [ready]);
267
+ useEffect(() => {
268
+ const mf = field.current;
269
+ if (!mf) return;
270
+ mf.readOnly = !!props.readOnly;
271
+ mf.setAttribute("aria-label", labels.field);
272
+ if (mf.value !== props.value) mf.setValue(props.value, { silenceNotifications: true });
273
+ }, [props.value, props.readOnly, labels.field, ready]);
274
+ useEffect(() => {
275
+ if (props.locale && ready)
276
+ void loadMathLive().then(({ MathfieldElement }) => {
277
+ MathfieldElement.locale = props.locale;
278
+ });
279
+ }, [props.locale, ready]);
280
+ return /* @__PURE__ */ jsxs(
281
+ Box,
282
+ {
283
+ component: "span",
284
+ className: "prism-math-input",
285
+ sx: {
286
+ color: "text.primary",
287
+ bgcolor: "background.paper",
288
+ borderColor: "divider",
289
+ "--prism-editor-accent": theme.palette.primary.main,
290
+ "--prism-editor-radius": `${theme.shape.borderRadius}px`
291
+ },
292
+ children: [
293
+ /* @__PURE__ */ jsx(
294
+ GlobalStyles,
295
+ {
296
+ styles: {
297
+ ".ML__keyboard": {
298
+ "--keyboard-background": theme.palette.background.default,
299
+ "--keycap-background": theme.palette.background.paper,
300
+ "--keycap-text": theme.palette.text.primary,
301
+ "--keycap-background-hover": theme.palette.action.hover,
302
+ "--keycap-text-hover": theme.palette.text.primary,
303
+ "--keyboard-accent-color": theme.palette.primary.main,
304
+ "--keyboard-toolbar-background": theme.palette.background.paper,
305
+ "--keyboard-toolbar-text": theme.palette.text.secondary,
306
+ "--keyboard-toolbar-text-active": theme.palette.primary.main,
307
+ "--keycap-primary-background": theme.palette.primary.main,
308
+ "--keycap-primary-text": theme.palette.primary.contrastText,
309
+ "--keycap-secondary-background": theme.palette.action.hover,
310
+ "--keycap-secondary-text": theme.palette.text.primary,
311
+ "--keycap-border": `1px solid ${theme.palette.divider}`,
312
+ "--keycap-secondary-border": `1px solid ${theme.palette.divider}`,
313
+ "--keyboard-zindex": theme.zIndex.modal + 1
314
+ }
315
+ }
316
+ }
317
+ ),
318
+ !ready && /* @__PURE__ */ jsx(Box, { component: "span", role: "status", sx: { typography: "caption" }, children: failed ? labels.unavailable : labels.loading }),
319
+ /* @__PURE__ */ jsx("span", { ref: host, className: "prism-math-input__field" }),
320
+ /* @__PURE__ */ jsxs(Box, { component: "span", className: "prism-math-input__tools", children: [
321
+ /* @__PURE__ */ jsx(
322
+ Button2,
323
+ {
324
+ type: "button",
325
+ size: "small",
326
+ "aria-pressed": source,
327
+ onMouseDown: (e) => e.preventDefault(),
328
+ onClick: () => setSource(!source),
329
+ children: "LaTeX"
330
+ }
331
+ ),
332
+ /* @__PURE__ */ jsx(Tooltip, { title: labels.keyboard, children: /* @__PURE__ */ jsx("span", { children: /* @__PURE__ */ jsx(
333
+ IconButton,
334
+ {
335
+ "aria-label": labels.keyboard,
336
+ type: "button",
337
+ size: "small",
338
+ disabled: !ready || props.readOnly,
339
+ onMouseDown: (e) => e.preventDefault(),
340
+ onClick: () => {
341
+ keyboardOwner = field.current;
342
+ field.current?.focus();
343
+ field.current?.executeCommand("toggleVirtualKeyboard");
344
+ },
345
+ children: /* @__PURE__ */ jsx(KeyboardIcon, { fontSize: "small" })
346
+ }
347
+ ) }) }),
348
+ props.onExit && /* @__PURE__ */ jsx(Tooltip, { title: labels.done, children: /* @__PURE__ */ jsx(IconButton, { type: "button", size: "small", "aria-label": labels.done, onClick: () => props.onExit?.("forward"), children: /* @__PURE__ */ jsx(CheckIcon, { fontSize: "small" }) }) })
349
+ ] }),
350
+ (source || !ready) && /* @__PURE__ */ jsx(
351
+ TextField2,
352
+ {
353
+ fullWidth: true,
354
+ autoFocus: !ready && props.autoFocus,
355
+ size: "small",
356
+ multiline: true,
357
+ maxRows: 8,
358
+ label: labels.source,
359
+ value: props.value,
360
+ onChange: (event) => {
361
+ editingSource.current = true;
362
+ setSource(true);
363
+ if (accept(event.target.value)) setIssue(void 0);
364
+ },
365
+ slotProps: { input: { readOnly: props.readOnly }, htmlInput: { spellCheck: false } },
366
+ onKeyDown: (event) => {
367
+ if (event.key === "Escape") {
368
+ event.stopPropagation();
369
+ props.onExit?.("forward");
370
+ }
371
+ if (props.onHistory && (event.ctrlKey || event.metaKey) && ["z", "y"].includes(event.key.toLowerCase())) {
372
+ event.preventDefault();
373
+ event.stopPropagation();
374
+ props.onHistory(event.shiftKey || event.key.toLowerCase() === "y");
375
+ }
376
+ },
377
+ sx: { flexBasis: "100%", mt: 1, "& textarea": { fontFamily: "monospace" } }
378
+ }
379
+ ),
380
+ issue && /* @__PURE__ */ jsx(Box, { component: "span", role: "status", sx: { typography: "caption", color: "text.secondary", flexBasis: "100%" }, children: labels[issue] })
381
+ ]
382
+ }
383
+ );
384
+ }
385
+ var opaque = /* @__PURE__ */ new Set([
386
+ "html",
387
+ "frontmatter",
388
+ "image",
389
+ "imageReference",
390
+ "linkReference",
391
+ "definition",
392
+ "footnoteDefinition",
393
+ "footnoteReference",
394
+ "containerDirective",
395
+ "leafDirective",
396
+ "textDirective"
397
+ ]);
398
+ var hasOpaque = (n) => (n.type === "code" || n.type === "math") && !!n.meta || n.type === "list" && n.children?.some((c) => typeof c.checked === "boolean") && !n.children?.every((c) => typeof c.checked === "boolean") || n.type === "table" && Array.isArray(n.align) && n.align.some(Boolean) || opaque.has(n.type) || n.type === "code" && ["mermaid", "pintora", "prism"].includes(String(n.lang).toLowerCase()) || !!n.children?.some(hasOpaque);
399
+ var newBlockId = () => crypto.randomUUID();
400
+ function semantic(n) {
401
+ const attrs = Object.fromEntries(
402
+ Object.entries(n.attrs ?? {}).filter(([k, v]) => !["source", "id"].includes(k) && v != null)
403
+ );
404
+ return {
405
+ type: n.type,
406
+ ...Object.keys(attrs).length ? { attrs } : {},
407
+ ...n.text !== void 0 ? { text: n.text } : {},
408
+ ...n.marks?.length ? { marks: n.marks } : {},
409
+ ...n.content?.length ? { content: n.content.map(semantic) } : {}
410
+ };
411
+ }
412
+ var signature = (content) => JSON.stringify(content.map(semantic));
413
+ function sourceDocument(source, id = newBlockId) {
414
+ if (source.length > researchLimits.source) throw new Error("document_limit");
415
+ parseResearchMarkdown(source);
416
+ const { body, metadata } = splitFrontmatter(source);
417
+ const ast = fromMarkdown(body, {
418
+ extensions: [gfm(), math(), directive()],
419
+ mdastExtensions: [gfmFromMarkdown(), mathFromMarkdown(), directiveFromMarkdown()]
420
+ });
421
+ if (metadata) {
422
+ const stop = metadata.end - (metadata.raw.endsWith("\r\n") ? 2 : metadata.raw.endsWith("\n") ? 1 : 0);
423
+ ast.children.unshift({ type: "frontmatter", position: { start: { offset: 0 }, end: { offset: stop } } });
424
+ }
425
+ let end = 0;
426
+ const content = (ast.children ?? []).map((n) => {
427
+ const start = n.position.start.offset, stop = n.position.end.offset;
428
+ const raw = source.slice(start, stop), prefix = source.slice(end, start);
429
+ end = stop;
430
+ const nodes = hasOpaque(n) ? [{ type: "researchSource", attrs: { raw, kind: n.type === "code" ? String(n.lang) : n.type } }] : parseResearchMarkdown(raw).doc.content;
431
+ const cleaned = nodes.map(cleanNode);
432
+ return {
433
+ type: "researchBlock",
434
+ attrs: { id: id(), raw, prefix, baseline: signature(cleaned) },
435
+ content: cleaned.length ? cleaned : [{ type: "paragraph" }]
436
+ };
437
+ });
438
+ return {
439
+ type: "doc",
440
+ attrs: { tail: source.slice(end) },
441
+ content: content.length ? content : [
442
+ {
443
+ type: "researchBlock",
444
+ attrs: { id: id(), raw: "", prefix: "", baseline: signature([{ type: "paragraph" }]) },
445
+ content: [{ type: "paragraph" }]
446
+ }
447
+ ]
448
+ };
449
+ }
450
+ function cleanNode(n) {
451
+ const attrs = Object.fromEntries(Object.entries(n.attrs ?? {}).filter(([k]) => !["source", "id"].includes(k)));
452
+ if (n.type === "orderedList") attrs.start ??= 1;
453
+ if (n.type === "codeBlock") attrs.language ||= null;
454
+ if (n.type === "taskItem") attrs.checked ??= false;
455
+ return { ...n, attrs, content: n.content?.map(cleanNode) };
456
+ }
457
+ function astNode(n) {
458
+ const children = () => (n.content ?? []).map(astNode), a = n.attrs ?? {};
459
+ let result;
460
+ switch (n.type) {
461
+ case "paragraph":
462
+ result = { type: "paragraph", children: children() };
463
+ break;
464
+ case "heading":
465
+ result = { type: "heading", depth: a.level, children: children() };
466
+ break;
467
+ case "text":
468
+ result = { type: "text", value: n.text ?? "" };
469
+ break;
470
+ case "hardBreak":
471
+ return { type: "break" };
472
+ case "horizontalRule":
473
+ return { type: "thematicBreak" };
474
+ case "blockquote":
475
+ return { type: "blockquote", children: children() };
476
+ case "codeBlock":
477
+ return { type: "code", lang: a.language || null, value: (n.content ?? []).map((x) => x.text ?? "").join("") };
478
+ case "mathBlock":
479
+ return { type: "math", value: a.tex ?? "" };
480
+ case "mathInline":
481
+ result = { type: "inlineMath", value: a.tex ?? "" };
482
+ break;
483
+ case "bulletList":
484
+ case "orderedList":
485
+ case "taskList":
486
+ return {
487
+ type: "list",
488
+ ordered: n.type === "orderedList",
489
+ start: a.start ?? 1,
490
+ spread: false,
491
+ children: children()
492
+ };
493
+ case "listItem":
494
+ case "taskItem":
495
+ return {
496
+ type: "listItem",
497
+ spread: false,
498
+ checked: n.type === "taskItem" ? !!a.checked : null,
499
+ children: children()
500
+ };
501
+ case "table":
502
+ return { type: "table", align: (n.content?.[0]?.content ?? []).map(() => null), children: children() };
503
+ case "tableRow":
504
+ return { type: "tableRow", children: children() };
505
+ case "tableCell":
506
+ case "tableHeader":
507
+ if ((a.colspan ?? 1) !== 1 || (a.rowspan ?? 1) !== 1 || n.content?.length !== 1 || n.content[0]?.type !== "paragraph")
508
+ throw Error("unsupported_table_shape");
509
+ return { type: "tableCell", children: (n.content ?? []).flatMap((p) => (p.content ?? []).map(astNode)) };
510
+ default:
511
+ throw new Error(`unsupported_editor_node:${n.type}`);
512
+ }
513
+ for (const mark of n.marks ?? []) {
514
+ const type = { bold: "strong", italic: "emphasis", strike: "delete", code: "inlineCode", link: "link" }[mark.type];
515
+ if (!type) throw new Error(`unsupported_editor_mark:${mark.type}`);
516
+ if (type === "inlineCode") result = { type, value: n.text ?? "" };
517
+ else
518
+ result = {
519
+ type,
520
+ ...type === "link" ? { url: mark.attrs?.href, title: mark.attrs?.title ?? null } : {},
521
+ children: [result]
522
+ };
523
+ }
524
+ return result;
525
+ }
526
+ function blockSource(block) {
527
+ const content = block.content ?? [];
528
+ if (signature(content) === block.attrs?.baseline) return String(block.attrs.raw ?? "");
529
+ if (content.length === 1 && content[0]?.type === "researchSource") return String(content[0].attrs?.raw ?? "");
530
+ return toMarkdown({ type: "root", children: content.map(astNode) }, {
531
+ extensions: [gfmToMarkdown(), mathToMarkdown()],
532
+ bullet: "-",
533
+ fences: true
534
+ }).replace(/\n$/, "");
535
+ }
536
+ var blockCache = /* @__PURE__ */ new WeakMap();
537
+ function editorSource(doc) {
538
+ const parts = [];
539
+ doc.forEach((block, _offset, index) => {
540
+ let raw = blockCache.get(block);
541
+ if (raw === void 0) {
542
+ raw = blockSource(block.toJSON());
543
+ blockCache.set(block, raw);
544
+ }
545
+ const prefix = String(block.attrs.prefix ?? "");
546
+ const afterMetadata = index === 1 && doc.firstChild?.firstChild?.attrs.kind === "frontmatter";
547
+ parts.push(index === 0 || afterMetadata ? prefix : /\r?\n[ \t]*\r?\n/.test(prefix) ? prefix : "\n\n", raw);
548
+ });
549
+ return parts.join("") + String(doc.attrs.tail ?? "");
550
+ }
551
+ function snapshot(doc) {
552
+ let source;
553
+ return Object.freeze({
554
+ format: "prism-research-source/1",
555
+ blocks: doc.childCount,
556
+ getSource: () => source ??= editorSource(doc)
557
+ });
558
+ }
559
+ function hydrateSource(source, schema) {
560
+ const doc = sourceDocument(source);
561
+ for (const block of doc.content ?? [])
562
+ block.attrs.baseline = signature(schema.nodeFromJSON(block).toJSON().content ?? []);
563
+ schema.nodeFromJSON(doc).check();
564
+ return doc;
565
+ }
566
+
567
+ // src/components/research-editor/math-navigation.ts
568
+ function exitMathTransaction(state, pos, before) {
569
+ const node = state.doc.nodeAt(pos);
570
+ if (!node || !["mathInline", "mathBlock"].includes(node.type.name)) return void 0;
571
+ const tr = state.tr;
572
+ let target = TextSelection.near(tr.doc.resolve(before ? pos : pos + node.nodeSize), before ? -1 : 1);
573
+ const neighbourMath = target instanceof NodeSelection && ["mathInline", "mathBlock"].includes(target.node.type.name) && target.from !== pos;
574
+ const reachableText = target instanceof TextSelection && (before ? target.from <= pos : target.from >= pos + node.nodeSize);
575
+ if (!neighbourMath && !reachableText) {
576
+ const $pos = tr.doc.resolve(pos);
577
+ const edge = before ? $pos.before(1) : $pos.after(1);
578
+ tr.insert(
579
+ edge,
580
+ state.schema.nodes.researchBlock.create({ id: newBlockId() }, state.schema.nodes.paragraph.create())
581
+ );
582
+ target = TextSelection.create(tr.doc, edge + 2);
583
+ }
584
+ return closeHistory(tr.setSelection(target)).setMeta("prismMathEntry", before ? "end" : "start").scrollIntoView();
585
+ }
586
+ function updateMathTransaction(state, pos, tex) {
587
+ const node = state.doc.nodeAt(pos);
588
+ if (!node || !["mathInline", "mathBlock"].includes(node.type.name)) return void 0;
589
+ const tr = state.tr.setNodeMarkup(pos, void 0, { ...node.attrs, tex });
590
+ if (state.selection instanceof NodeSelection && state.selection.from === pos)
591
+ tr.setSelection(NodeSelection.create(tr.doc, pos));
592
+ return tr;
593
+ }
594
+ var mathEntryKey = new PluginKey("researchMathEntry");
595
+ var ResearchMathContext = createContext({});
596
+ function MathNodeView({ node, editor, getPos, selected }) {
597
+ const config = useContext(ResearchMathContext);
598
+ const display = node.type.name === "mathBlock", latex = String(node.attrs.tex);
599
+ const editable = config.readOnly === void 0 ? editor.isEditable : !config.readOnly;
600
+ const active = selected && editable;
601
+ const preview = useRef(null);
602
+ useEffect(() => {
603
+ if (!preview.current) return;
604
+ try {
605
+ katex.render(latex === "\\placeholder{}" ? "\\square" : latex, preview.current, {
606
+ displayMode: display,
607
+ trust: false,
608
+ strict: "error",
609
+ throwOnError: true,
610
+ maxExpand: 1e3,
611
+ maxSize: 20
612
+ });
613
+ } catch {
614
+ preview.current.textContent = latex || config.labels?.field || "Equation";
615
+ }
616
+ }, [latex, display, active, config.labels?.field]);
617
+ useEffect(() => {
618
+ if (active) editor.view.dispatch(closeHistory(editor.state.tr));
619
+ return () => {
620
+ if (active && !editor.isDestroyed) editor.view.dispatch(closeHistory(editor.state.tr));
621
+ };
622
+ }, [active, editor]);
623
+ function exit(direction) {
624
+ const pos = getPos();
625
+ if (typeof pos !== "number" || editor.isDestroyed) return;
626
+ const before = direction === "backward" || direction === "upward";
627
+ const tr = exitMathTransaction(editor.state, pos, before);
628
+ if (tr) flushSync(() => editor.view.dispatch(tr));
629
+ editor.view.focus();
630
+ }
631
+ return /* @__PURE__ */ jsx(
632
+ NodeViewWrapper,
633
+ {
634
+ as: display ? "div" : "span",
635
+ className: `prism-science__math${display ? " prism-science__math--display" : ""}`,
636
+ contentEditable: false,
637
+ children: active ? /* @__PURE__ */ jsx(
638
+ MathInput,
639
+ {
640
+ ...config,
641
+ value: latex,
642
+ display,
643
+ entry: mathEntryKey.getState(editor.state),
644
+ autoFocus: true,
645
+ onChange: (input) => {
646
+ const value = input || "\\placeholder{}";
647
+ const pos = getPos();
648
+ if (!editor.isEditable || typeof pos !== "number" || editor.state.doc.nodeAt(pos)?.type !== node.type)
649
+ return false;
650
+ if (value === editor.state.doc.nodeAt(pos)?.attrs.tex) return true;
651
+ const tr = updateMathTransaction(editor.state, pos, value);
652
+ if (!tr) return false;
653
+ editor.view.dispatch(tr);
654
+ return editor.state.doc.nodeAt(pos)?.attrs.tex === value;
655
+ },
656
+ onExit: exit,
657
+ onHistory: (redo) => {
658
+ if (redo) editor.commands.redo();
659
+ else editor.commands.undo();
660
+ }
661
+ }
662
+ ) : /* @__PURE__ */ jsx(
663
+ "span",
664
+ {
665
+ ref: preview,
666
+ role: editable ? "button" : "math",
667
+ tabIndex: editable ? 0 : void 0,
668
+ "aria-label": `${config.labels?.field ?? "Equation"}: ${latex}`,
669
+ className: "prism-science__math-preview",
670
+ onClick: () => {
671
+ const pos = getPos();
672
+ if (editor.isEditable && !config.readOnly && typeof pos === "number") editor.commands.setNodeSelection(pos);
673
+ },
674
+ onKeyDown: (event) => {
675
+ if (event.key === "Enter" || event.key === " ") {
676
+ event.preventDefault();
677
+ event.currentTarget.click();
678
+ }
679
+ }
680
+ }
681
+ )
682
+ }
683
+ );
684
+ }
685
+ function findBlock(doc, id) {
686
+ let found;
687
+ doc.forEach((node, pos, index) => {
688
+ if (node.type.name === "researchBlock" && node.attrs.id === id) found = { node, pos, index };
689
+ });
690
+ return found;
691
+ }
692
+ function currentBlock(editor) {
693
+ const { $from } = editor.state.selection;
694
+ if ($from.depth >= 1) return { pos: $from.before(1), index: $from.index(0) };
695
+ const index = $from.index(0);
696
+ return editor.state.doc.childCount ? {
697
+ pos: index >= editor.state.doc.childCount ? editor.state.doc.content.size - editor.state.doc.lastChild.nodeSize : $from.pos,
698
+ index: Math.min(index, editor.state.doc.childCount - 1)
699
+ } : void 0;
700
+ }
701
+ function selectMoved(tr, state, oldPos, newPos, node) {
702
+ const { selection } = state;
703
+ const within = selection.from >= oldPos && selection.to <= oldPos + node.nodeSize;
704
+ if (within && selection instanceof TextSelection) {
705
+ tr.setSelection(TextSelection.create(tr.doc, newPos + selection.anchor - oldPos, newPos + selection.head - oldPos));
706
+ } else if (within && selection instanceof NodeSelection) {
707
+ tr.setSelection(NodeSelection.create(tr.doc, newPos + selection.from - oldPos));
708
+ } else {
709
+ tr.setSelection(Selection.near(tr.doc.resolve(newPos + 1)));
710
+ }
711
+ return closeHistory(tr).scrollIntoView();
712
+ }
713
+ function moveBlockTransaction(state, id, beforeId) {
714
+ const from = findBlock(state.doc, id);
715
+ const before = beforeId === null ? void 0 : findBlock(state.doc, beforeId);
716
+ if (!from || beforeId !== null && !before || beforeId === id) return void 0;
717
+ const destination = before?.index ?? state.doc.childCount;
718
+ if (destination === from.index + 1 || destination === state.doc.childCount && from.index === destination - 1)
719
+ return void 0;
720
+ const tr = state.tr.delete(from.pos, from.pos + from.node.nodeSize);
721
+ const target = beforeId === null ? tr.doc.content.size : findBlock(tr.doc, beforeId).pos;
722
+ tr.insert(target, from.node);
723
+ return selectMoved(tr, state, from.pos, target, from.node);
724
+ }
725
+ function blockActionTransaction(state, id, action) {
726
+ const block = findBlock(state.doc, id);
727
+ if (!block) return void 0;
728
+ const { node, pos, index } = block;
729
+ if (action === "up")
730
+ return index > 0 ? moveBlockTransaction(state, id, String(state.doc.child(index - 1).attrs.id)) : void 0;
731
+ if (action === "down")
732
+ return index < state.doc.childCount - 1 ? moveBlockTransaction(
733
+ state,
734
+ id,
735
+ index + 2 < state.doc.childCount ? String(state.doc.child(index + 2).attrs.id) : null
736
+ ) : void 0;
737
+ const tr = state.tr;
738
+ if (action === "duplicate") {
739
+ const copy = node.type.create({ ...node.attrs, id: newBlockId(), prefix: "\n\n" }, node.content);
740
+ tr.insert(pos + node.nodeSize, copy);
741
+ return selectMoved(tr, state, pos, pos + node.nodeSize, copy);
742
+ }
743
+ if (state.doc.childCount === 1) {
744
+ tr.replaceWith(
745
+ pos,
746
+ pos + node.nodeSize,
747
+ node.type.create({ id: newBlockId() }, state.schema.nodes.paragraph.create())
748
+ );
749
+ } else {
750
+ tr.delete(pos, pos + node.nodeSize);
751
+ }
752
+ tr.setSelection(Selection.near(tr.doc.resolve(Math.min(pos + 1, tr.doc.content.size))));
753
+ return closeHistory(tr).scrollIntoView();
754
+ }
755
+ function runBlockAction(editor, action, id) {
756
+ if (!editor.isEditable) return false;
757
+ const selected = currentBlock(editor);
758
+ const target = id ?? (selected && String(editor.state.doc.child(selected.index).attrs.id));
759
+ const tr = target && blockActionTransaction(editor.state, target, action);
760
+ return dispatchBlockTransaction(editor, tr || void 0);
761
+ }
762
+ function dispatchBlockTransaction(editor, tr) {
763
+ if (!editor.isEditable || !tr) return false;
764
+ editor.view.dispatch(tr);
765
+ editor.view.dispatch(closeHistory(editor.state.tr));
766
+ editor.commands.focus();
767
+ return true;
768
+ }
769
+ var ResearchViewContext = createContext(void 0);
770
+ function SourceView({ node, extension }) {
771
+ const presentation = useContext(ResearchViewContext);
772
+ const ref = useRef(null), [visible, setVisible] = useState(false);
773
+ useEffect(() => {
774
+ if (!ref.current) return void 0;
775
+ if (typeof IntersectionObserver === "undefined") {
776
+ setVisible(true);
777
+ return void 0;
778
+ }
779
+ const observer = new IntersectionObserver(
780
+ (entries) => {
781
+ if (entries.some((e) => e.isIntersecting)) {
782
+ setVisible(true);
783
+ observer.disconnect();
784
+ }
785
+ },
786
+ { rootMargin: "200px" }
787
+ );
788
+ observer.observe(ref.current);
789
+ return () => observer.disconnect();
790
+ }, []);
791
+ return /* @__PURE__ */ jsx(NodeViewWrapper, { className: "prism-science__source-block", contentEditable: false, children: /* @__PURE__ */ jsxs("div", { ref, children: [
792
+ /* @__PURE__ */ jsx("span", { className: "prism-science__kind", children: String(node.attrs.kind) }),
793
+ visible ? /* @__PURE__ */ jsx(
794
+ ResearchDocument,
795
+ {
796
+ source: String(node.attrs.raw),
797
+ widgets: presentation?.widgets ?? extension.options.widgets,
798
+ labels: presentation?.labels ?? extension.options.labels
799
+ }
800
+ ) : /* @__PURE__ */ jsx("pre", { children: String(node.attrs.raw).slice(0, 160) })
801
+ ] }) });
802
+ }
803
+ function researchExtensions(widgets = {}, limits, labels) {
804
+ const Doc = Node.create({
805
+ name: "doc",
806
+ topNode: true,
807
+ content: "researchBlock+",
808
+ addAttributes: () => ({ tail: { default: "" } })
809
+ });
810
+ const Block = Node.create({
811
+ name: "researchBlock",
812
+ content: "block+",
813
+ group: "researchGroup",
814
+ defining: true,
815
+ draggable: true,
816
+ addAttributes: () => ({
817
+ id: { default: null },
818
+ raw: { default: "" },
819
+ prefix: { default: "" },
820
+ baseline: { default: "" }
821
+ }),
822
+ parseHTML: () => [{ tag: "div[data-research-block]" }],
823
+ renderHTML: ({ node }) => ["div", { "data-research-block": node.attrs.id, class: "prism-science__block" }, 0],
824
+ addKeyboardShortcuts() {
825
+ return {
826
+ "Mod-Alt-ArrowUp": () => runBlockAction(this.editor, "up"),
827
+ "Mod-Alt-ArrowDown": () => runBlockAction(this.editor, "down"),
828
+ Enter: () => {
829
+ if (!this.editor.isEditable) return false;
830
+ const { state, view } = this.editor, { $from, $to } = state.selection;
831
+ if (!$from.sameParent($to) || $from.depth !== 2 || !["paragraph", "heading"].includes($from.parent.type.name))
832
+ return false;
833
+ const next = $from.parentOffset === $from.parent.content.size ? state.schema.nodes.paragraph : $from.parent.type;
834
+ const types = [
835
+ { type: state.schema.nodes.researchBlock, attrs: { id: newBlockId() } },
836
+ { type: next, attrs: $from.parent.attrs }
837
+ ];
838
+ const tr = state.tr.deleteSelection();
839
+ if (!canSplit(tr.doc, tr.selection.from, 2, types)) return false;
840
+ view.dispatch(tr.split(tr.selection.from, 2, types).scrollIntoView());
841
+ return true;
842
+ }
843
+ };
844
+ }
845
+ });
846
+ const Source = Node.create({
847
+ name: "researchSource",
848
+ group: "block",
849
+ atom: true,
850
+ selectable: true,
851
+ addOptions: () => ({ widgets, labels }),
852
+ addAttributes: () => ({ raw: { default: "" }, kind: { default: "source" } }),
853
+ parseHTML: () => [
854
+ {
855
+ tag: "pre[data-research-source]",
856
+ priority: 100,
857
+ preserveWhitespace: "full",
858
+ getAttrs: (element) => ({
859
+ raw: element.getAttribute("data-source") ?? element.textContent ?? "",
860
+ kind: element.getAttribute("data-research-source") ?? "source"
861
+ })
862
+ }
863
+ ],
864
+ renderHTML: ({ node }) => [
865
+ "pre",
866
+ { "data-research-source": node.attrs.kind, "data-source": node.attrs.raw },
867
+ node.attrs.raw
868
+ ],
869
+ addNodeView: () => ReactNodeViewRenderer(SourceView)
870
+ });
871
+ const mathNode = (name) => Node.create({
872
+ name,
873
+ marks: name === "mathInline" ? "bold italic strike link" : "",
874
+ group: name === "mathInline" ? "inline" : "block",
875
+ inline: name === "mathInline",
876
+ atom: true,
877
+ selectable: true,
878
+ addAttributes: () => ({ tex: { default: "" } }),
879
+ parseHTML: () => [
880
+ {
881
+ tag: name === "mathInline" ? "span[data-math-inline]" : "div[data-math-block]",
882
+ getAttrs: (element) => ({ tex: element.getAttribute("data-tex") ?? element.textContent ?? "" })
883
+ }
884
+ ],
885
+ renderHTML: ({ node }) => [
886
+ name === "mathInline" ? "span" : "div",
887
+ {
888
+ [name === "mathInline" ? "data-math-inline" : "data-math-block"]: true,
889
+ "data-tex": String(node.attrs.tex)
890
+ },
891
+ String(node.attrs.tex)
892
+ ],
893
+ addNodeView: () => ReactNodeViewRenderer(MathNodeView, {
894
+ // Shadow-DOM math input is not a native INPUT/TEXTAREA. Letting its keys
895
+ // reach ProseMirror would replace the selected atom with ordinary text.
896
+ stopEvent: ({ event }) => event.target instanceof Element && !!event.target.closest(".prism-math-input")
897
+ }),
898
+ addKeyboardShortcuts() {
899
+ const enter = (backward) => {
900
+ if (!this.editor.isEditable || !this.editor.state.selection.empty) return false;
901
+ const { $from } = this.editor.state.selection;
902
+ const next = backward ? $from.nodeBefore : $from.nodeAfter;
903
+ if (next?.type.name !== "mathInline") return false;
904
+ const pos = backward ? $from.pos - next.nodeSize : $from.pos;
905
+ this.editor.view.dispatch(
906
+ this.editor.state.tr.setSelection(NodeSelection.create(this.editor.state.doc, pos)).setMeta("prismMathEntry", backward ? "end" : "start")
907
+ );
908
+ return true;
909
+ };
910
+ return { ArrowLeft: () => enter(true), ArrowRight: () => enter(false) };
911
+ }
912
+ });
913
+ const Ids = Extension.create({
914
+ name: "researchIds",
915
+ addProseMirrorPlugins() {
916
+ return [
917
+ new Plugin({
918
+ key: mathEntryKey,
919
+ state: { init: () => "end", apply: (tr, value) => tr.getMeta("prismMathEntry") ?? value }
920
+ }),
921
+ new Plugin({
922
+ props: {
923
+ decorations(state) {
924
+ const { from, to, empty } = state.selection;
925
+ const decorations = [];
926
+ state.doc.forEach((node, pos) => {
927
+ if (empty ? from >= pos && from < pos + node.nodeSize : from < pos + node.nodeSize && to > pos)
928
+ decorations.push(
929
+ Decoration.node(pos, pos + node.nodeSize, { class: empty ? "is-current" : "is-selected" })
930
+ );
931
+ });
932
+ return DecorationSet.create(state.doc, decorations);
933
+ }
934
+ },
935
+ filterTransaction(tr) {
936
+ if (!tr.docChanged || !limits) return true;
937
+ try {
938
+ if (snapshot(tr.doc).getSource().length <= limits.source) return true;
939
+ } catch {
940
+ }
941
+ limits.onLimit?.();
942
+ return false;
943
+ },
944
+ appendTransaction(transactions, _old, state) {
945
+ if (!transactions.some((t) => t.docChanged)) return null;
946
+ const seen = /* @__PURE__ */ new Set(), tr = state.tr;
947
+ state.doc.forEach((node, pos) => {
948
+ const id = node.attrs.id;
949
+ if (!id || seen.has(id)) tr.setNodeMarkup(pos, void 0, { ...node.attrs, id: newBlockId() });
950
+ else seen.add(id);
951
+ });
952
+ return tr.docChanged ? tr.setMeta("addToHistory", false) : null;
953
+ }
954
+ })
955
+ ];
956
+ }
957
+ });
958
+ return [
959
+ Doc,
960
+ Block,
961
+ StarterKit.configure({ document: false, underline: false, link: { openOnClick: false }, trailingNode: false }),
962
+ TaskList,
963
+ TaskItem.configure({ nested: true, a11y: { checkboxLabel: (node) => node.textContent } }),
964
+ TableKit.configure({ table: { resizable: false } }),
965
+ Source,
966
+ mathNode("mathInline"),
967
+ mathNode("mathBlock"),
968
+ Ids
969
+ ];
970
+ }
971
+ function BlockControls({
972
+ editor,
973
+ container,
974
+ labels,
975
+ readOnly,
976
+ onInsert,
977
+ onSource
978
+ }) {
979
+ const [anchor, setAnchor] = useState();
980
+ const [menu, setMenu] = useState();
981
+ const [dropTop, setDropTop] = useState();
982
+ const dragged = useRef(void 0);
983
+ useEffect(() => {
984
+ const host = container.current;
985
+ if (!host || readOnly) {
986
+ setAnchor(void 0);
987
+ setMenu(void 0);
988
+ setDropTop(void 0);
989
+ return void 0;
990
+ }
991
+ let hovered;
992
+ let frame = 0;
993
+ const selectedElement = () => {
994
+ const selected3 = currentBlock(editor);
995
+ const element = selected3 && editor.view.nodeDOM(selected3.pos);
996
+ return element instanceof HTMLElement ? element : void 0;
997
+ };
998
+ const update = () => {
999
+ frame = 0;
1000
+ const element = hovered && editor.view.dom.contains(hovered) ? hovered : selectedElement();
1001
+ const id = element?.getAttribute("data-research-block");
1002
+ if (!id || !element) {
1003
+ setAnchor(void 0);
1004
+ return;
1005
+ }
1006
+ const top = element.getBoundingClientRect().top - host.getBoundingClientRect().top;
1007
+ setAnchor((old) => old?.id === id && old.top === top ? old : { id, top });
1008
+ };
1009
+ const schedule = () => {
1010
+ if (!frame) frame = requestAnimationFrame(update);
1011
+ };
1012
+ const elementAt = (target) => {
1013
+ const element = target instanceof Element ? target.closest("[data-research-block]") : null;
1014
+ return element && editor.view.dom.contains(element) ? element : void 0;
1015
+ };
1016
+ const pointer = (event) => {
1017
+ if (dragged.current) return;
1018
+ const element = elementAt(event.target);
1019
+ if (element) {
1020
+ hovered = element;
1021
+ schedule();
1022
+ }
1023
+ };
1024
+ const selected2 = () => {
1025
+ hovered = void 0;
1026
+ schedule();
1027
+ };
1028
+ const clearDrop = () => {
1029
+ dragged.current = void 0;
1030
+ setDropTop(void 0);
1031
+ };
1032
+ const destination = (event) => {
1033
+ const element = elementAt(event.target);
1034
+ if (!element) return void 0;
1035
+ const id = element.getAttribute("data-research-block");
1036
+ const block = findBlock(editor.state.doc, id);
1037
+ if (!block) return void 0;
1038
+ const rect = element.getBoundingClientRect();
1039
+ const before = event.clientY < rect.top + rect.height / 2;
1040
+ return {
1041
+ id: before ? id : block.index + 1 < editor.state.doc.childCount ? String(editor.state.doc.child(block.index + 1).attrs.id) : null,
1042
+ top: (before ? rect.top : rect.bottom) - host.getBoundingClientRect().top
1043
+ };
1044
+ };
1045
+ const over = (event) => {
1046
+ if (!dragged.current || !editor.isEditable) return;
1047
+ const target = destination(event);
1048
+ if (!target) {
1049
+ setDropTop(void 0);
1050
+ return;
1051
+ }
1052
+ event.preventDefault();
1053
+ event.stopPropagation();
1054
+ if (event.dataTransfer) event.dataTransfer.dropEffect = "move";
1055
+ setDropTop(target.top);
1056
+ };
1057
+ const drop = (event) => {
1058
+ if (!dragged.current) return;
1059
+ event.preventDefault();
1060
+ event.stopPropagation();
1061
+ const target = destination(event);
1062
+ const tr = editor.isEditable && target && moveBlockTransaction(editor.state, dragged.current, target.id);
1063
+ clearDrop();
1064
+ if (tr) dispatchBlockTransaction(editor, tr);
1065
+ };
1066
+ host.addEventListener("pointermove", pointer);
1067
+ host.addEventListener("dragover", over, true);
1068
+ host.addEventListener("drop", drop, true);
1069
+ window.addEventListener("dragend", clearDrop);
1070
+ editor.on("selectionUpdate", selected2);
1071
+ editor.on("transaction", selected2);
1072
+ const observer = typeof ResizeObserver !== "undefined" ? new ResizeObserver(schedule) : void 0;
1073
+ observer?.observe(host);
1074
+ window.addEventListener("resize", schedule);
1075
+ update();
1076
+ return () => {
1077
+ cancelAnimationFrame(frame);
1078
+ observer?.disconnect();
1079
+ host.removeEventListener("pointermove", pointer);
1080
+ host.removeEventListener("dragover", over, true);
1081
+ host.removeEventListener("drop", drop, true);
1082
+ window.removeEventListener("dragend", clearDrop);
1083
+ window.removeEventListener("resize", schedule);
1084
+ editor.off("selectionUpdate", selected2);
1085
+ editor.off("transaction", selected2);
1086
+ dragged.current = void 0;
1087
+ };
1088
+ }, [editor, container, readOnly]);
1089
+ if (readOnly || !anchor) return null;
1090
+ const selected = menu && findBlock(editor.state.doc, menu.id);
1091
+ function action(kind) {
1092
+ if (menu) runBlockAction(editor, kind, menu.id);
1093
+ setMenu(void 0);
1094
+ }
1095
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
1096
+ /* @__PURE__ */ jsxs("div", { className: "prism-science__gutter", style: { top: anchor.top }, role: "group", "aria-label": labels.blockMenu, children: [
1097
+ /* @__PURE__ */ jsx(
1098
+ IconButton,
1099
+ {
1100
+ type: "button",
1101
+ title: labels.insert,
1102
+ "aria-label": labels.insert,
1103
+ onMouseDown: (e) => e.preventDefault(),
1104
+ onClick: () => onInsert(anchor.id),
1105
+ children: /* @__PURE__ */ jsx(AddIcon, { fontSize: "small" })
1106
+ }
1107
+ ),
1108
+ /* @__PURE__ */ jsx(
1109
+ IconButton,
1110
+ {
1111
+ type: "button",
1112
+ title: labels.dragBlock,
1113
+ "aria-label": labels.blockMenu,
1114
+ "aria-haspopup": "menu",
1115
+ "aria-expanded": !!menu,
1116
+ draggable: true,
1117
+ onDragStart: (event) => {
1118
+ if (!editor.isEditable || !findBlock(editor.state.doc, anchor.id)) {
1119
+ event.preventDefault();
1120
+ return;
1121
+ }
1122
+ dragged.current = anchor.id;
1123
+ event.dataTransfer.effectAllowed = "move";
1124
+ event.dataTransfer.setData("application/x-prism-block", anchor.id);
1125
+ setMenu(void 0);
1126
+ },
1127
+ onClick: (event) => setMenu({ id: anchor.id, element: event.currentTarget }),
1128
+ children: /* @__PURE__ */ jsx(DragIcon, { fontSize: "small" })
1129
+ }
1130
+ )
1131
+ ] }),
1132
+ dropTop !== void 0 && /* @__PURE__ */ jsx("div", { className: "prism-science__drop-line", style: { top: dropTop }, "aria-hidden": "true" }),
1133
+ /* @__PURE__ */ jsxs(Menu, { open: !!menu, anchorEl: menu?.element, onClose: () => setMenu(void 0), children: [
1134
+ /* @__PURE__ */ jsx(
1135
+ MenuItem,
1136
+ {
1137
+ disabled: !selected,
1138
+ onClick: () => {
1139
+ if (menu) onSource(menu.id);
1140
+ setMenu(void 0);
1141
+ },
1142
+ children: labels.editBlock
1143
+ }
1144
+ ),
1145
+ /* @__PURE__ */ jsx(MenuItem, { disabled: !selected || selected.index === 0, onClick: () => action("up"), children: labels.up }),
1146
+ /* @__PURE__ */ jsx(
1147
+ MenuItem,
1148
+ {
1149
+ disabled: !selected || selected.index === editor.state.doc.childCount - 1,
1150
+ onClick: () => action("down"),
1151
+ children: labels.down
1152
+ }
1153
+ ),
1154
+ /* @__PURE__ */ jsx(MenuItem, { disabled: !selected, onClick: () => action("duplicate"), children: labels.duplicate }),
1155
+ /* @__PURE__ */ jsx(MenuItem, { disabled: !selected, onClick: () => action("remove"), children: labels.remove })
1156
+ ] })
1157
+ ] });
1158
+ }
1159
+ var defaultResearchEditorLabels = {
1160
+ editor: "Research document",
1161
+ insert: "Insert block",
1162
+ search: "Find a block",
1163
+ source: "Document source",
1164
+ editBlock: "Block source",
1165
+ up: "Move block up",
1166
+ down: "Move block down",
1167
+ duplicate: "Duplicate block",
1168
+ remove: "Delete block",
1169
+ undo: "Undo",
1170
+ redo: "Redo",
1171
+ bold: "Bold",
1172
+ italic: "Italic",
1173
+ link: "Link",
1174
+ inlineMath: "Inline equation",
1175
+ apply: "Apply",
1176
+ cancel: "Cancel",
1177
+ invalid: "This source cannot be applied. Check the document limits and structure.",
1178
+ limit: "Document exceeds the configured source limit.",
1179
+ hint: "Type / for a new block. Ctrl/\u2318 + Shift + M inserts an equation. Arrow keys move between text and math.",
1180
+ paragraph: "Text",
1181
+ heading: "Heading",
1182
+ list: "Bullet list",
1183
+ ordered: "Numbered list",
1184
+ tasks: "Task list",
1185
+ quote: "Quote",
1186
+ code: "Code",
1187
+ equation: "Equation",
1188
+ diagram: "Diagram",
1189
+ table: "Table",
1190
+ widget: "Interactive block",
1191
+ blocks: "blocks",
1192
+ blockMenu: "Block actions",
1193
+ dragBlock: "Drag to move; click for block actions. Keyboard: Ctrl/Command + Alt + Up/Down."
1194
+ };
1195
+ var filterInsertions = createFilterOptions({
1196
+ stringify: (recipe) => [recipe.label, ...recipe.keywords ?? []].join(" ")
1197
+ });
1198
+ var noWidgets = Object.freeze({});
1199
+ var noInsertions = [];
1200
+ function ResearchEditor({
1201
+ initialSource,
1202
+ onChange,
1203
+ ref,
1204
+ readOnly = false,
1205
+ labels: overrides,
1206
+ widgets = noWidgets,
1207
+ previewLabels,
1208
+ insertions = noInsertions,
1209
+ maxSourceLength = researchLimits.source,
1210
+ blockControls = true,
1211
+ math: math2,
1212
+ className,
1213
+ sx
1214
+ }) {
1215
+ const presentation = useMemo(() => ({ widgets, labels: previewLabels }), [widgets, previewLabels]);
1216
+ const labels = useMemo(() => ({ ...defaultResearchEditorLabels, ...overrides }), [overrides]);
1217
+ const workspace = useRef(null);
1218
+ const notify = useRef(onChange);
1219
+ notify.current = onChange;
1220
+ const [palette, setPalette] = useState(false), [dialog, setDialog] = useState(), [invalid, setInvalid] = useState("");
1221
+ const extensions = useMemo(
1222
+ () => researchExtensions(widgets, { source: maxSourceLength, onLimit: () => setInvalid(labels.limit) }, previewLabels),
1223
+ [widgets, maxSourceLength, labels.limit, previewLabels]
1224
+ );
1225
+ const [initial] = useState(() => hydrateSource(initialSource, getSchema(extensions)));
1226
+ const editor = useEditor({
1227
+ extensions,
1228
+ content: initial,
1229
+ editable: !readOnly,
1230
+ immediatelyRender: false,
1231
+ shouldRerenderOnTransaction: false,
1232
+ editorProps: {
1233
+ attributes: { role: "textbox", "aria-multiline": "true", "aria-label": labels.editor },
1234
+ handleKeyDown: (view, event) => {
1235
+ if (!readOnly && !event.isComposing && (event.metaKey || event.ctrlKey) && event.shiftKey && event.key.toLowerCase() === "m") {
1236
+ event.preventDefault();
1237
+ insertInlineMath();
1238
+ return true;
1239
+ }
1240
+ if (event.key === "/" && !event.isComposing && !view.composing && view.state.selection.empty && view.state.selection.$from.parent.type.name === "paragraph" && view.state.selection.$from.parent.content.size === 0) {
1241
+ event.preventDefault();
1242
+ setPalette(true);
1243
+ return true;
1244
+ }
1245
+ return false;
1246
+ }
1247
+ },
1248
+ onUpdate: ({ editor: e }) => {
1249
+ setInvalid("");
1250
+ notify.current?.(snapshot(e.state.doc));
1251
+ }
1252
+ });
1253
+ useImperativeHandle(
1254
+ ref,
1255
+ () => ({
1256
+ getSnapshot: () => editor ? snapshot(editor.state.doc) : { format: "prism-research-source/1", blocks: initial.content?.length ?? 0, getSource: () => initialSource },
1257
+ focus: () => {
1258
+ editor?.commands.focus();
1259
+ }
1260
+ }),
1261
+ [editor, initial, initialSource]
1262
+ );
1263
+ useEffect(() => {
1264
+ editor?.setEditable(!readOnly, false);
1265
+ if (readOnly) {
1266
+ setPalette(false);
1267
+ setDialog(void 0);
1268
+ }
1269
+ }, [editor, readOnly]);
1270
+ const selection = useEditorState({
1271
+ editor,
1272
+ selector: ({ editor: e }) => e ? {
1273
+ bold: e.isActive("bold"),
1274
+ italic: e.isActive("italic"),
1275
+ index: currentBlock(e)?.index ?? 0,
1276
+ blocks: e.state.doc.childCount,
1277
+ undo: e.can().undo(),
1278
+ redo: e.can().redo()
1279
+ } : null
1280
+ });
1281
+ const blockIndex = selection?.index ?? (editor ? currentBlock(editor)?.index : void 0) ?? 0;
1282
+ const blockCount = selection?.blocks ?? editor?.state.doc.childCount ?? initial.content?.length ?? 1;
1283
+ const recipes = useMemo(
1284
+ () => [
1285
+ { id: "text", label: labels.paragraph, source: "" },
1286
+ { id: "heading", label: labels.heading, source: "## " },
1287
+ { id: "list", label: labels.list, source: "- " },
1288
+ { id: "ordered", label: labels.ordered, source: "1. " },
1289
+ { id: "tasks", label: labels.tasks, source: "- [ ] " },
1290
+ { id: "quote", label: labels.quote, source: "> " },
1291
+ { id: "code", label: labels.code, source: "```\n\n```" },
1292
+ { id: "equation", label: labels.equation, source: "$$\n\\placeholder{}\n$$" },
1293
+ { id: "diagram", label: labels.diagram, source: "```mermaid\nflowchart LR\n A[Source] --> B[Question]\n```" },
1294
+ { id: "table", label: labels.table, source: "| A | B |\n| --- | --- |\n| | |" },
1295
+ ...insertions
1296
+ ],
1297
+ [labels, insertions]
1298
+ );
1299
+ function insertInlineMath() {
1300
+ if (!editor?.isEditable) return;
1301
+ if (editor.state.selection instanceof NodeSelection && editor.state.selection.node.type.name === "mathInline")
1302
+ return;
1303
+ const tr = editor.state.tr.replaceSelectionWith(editor.schema.nodes.mathInline.create({ tex: "\\placeholder{}" }));
1304
+ tr.setSelection(NodeSelection.create(tr.doc, tr.selection.from - 1));
1305
+ editor.view.dispatch(tr.setMeta("prismMathEntry", "start"));
1306
+ }
1307
+ function applyDocument(source) {
1308
+ if (!editor) return;
1309
+ if (source.length > maxSourceLength) throw Error("document_limit");
1310
+ const json = hydrateSource(source, editor.schema), doc = editor.schema.nodeFromJSON(json);
1311
+ editor.view.dispatch(
1312
+ editor.state.tr.replaceWith(0, editor.state.doc.content.size, doc.content).setDocAttribute("tail", doc.attrs.tail).scrollIntoView()
1313
+ );
1314
+ }
1315
+ function insert(recipe) {
1316
+ if (!editor?.isEditable) return;
1317
+ const selected = currentBlock(editor), old = selected && editor.state.doc.child(selected.index);
1318
+ const blocks = hydrateSource(recipe.source, editor.schema).content ?? [];
1319
+ const simple = {
1320
+ heading: { type: "heading", attrs: { level: 2 } },
1321
+ list: { type: "bulletList", content: [{ type: "listItem", content: [{ type: "paragraph" }] }] },
1322
+ ordered: { type: "orderedList", content: [{ type: "listItem", content: [{ type: "paragraph" }] }] },
1323
+ tasks: {
1324
+ type: "taskList",
1325
+ content: [{ type: "taskItem", attrs: { checked: false }, content: [{ type: "paragraph" }] }]
1326
+ },
1327
+ quote: { type: "blockquote", content: [{ type: "paragraph" }] }
1328
+ };
1329
+ if (simple[recipe.id] && blocks[0]) {
1330
+ blocks[0].content = [simple[recipe.id]];
1331
+ blocks[0].attrs.baseline = "";
1332
+ }
1333
+ const empty = old?.childCount === 1 && old.firstChild?.type.name === "paragraph" && old.firstChild.content.size === 0;
1334
+ const from = selected ? selected.pos + (empty ? 0 : old.nodeSize) : editor.state.doc.content.size;
1335
+ const to = empty ? from + old.nodeSize : from;
1336
+ const tr = editor.state.tr.replaceWith(
1337
+ from,
1338
+ to,
1339
+ blocks.map((b) => editor.schema.nodeFromJSON(b))
1340
+ );
1341
+ const first = tr.doc.nodeAt(from)?.firstChild;
1342
+ tr.setSelection(
1343
+ first?.isAtom && !first.isTextblock ? NodeSelection.create(tr.doc, from + 1) : TextSelection.near(tr.doc.resolve(Math.min(from + 2, tr.doc.content.size)))
1344
+ );
1345
+ editor.view.dispatch(tr.scrollIntoView());
1346
+ setPalette(false);
1347
+ editor.commands.focus();
1348
+ }
1349
+ function openSource(id) {
1350
+ if (!editor?.isEditable) return;
1351
+ const block = id ? findBlock(editor.state.doc, id) : currentBlock(editor);
1352
+ if (!block) return;
1353
+ setDialog({ kind: "block", pos: block.pos, text: blockSource(editor.state.doc.child(block.index).toJSON()) });
1354
+ }
1355
+ function applyDialog(text) {
1356
+ if (!editor?.isEditable || !dialog) return;
1357
+ try {
1358
+ if (dialog.kind === "document") applyDocument(text);
1359
+ else if (dialog.kind === "block") {
1360
+ const old = editor.state.doc.nodeAt(dialog.pos);
1361
+ if (!old) throw Error("stale_selection");
1362
+ const blocks = hydrateSource(text, editor.schema).content;
1363
+ blocks[0].attrs = { ...blocks[0].attrs, id: old.attrs.id, prefix: old.attrs.prefix };
1364
+ const tr = editor.state.tr.replaceWith(
1365
+ dialog.pos,
1366
+ dialog.pos + old.nodeSize,
1367
+ blocks.map((b) => editor.schema.nodeFromJSON(b))
1368
+ );
1369
+ if (snapshot(tr.doc).getSource().length > maxSourceLength) throw Error("document_limit");
1370
+ editor.view.dispatch(tr.scrollIntoView());
1371
+ } else {
1372
+ if (text && !/^(https?:\/\/|mailto:)/i.test(text)) throw Error("invalid_link");
1373
+ const chain = editor.chain().focus().extendMarkRange("link");
1374
+ if (text) chain.setLink({ href: text }).run();
1375
+ else chain.unsetLink().run();
1376
+ }
1377
+ setDialog(void 0);
1378
+ setInvalid("");
1379
+ editor.commands.focus();
1380
+ } catch {
1381
+ setInvalid(labels.invalid);
1382
+ }
1383
+ }
1384
+ const button = (label, action, disabled = false, pressed, icon) => /* @__PURE__ */ jsx(
1385
+ Button2,
1386
+ {
1387
+ size: "small",
1388
+ startIcon: icon,
1389
+ variant: pressed ? "contained" : "text",
1390
+ type: "button",
1391
+ title: label,
1392
+ "aria-label": label,
1393
+ "aria-pressed": pressed,
1394
+ disabled: readOnly || !editor || disabled,
1395
+ onMouseDown: (e) => e.preventDefault(),
1396
+ onClick: () => action(),
1397
+ children: label
1398
+ }
1399
+ );
1400
+ return /* @__PURE__ */ jsxs(
1401
+ Box,
1402
+ {
1403
+ className: ["prism-science", className].filter(Boolean).join(" "),
1404
+ sx: [
1405
+ (theme) => ({
1406
+ "--prism-editor-border": theme.palette.divider,
1407
+ "--prism-editor-bg": theme.palette.background.paper,
1408
+ "--prism-editor-muted": theme.palette.text.secondary,
1409
+ "--prism-editor-accent": theme.palette.primary.main,
1410
+ "--prism-editor-radius": `${theme.shape.borderRadius}px`
1411
+ }),
1412
+ ...Array.isArray(sx) ? sx : [sx]
1413
+ ],
1414
+ children: [
1415
+ /* @__PURE__ */ jsxs("div", { className: "prism-science__toolbar", role: "toolbar", "aria-label": labels.editor, children: [
1416
+ button(labels.insert, () => setPalette(true), false, void 0, /* @__PURE__ */ jsx(AddIcon, {})),
1417
+ button(
1418
+ labels.bold,
1419
+ () => {
1420
+ editor?.chain().focus().toggleBold().run();
1421
+ },
1422
+ false,
1423
+ selection?.bold
1424
+ ),
1425
+ button(
1426
+ labels.italic,
1427
+ () => {
1428
+ editor?.chain().focus().toggleItalic().run();
1429
+ },
1430
+ false,
1431
+ selection?.italic
1432
+ ),
1433
+ button(labels.link, () => setDialog({ kind: "link", text: String(editor?.getAttributes("link").href ?? "") })),
1434
+ button(labels.inlineMath, insertInlineMath),
1435
+ button(
1436
+ labels.undo,
1437
+ () => {
1438
+ editor?.chain().focus().undo().run();
1439
+ },
1440
+ !selection?.undo
1441
+ ),
1442
+ button(
1443
+ labels.redo,
1444
+ () => {
1445
+ editor?.chain().focus().redo().run();
1446
+ },
1447
+ !selection?.redo
1448
+ ),
1449
+ button(labels.source, () => {
1450
+ if (editor) setDialog({ kind: "document", text: snapshot(editor.state.doc).getSource() });
1451
+ })
1452
+ ] }),
1453
+ /* @__PURE__ */ jsx("p", { className: "prism-science__hint", children: labels.hint }),
1454
+ invalid && !dialog && /* @__PURE__ */ jsx("p", { role: "alert", children: invalid }),
1455
+ /* @__PURE__ */ jsxs(
1456
+ "div",
1457
+ {
1458
+ ref: workspace,
1459
+ className: `prism-science__workspace${blockControls ? " prism-science__workspace--controls" : ""}`,
1460
+ children: [
1461
+ /* @__PURE__ */ jsx(ResearchViewContext.Provider, { value: presentation, children: /* @__PURE__ */ jsx(ResearchMathContext.Provider, { value: { ...math2, readOnly }, children: /* @__PURE__ */ jsx(EditorContent, { editor, className: "prism-science__content" }) }) }),
1462
+ editor && blockControls && /* @__PURE__ */ jsx(
1463
+ BlockControls,
1464
+ {
1465
+ editor,
1466
+ container: workspace,
1467
+ labels,
1468
+ readOnly,
1469
+ onSource: openSource,
1470
+ onInsert: (id) => {
1471
+ if (!editor.isEditable) return;
1472
+ const block = findBlock(editor.state.doc, id);
1473
+ if (block) {
1474
+ editor.commands.setNodeSelection(block.pos);
1475
+ setPalette(true);
1476
+ }
1477
+ }
1478
+ }
1479
+ )
1480
+ ]
1481
+ }
1482
+ ),
1483
+ /* @__PURE__ */ jsxs("div", { className: "prism-science__block-tools", role: "group", "aria-label": labels.editBlock, children: [
1484
+ /* @__PURE__ */ jsxs("span", { "aria-live": "polite", "aria-atomic": "true", children: [
1485
+ blockIndex + 1,
1486
+ " / ",
1487
+ blockCount,
1488
+ " ",
1489
+ labels.blocks
1490
+ ] }),
1491
+ button(labels.editBlock, openSource),
1492
+ button(
1493
+ labels.up,
1494
+ () => {
1495
+ if (editor) runBlockAction(editor, "up");
1496
+ },
1497
+ blockIndex === 0
1498
+ ),
1499
+ button(
1500
+ labels.down,
1501
+ () => {
1502
+ if (editor) runBlockAction(editor, "down");
1503
+ },
1504
+ blockIndex === blockCount - 1
1505
+ ),
1506
+ button(labels.duplicate, () => {
1507
+ if (editor) runBlockAction(editor, "duplicate");
1508
+ }),
1509
+ button(labels.remove, () => {
1510
+ if (editor) runBlockAction(editor, "remove");
1511
+ })
1512
+ ] }),
1513
+ /* @__PURE__ */ jsxs(Dialog, { open: palette, onClose: () => setPalette(false), fullWidth: true, maxWidth: "sm", children: [
1514
+ /* @__PURE__ */ jsx(DialogTitle, { children: labels.insert }),
1515
+ /* @__PURE__ */ jsx(DialogContent, { children: /* @__PURE__ */ jsx(
1516
+ Autocomplete,
1517
+ {
1518
+ value: null,
1519
+ openText: labels.insert,
1520
+ closeText: labels.cancel,
1521
+ options: recipes,
1522
+ filterOptions: filterInsertions,
1523
+ getOptionLabel: (r) => r.label,
1524
+ onChange: (_e, value) => {
1525
+ if (value) insert(value);
1526
+ },
1527
+ renderInput: (params) => /* @__PURE__ */ jsx(TextField2, { ...params, autoFocus: true, label: labels.search, margin: "dense" }),
1528
+ openOnFocus: true,
1529
+ disablePortal: true
1530
+ }
1531
+ ) }),
1532
+ /* @__PURE__ */ jsx(DialogActions, { children: /* @__PURE__ */ jsx(Button2, { onClick: () => setPalette(false), children: labels.cancel }) })
1533
+ ] }),
1534
+ dialog && /* @__PURE__ */ jsx(
1535
+ SourceDialog,
1536
+ {
1537
+ title: dialog.kind === "document" ? labels.source : dialog.kind === "link" ? labels.link : labels.editBlock,
1538
+ initial: dialog.text,
1539
+ maxLength: maxSourceLength,
1540
+ labels,
1541
+ error: invalid,
1542
+ onCancel: () => {
1543
+ setDialog(void 0);
1544
+ setInvalid("");
1545
+ },
1546
+ onApply: applyDialog
1547
+ },
1548
+ `${dialog.kind}:${dialog.pos}`
1549
+ )
1550
+ ]
1551
+ }
1552
+ );
1553
+ }
1554
+ function SourceDialog({
1555
+ title,
1556
+ initial,
1557
+ maxLength,
1558
+ labels,
1559
+ error,
1560
+ onCancel,
1561
+ onApply
1562
+ }) {
1563
+ const [text, setText] = useState(initial);
1564
+ return /* @__PURE__ */ jsxs(Dialog, { open: true, onClose: onCancel, fullWidth: true, maxWidth: "md", children: [
1565
+ /* @__PURE__ */ jsx(DialogTitle, { children: title }),
1566
+ /* @__PURE__ */ jsxs(DialogContent, { children: [
1567
+ /* @__PURE__ */ jsx(
1568
+ TextField2,
1569
+ {
1570
+ label: title,
1571
+ value: text,
1572
+ onChange: (e) => setText(e.target.value),
1573
+ multiline: true,
1574
+ minRows: 5,
1575
+ maxRows: 20,
1576
+ fullWidth: true,
1577
+ autoFocus: true,
1578
+ margin: "dense",
1579
+ slotProps: { htmlInput: { maxLength, spellCheck: false } }
1580
+ }
1581
+ ),
1582
+ error && /* @__PURE__ */ jsx("p", { role: "alert", children: error })
1583
+ ] }),
1584
+ /* @__PURE__ */ jsxs(DialogActions, { children: [
1585
+ /* @__PURE__ */ jsx(Button2, { onClick: onCancel, children: labels.cancel }),
1586
+ /* @__PURE__ */ jsx(Button2, { onClick: () => onApply(text), variant: "contained", children: labels.apply })
1587
+ ] })
1588
+ ] });
1589
+ }
1590
+
1591
+ export { MathInput, ResearchEditor, defaultMathInputLabels, defaultResearchEditorLabels };
1592
+ //# sourceMappingURL=index.js.map
1593
+ //# sourceMappingURL=index.js.map