quoin-editor 1.7.0 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (260) hide show
  1. package/CHANGELOG.md +21 -1
  2. package/MIGRATION.md +137 -23
  3. package/README.md +32 -11
  4. package/dist/ai-labels-BXX32H9a.d.cts +53 -0
  5. package/dist/ai-labels-BXX32H9a.d.ts +53 -0
  6. package/dist/ai.cjs +84 -86
  7. package/dist/ai.d.cts +4 -53
  8. package/dist/ai.d.ts +4 -53
  9. package/dist/ai.js +8 -10
  10. package/dist/ai.js.map +1 -1
  11. package/dist/catalogue.cjs +27 -26
  12. package/dist/catalogue.d.cts +10 -1
  13. package/dist/catalogue.d.ts +10 -1
  14. package/dist/catalogue.js +18 -17
  15. package/dist/catalogue.js.map +1 -1
  16. package/dist/{chunk-MNA7MBCH.js → chunk-2UKI26JA.js} +9 -11
  17. package/dist/chunk-2UKI26JA.js.map +1 -0
  18. package/dist/{chunk-MZXW2HXP.cjs → chunk-4PIJC4FD.cjs} +27 -29
  19. package/dist/{chunk-OS2O6IKX.js → chunk-5RBMZGKV.js} +4 -4
  20. package/dist/{chunk-OS2O6IKX.js.map → chunk-5RBMZGKV.js.map} +1 -1
  21. package/dist/{chunk-OJ4O6HWC.js → chunk-5X52BAZB.js} +10 -12
  22. package/dist/chunk-5X52BAZB.js.map +1 -0
  23. package/dist/{chunk-JY5VUHKN.cjs → chunk-5YAJZSTI.cjs} +28 -30
  24. package/dist/{chunk-YEFPH27F.cjs → chunk-66OPHDFA.cjs} +92 -94
  25. package/dist/{chunk-PWUFFHAQ.js → chunk-6BVE46K7.js} +8 -10
  26. package/dist/chunk-6BVE46K7.js.map +1 -0
  27. package/dist/{chunk-LKZJ2TDU.cjs → chunk-77CNOLHY.cjs} +10 -13
  28. package/dist/{chunk-4T4TJ2QS.cjs → chunk-7E43TURF.cjs} +7 -7
  29. package/dist/{chunk-BJTOLCRR.js → chunk-7Y4B7NHO.js} +2 -2
  30. package/dist/chunk-7Y4B7NHO.js.map +1 -0
  31. package/dist/{chunk-7GU25Z6L.js → chunk-B4VCDJSA.js} +9 -11
  32. package/dist/chunk-B4VCDJSA.js.map +1 -0
  33. package/dist/{chunk-QR2NIDUK.cjs → chunk-BYYCD54G.cjs} +2 -2
  34. package/dist/{chunk-6T5YGCZ5.cjs → chunk-CJVJNMOB.cjs} +302 -299
  35. package/dist/{chunk-CSKKSXCE.js → chunk-CSPCDVCT.js} +3 -3
  36. package/dist/{chunk-CSKKSXCE.js.map → chunk-CSPCDVCT.js.map} +1 -1
  37. package/dist/{chunk-BF7733XS.cjs → chunk-D6CIIWCU.cjs} +57 -59
  38. package/dist/{chunk-GHNQKJMD.js → chunk-DBOZFNWU.js} +3 -3
  39. package/dist/{chunk-GHNQKJMD.js.map → chunk-DBOZFNWU.js.map} +1 -1
  40. package/dist/{chunk-BM2GRZNM.cjs → chunk-DJU25PFC.cjs} +11 -11
  41. package/dist/chunk-DLQCTGC3.js +10 -0
  42. package/dist/chunk-DLQCTGC3.js.map +1 -0
  43. package/dist/{chunk-RQXJKJ5S.js → chunk-EU5IGKMP.js} +7 -10
  44. package/dist/chunk-EU5IGKMP.js.map +1 -0
  45. package/dist/{chunk-VZZPCYA3.cjs → chunk-FK7EBZPX.cjs} +226 -226
  46. package/dist/{chunk-BXSWZEA5.js → chunk-GPTJYWGS.js} +3 -3
  47. package/dist/{chunk-BXSWZEA5.js.map → chunk-GPTJYWGS.js.map} +1 -1
  48. package/dist/{chunk-I722LBD3.cjs → chunk-HOSDMHK6.cjs} +32 -34
  49. package/dist/{chunk-AZF7B2AE.cjs → chunk-IKZSCTRF.cjs} +11 -11
  50. package/dist/{chunk-R7MYG522.js → chunk-IW4TMECB.js} +3 -3
  51. package/dist/{chunk-R7MYG522.js.map → chunk-IW4TMECB.js.map} +1 -1
  52. package/dist/{chunk-PLUMKN4B.js → chunk-J2SVYBTC.js} +10 -12
  53. package/dist/chunk-J2SVYBTC.js.map +1 -0
  54. package/dist/{chunk-UZS3TW75.js → chunk-KQPZTSW3.js} +9 -11
  55. package/dist/chunk-KQPZTSW3.js.map +1 -0
  56. package/dist/{chunk-STKGRXSA.cjs → chunk-LEICOZYK.cjs} +15 -17
  57. package/dist/{chunk-H3C3MJW5.cjs → chunk-LM3DHROX.cjs} +2 -2
  58. package/dist/{chunk-AD3NY7NA.js → chunk-LSI4RMTY.js} +3 -3
  59. package/dist/{chunk-AD3NY7NA.js.map → chunk-LSI4RMTY.js.map} +1 -1
  60. package/dist/{chunk-QOIVLYMW.js → chunk-M77A3EGD.js} +5 -5
  61. package/dist/{chunk-QOIVLYMW.js.map → chunk-M77A3EGD.js.map} +1 -1
  62. package/dist/{chunk-5JEQZIRI.js → chunk-MAS4AEF4.js} +8 -10
  63. package/dist/chunk-MAS4AEF4.js.map +1 -0
  64. package/dist/{chunk-KDK2ATMB.cjs → chunk-NFO3W644.cjs} +51 -53
  65. package/dist/{chunk-XFEDJEJF.js → chunk-NL5J77VD.js} +204 -204
  66. package/dist/chunk-NL5J77VD.js.map +1 -0
  67. package/dist/{chunk-WN7BZDNH.cjs → chunk-PURYVDC3.cjs} +13 -13
  68. package/dist/{chunk-G25FMFEZ.js → chunk-UDBLZILE.js} +4 -4
  69. package/dist/{chunk-G25FMFEZ.js.map → chunk-UDBLZILE.js.map} +1 -1
  70. package/dist/{chunk-FNJOPGMN.cjs → chunk-V4WQG7FR.cjs} +116 -118
  71. package/dist/{chunk-IJKGF6SC.js → chunk-YABGWOAV.js} +8 -10
  72. package/dist/chunk-YABGWOAV.js.map +1 -0
  73. package/dist/{chunk-XZ4NC3Q7.cjs → chunk-YEDPBYO5.cjs} +4 -4
  74. package/dist/{chunk-QJ34MOFV.cjs → chunk-Z6LAARPB.cjs} +315 -320
  75. package/dist/{chunk-HSLOPJVT.js → chunk-ZN5DHNSL.js} +19 -16
  76. package/dist/chunk-ZN5DHNSL.js.map +1 -0
  77. package/dist/chunk-ZWTIRGY5.cjs +10 -0
  78. package/dist/comments-labels-DWqsSz8G.d.cts +30 -0
  79. package/dist/comments-labels-DWqsSz8G.d.ts +30 -0
  80. package/dist/comments.cjs +63 -65
  81. package/dist/comments.d.cts +4 -30
  82. package/dist/comments.d.ts +4 -30
  83. package/dist/comments.js +9 -11
  84. package/dist/comments.js.map +1 -1
  85. package/dist/{diagram-extension-Da7hp-tv.d.ts → diagram-extension-22x_njXB.d.ts} +4 -12
  86. package/dist/{diagram-extension-D573COJv.d.cts → diagram-extension-C_FSkoj9.d.cts} +4 -12
  87. package/dist/diagram-labels-Bi_jEZ8_.d.cts +11 -0
  88. package/dist/diagram-labels-Bi_jEZ8_.d.ts +11 -0
  89. package/dist/diagram.cjs +10 -9
  90. package/dist/diagram.d.cts +3 -2
  91. package/dist/diagram.d.ts +3 -2
  92. package/dist/diagram.js +7 -6
  93. package/dist/diff-labels-DWwg7N0n.d.cts +27 -0
  94. package/dist/diff-labels-DWwg7N0n.d.ts +27 -0
  95. package/dist/diff.cjs +27 -29
  96. package/dist/diff.d.cts +4 -27
  97. package/dist/diff.d.ts +4 -27
  98. package/dist/diff.js +5 -7
  99. package/dist/diff.js.map +1 -1
  100. package/dist/docx.cjs +30 -30
  101. package/dist/docx.js +3 -3
  102. package/dist/embed-labels-BiVa9HYl.d.cts +23 -0
  103. package/dist/embed-labels-BiVa9HYl.d.ts +23 -0
  104. package/dist/embed.cjs +10 -9
  105. package/dist/embed.d.cts +4 -23
  106. package/dist/embed.d.ts +4 -23
  107. package/dist/embed.js +8 -7
  108. package/dist/emoji-extension-C832oGeT.d.ts +16 -0
  109. package/dist/emoji-extension-Dk5IQLZf.d.cts +16 -0
  110. package/dist/{emoji-extension-gRKnbW8G.d.ts → emoji-labels-YwOms7ZJ.d.cts} +2 -15
  111. package/dist/{emoji-extension-C3o_Y5uC.d.cts → emoji-labels-YwOms7ZJ.d.ts} +2 -15
  112. package/dist/emoji.cjs +10 -9
  113. package/dist/emoji.d.cts +4 -3
  114. package/dist/emoji.d.ts +4 -3
  115. package/dist/emoji.js +7 -6
  116. package/dist/engine.cjs +58 -58
  117. package/dist/engine.d.cts +8 -7
  118. package/dist/engine.d.ts +8 -7
  119. package/dist/engine.js +3 -3
  120. package/dist/find-extension-BfruAPLi.d.cts +15 -0
  121. package/dist/find-extension-DmK9_N81.d.ts +15 -0
  122. package/dist/{find-extension-B_Ctrs6T.d.ts → find-labels-C4vs8Qe9.d.cts} +2 -14
  123. package/dist/{find-extension-BGGsJMu4.d.cts → find-labels-C4vs8Qe9.d.ts} +2 -14
  124. package/dist/find.cjs +11 -10
  125. package/dist/find.d.cts +2 -1
  126. package/dist/find.d.ts +2 -1
  127. package/dist/find.js +7 -6
  128. package/dist/headless.cjs +69 -89
  129. package/dist/headless.d.cts +21 -28
  130. package/dist/headless.d.ts +21 -28
  131. package/dist/headless.js +4 -4
  132. package/dist/highlight.cjs +7 -6
  133. package/dist/highlight.js +6 -5
  134. package/dist/highlight.js.map +1 -1
  135. package/dist/{index-CsG7OQoq.d.cts → index-3fYvwqUZ.d.cts} +1 -1
  136. package/dist/{index-h1llgZM-.d.ts → index-CgxnzCO5.d.ts} +1 -1
  137. package/dist/index.cjs +82 -101
  138. package/dist/index.d.cts +18 -185
  139. package/dist/index.d.ts +18 -185
  140. package/dist/index.js +6 -5
  141. package/dist/labels-BhRJYo46.d.ts +176 -0
  142. package/dist/labels-CiCxj2jP.d.cts +176 -0
  143. package/dist/locale-ar.cjs +565 -0
  144. package/dist/locale-ar.d.cts +63 -0
  145. package/dist/locale-ar.d.ts +63 -0
  146. package/dist/locale-ar.js +551 -0
  147. package/dist/locale-ar.js.map +1 -0
  148. package/dist/locale-de.cjs +510 -0
  149. package/dist/locale-de.d.cts +63 -0
  150. package/dist/locale-de.d.ts +63 -0
  151. package/dist/locale-de.js +496 -0
  152. package/dist/locale-de.js.map +1 -0
  153. package/dist/locale-es.cjs +510 -0
  154. package/dist/locale-es.d.cts +63 -0
  155. package/dist/locale-es.d.ts +63 -0
  156. package/dist/locale-es.js +496 -0
  157. package/dist/locale-es.js.map +1 -0
  158. package/dist/locale-fr.cjs +510 -0
  159. package/dist/locale-fr.d.cts +63 -0
  160. package/dist/locale-fr.d.ts +63 -0
  161. package/dist/locale-fr.js +496 -0
  162. package/dist/locale-fr.js.map +1 -0
  163. package/dist/locale-ja.cjs +505 -0
  164. package/dist/locale-ja.d.cts +63 -0
  165. package/dist/locale-ja.d.ts +63 -0
  166. package/dist/locale-ja.js +491 -0
  167. package/dist/locale-ja.js.map +1 -0
  168. package/dist/locale-pt.cjs +511 -0
  169. package/dist/locale-pt.d.cts +63 -0
  170. package/dist/locale-pt.d.ts +63 -0
  171. package/dist/locale-pt.js +497 -0
  172. package/dist/locale-pt.js.map +1 -0
  173. package/dist/locale-zh.cjs +505 -0
  174. package/dist/locale-zh.d.cts +63 -0
  175. package/dist/locale-zh.d.ts +63 -0
  176. package/dist/locale-zh.js +491 -0
  177. package/dist/locale-zh.js.map +1 -0
  178. package/dist/math-labels-DOf5KFxp.d.cts +24 -0
  179. package/dist/math-labels-DOf5KFxp.d.ts +24 -0
  180. package/dist/math.cjs +11 -10
  181. package/dist/math.d.cts +4 -24
  182. package/dist/math.d.ts +4 -24
  183. package/dist/math.js +9 -8
  184. package/dist/mention-labels-DIQy8LRT.d.cts +15 -0
  185. package/dist/mention-labels-DIQy8LRT.d.ts +15 -0
  186. package/dist/mention.cjs +11 -10
  187. package/dist/mention.d.cts +4 -15
  188. package/dist/mention.d.ts +4 -15
  189. package/dist/mention.js +9 -8
  190. package/dist/{view-controller-p-2x3J7Y.d.ts → node-reveal-BnFcnHhz.d.ts} +14 -14
  191. package/dist/{view-controller-BfVSNZYZ.d.cts → node-reveal-DY6bimv3.d.cts} +14 -14
  192. package/dist/palette-BrX-hEd-.d.cts +4 -0
  193. package/dist/palette-BrX-hEd-.d.ts +4 -0
  194. package/dist/presence-labels-DXVJLifl.d.cts +15 -0
  195. package/dist/presence-labels-DXVJLifl.d.ts +15 -0
  196. package/dist/presence.cjs +40 -42
  197. package/dist/presence.d.cts +4 -15
  198. package/dist/presence.d.ts +4 -15
  199. package/dist/presence.js +9 -11
  200. package/dist/presence.js.map +1 -1
  201. package/dist/source-labels-CeQDXsYZ.d.cts +9 -0
  202. package/dist/source-labels-CeQDXsYZ.d.ts +9 -0
  203. package/dist/source.cjs +11 -14
  204. package/dist/source.d.cts +5 -10
  205. package/dist/source.d.ts +5 -10
  206. package/dist/source.js +7 -10
  207. package/dist/source.js.map +1 -1
  208. package/dist/{stats-extension-oD6D1cYy.d.ts → stats-extension-D5HySF0a.d.cts} +4 -16
  209. package/dist/{stats-extension-XqOTvRaq.d.cts → stats-extension-Dmw0Ujxe.d.ts} +4 -16
  210. package/dist/stats-labels-W8gep51s.d.cts +15 -0
  211. package/dist/stats-labels-W8gep51s.d.ts +15 -0
  212. package/dist/stats.cjs +11 -10
  213. package/dist/stats.d.cts +3 -2
  214. package/dist/stats.d.ts +3 -2
  215. package/dist/stats.js +8 -7
  216. package/dist/styles.css +2 -2
  217. package/dist/table-extension-7LkLNK6Q.d.cts +15 -0
  218. package/dist/table-extension-DEpV0DnP.d.ts +15 -0
  219. package/dist/{table-extension-v6VB59bF.d.ts → table-labels-Dc-MzU3j.d.cts} +2 -14
  220. package/dist/{table-extension-BP47hHoz.d.cts → table-labels-Dc-MzU3j.d.ts} +2 -14
  221. package/dist/table.cjs +26 -25
  222. package/dist/table.d.cts +2 -1
  223. package/dist/table.d.ts +2 -1
  224. package/dist/table.js +7 -6
  225. package/dist/{to-html-1oD-CDle.d.cts → to-html-C19PbIzh.d.cts} +1 -0
  226. package/dist/{to-html-CLRBCX0I.d.ts → to-html-CogwrQer.d.ts} +1 -0
  227. package/dist/{to-markdown-CFPMbbiX.d.cts → to-markdown-C2w7Dzg8.d.cts} +1 -0
  228. package/dist/{to-markdown-BVOzhgVM.d.ts → to-markdown-DC1EUye5.d.ts} +1 -0
  229. package/dist/toc-extension-Dvh37bWQ.d.cts +15 -0
  230. package/dist/toc-extension-SVckrFmb.d.ts +15 -0
  231. package/dist/toc-labels-B2apPfXG.d.cts +14 -0
  232. package/dist/toc-labels-B2apPfXG.d.ts +14 -0
  233. package/dist/toc.cjs +10 -9
  234. package/dist/toc.d.cts +3 -2
  235. package/dist/toc.d.ts +3 -2
  236. package/dist/toc.js +7 -6
  237. package/dist/{types-DXF9p4qV.d.cts → types-Bzhq5AXj.d.cts} +1 -0
  238. package/dist/{types-BjLcmV00.d.ts → types-DMuuDBVh.d.ts} +1 -0
  239. package/dist/view.cjs +4 -4
  240. package/dist/view.js +2 -2
  241. package/dist/yjs.cjs +121 -121
  242. package/dist/yjs.d.cts +2 -2
  243. package/dist/yjs.d.ts +2 -2
  244. package/dist/yjs.js +5 -5
  245. package/package.json +71 -1
  246. package/dist/chunk-5JEQZIRI.js.map +0 -1
  247. package/dist/chunk-7GU25Z6L.js.map +0 -1
  248. package/dist/chunk-BJTOLCRR.js.map +0 -1
  249. package/dist/chunk-HSLOPJVT.js.map +0 -1
  250. package/dist/chunk-IJKGF6SC.js.map +0 -1
  251. package/dist/chunk-MNA7MBCH.js.map +0 -1
  252. package/dist/chunk-OJ4O6HWC.js.map +0 -1
  253. package/dist/chunk-PLUMKN4B.js.map +0 -1
  254. package/dist/chunk-PWUFFHAQ.js.map +0 -1
  255. package/dist/chunk-RQXJKJ5S.js.map +0 -1
  256. package/dist/chunk-UZS3TW75.js.map +0 -1
  257. package/dist/chunk-XFEDJEJF.js.map +0 -1
  258. package/dist/toc-extension-CI6jNOYl.d.cts +0 -26
  259. package/dist/toc-extension-CTHWjNJC.d.ts +0 -26
  260. /package/dist/{chunk-WZA5S5EJ.cjs → chunk-I7X7B3WD.cjs} +0 -0
@@ -1,7 +1,7 @@
1
1
  'use strict';
2
2
 
3
- var chunkVZZPCYA3_cjs = require('./chunk-VZZPCYA3.cjs');
4
- var chunkWZA5S5EJ_cjs = require('./chunk-WZA5S5EJ.cjs');
3
+ var chunkFK7EBZPX_cjs = require('./chunk-FK7EBZPX.cjs');
4
+ var chunkI7X7B3WD_cjs = require('./chunk-I7X7B3WD.cjs');
5
5
  var react = require('react');
6
6
  var reactDom = require('react-dom');
7
7
  var jsxRuntime = require('react/jsx-runtime');
@@ -25,29 +25,10 @@ function useEditorState(controller, selector, isEqual = Object.is) {
25
25
  return react.useSyncExternalStore(subscribe, getSnapshot, getSnapshot);
26
26
  }
27
27
 
28
- // src/view/selection/selection-decorations.ts
29
- var SELECTED = { class: "quoin-selected" };
30
- function isCrossSelection(selection) {
31
- if (selection?.kind !== "text") return false;
32
- const { anchor, head } = selection;
33
- return anchor.block !== head.block || anchor.region !== head.region;
34
- }
35
- function selectionDecorations(state, mode) {
36
- if (mode !== "decorations" || !isCrossSelection(state.selection)) return [];
37
- return chunkVZZPCYA3_cjs.markRanges(state).map(({ block, region, from, to }) => ({
38
- kind: "inline",
39
- block,
40
- region,
41
- from,
42
- to,
43
- attrs: SELECTED
44
- }));
45
- }
46
-
47
28
  // src/view/dom/attributes.ts
48
- var sortedEntries = (attrs) => chunkWZA5S5EJ_cjs.dataAttributes(attrs, "");
29
+ var sortedEntries = (attrs) => chunkI7X7B3WD_cjs.dataAttributes(attrs, "");
49
30
  function setAttributes(element, attrs, prefix = "") {
50
- for (const [name, value] of chunkWZA5S5EJ_cjs.writtenAttrs(chunkWZA5S5EJ_cjs.dataAttributes(attrs, prefix))) element.setAttribute(name, value);
31
+ for (const [name, value] of chunkI7X7B3WD_cjs.writtenAttrs(chunkI7X7B3WD_cjs.dataAttributes(attrs, prefix))) element.setAttribute(name, value);
51
32
  }
52
33
 
53
34
  // src/view/dom/segments.ts
@@ -62,7 +43,7 @@ function decorationRanges(decorations, length) {
62
43
  return ranges;
63
44
  }
64
45
  function toSegments(inline, decorations) {
65
- const length = chunkWZA5S5EJ_cjs.inlineLength(inline);
46
+ const length = chunkI7X7B3WD_cjs.inlineLength(inline);
66
47
  const ranges = decorationRanges(decorations, length);
67
48
  const widgets = decorations.filter((decoration) => decoration.kind === "widget").map((decoration) => ({ decoration, at: Math.min(Math.max(decoration.offset, 0), length) })).sort((a, b) => a.at - b.at || (a.decoration.side ?? 1) - (b.decoration.side ?? 1));
68
49
  const edges = [...ranges.flatMap((range) => [range.from, range.to]), ...widgets.map((widget) => widget.at)];
@@ -78,7 +59,7 @@ function toSegments(inline, decorations) {
78
59
  };
79
60
  let start = 0;
80
61
  for (const node of inline) {
81
- const end = start + chunkWZA5S5EJ_cjs.nodeLength(node);
62
+ const end = start + chunkI7X7B3WD_cjs.nodeLength(node);
82
63
  if (node.kind === "atom") {
83
64
  placeWidgets(start);
84
65
  segments.push({ kind: "atom", node, decorations: covering(start, end), from: start });
@@ -133,7 +114,7 @@ function create(doc, tag, attributes) {
133
114
  return element;
134
115
  }
135
116
  function linkElement({ href = "", title } = {}, doc) {
136
- const safe = chunkWZA5S5EJ_cjs.sanitizeHref(href);
117
+ const safe = chunkI7X7B3WD_cjs.sanitizeHref(href);
137
118
  if (safe === null) return create(doc, "span", [["data-quoin-link", ""]]);
138
119
  const anchor = create(doc, "a", [["href", safe], ["data-quoin-link", ""]]);
139
120
  if (title) anchor.title = title;
@@ -141,8 +122,8 @@ function linkElement({ href = "", title } = {}, doc) {
141
122
  }
142
123
  function markElement2(mark2, doc) {
143
124
  if (mark2.type === "link") return linkElement(mark2.attrs, doc);
144
- const { tag, attrs } = chunkWZA5S5EJ_cjs.markElement(mark2);
145
- return create(doc, tag, chunkWZA5S5EJ_cjs.writtenAttrs(attrs));
125
+ const { tag, attrs } = chunkI7X7B3WD_cjs.markElement(mark2);
126
+ return create(doc, tag, chunkI7X7B3WD_cjs.writtenAttrs(attrs));
146
127
  }
147
128
 
148
129
  // src/view/dom/wrappers.ts
@@ -339,8 +320,8 @@ function reconcileChildren(parent, specs) {
339
320
  // src/view/dom/text-diff.ts
340
321
  function textDiff(before, after, caretHint) {
341
322
  if (before === after) return null;
342
- const prefix = chunkVZZPCYA3_cjs.commonPrefix(before, after);
343
- const suffix = chunkVZZPCYA3_cjs.commonSuffix(before, after);
323
+ const prefix = chunkFK7EBZPX_cjs.commonPrefix(before, after);
324
+ const suffix = chunkFK7EBZPX_cjs.commonSuffix(before, after);
344
325
  const shared = Math.min(suffix, Math.min(before.length, after.length) - prefix);
345
326
  const removed = before.length - prefix - shared;
346
327
  const inserted = after.length - prefix - shared;
@@ -445,12 +426,12 @@ function specsFor(segment, options, doc) {
445
426
  }
446
427
  }
447
428
  function needsFiller(inline) {
448
- const content = chunkWZA5S5EJ_cjs.inlineText(inline);
429
+ const content = chunkI7X7B3WD_cjs.inlineText(inline);
449
430
  return content === "" || content.endsWith("\n");
450
431
  }
451
432
  function renderInline(host, inline, decorations, options = {}) {
452
433
  const doc = host.ownerDocument;
453
- const length = chunkWZA5S5EJ_cjs.inlineLength(inline);
434
+ const length = chunkI7X7B3WD_cjs.inlineLength(inline);
454
435
  const specs = toSegments(inline, decorations).flatMap((segment) => specsFor(segment, options, doc));
455
436
  if (needsFiller(inline)) specs.push(fillerSpec(doc, length));
456
437
  reconcileChildren(host, specs);
@@ -528,10 +509,10 @@ function readSelection(registry, domSelection, blockAt2 = () => void 0) {
528
509
  if (!domSelection || !anchorNode || !focusNode) return null;
529
510
  const anchor = domToPos(registry, anchorNode, domSelection.anchorOffset);
530
511
  const head = domToPos(registry, focusNode, domSelection.focusOffset);
531
- if (anchor && head) return chunkVZZPCYA3_cjs.textSelection(anchor, head);
512
+ if (anchor && head) return chunkFK7EBZPX_cjs.textSelection(anchor, head);
532
513
  if (anchor || head || registry.locate(anchorNode) || registry.locate(focusNode)) return null;
533
514
  const block = blockAt2(anchorNode);
534
- return block !== void 0 && block === blockAt2(focusNode) ? chunkVZZPCYA3_cjs.nodeSelection(block) : null;
515
+ return block !== void 0 && block === blockAt2(focusNode) ? chunkFK7EBZPX_cjs.nodeSelection(block) : null;
535
516
  }
536
517
  function selectBlock(domSelection, element) {
537
518
  if (!element) return false;
@@ -544,8 +525,8 @@ function selectBlock(domSelection, element) {
544
525
  }
545
526
  var drawnUpstream = /* @__PURE__ */ new WeakMap();
546
527
  function drawUpstream(registry, pos, domSelection, drawn) {
547
- const caret = chunkVZZPCYA3_cjs.textSelection(pos);
548
- const isAt = () => chunkVZZPCYA3_cjs.sameSelection(readSelection(registry, domSelection), caret);
528
+ const caret = chunkFK7EBZPX_cjs.textSelection(pos);
529
+ const isAt = () => chunkFK7EBZPX_cjs.sameSelection(readSelection(registry, domSelection), caret);
549
530
  if (drawn?.node === domSelection.focusNode && drawn.offset === domSelection.focusOffset && isAt()) {
550
531
  drawnUpstream.set(domSelection, drawn);
551
532
  return true;
@@ -565,7 +546,7 @@ function writeSelection(registry, selection, domSelection, blockElement) {
565
546
  if (anchor.block !== head.block || anchor.region !== head.region) return false;
566
547
  const drawn = drawnUpstream.get(domSelection);
567
548
  drawnUpstream.delete(domSelection);
568
- if (chunkVZZPCYA3_cjs.sameSelection(readSelection(registry, domSelection), selection)) return true;
549
+ if (chunkFK7EBZPX_cjs.sameSelection(readSelection(registry, domSelection), selection)) return true;
569
550
  if (selection.assoc === -1 && anchor.offset === head.offset && drawUpstream(registry, head, domSelection, drawn)) {
570
551
  return true;
571
552
  }
@@ -618,20 +599,20 @@ function wrapsAt(pos, y, glyphAt2) {
618
599
  return after !== null && !onLine(after, y) && onLine(before, y) ? before : null;
619
600
  }
620
601
  function stayOnLine(pos, y, glyphAt2) {
621
- const caret = chunkVZZPCYA3_cjs.textSelection(pos);
602
+ const caret = chunkFK7EBZPX_cjs.textSelection(pos);
622
603
  const before = wrapsAt(pos, y, glyphAt2);
623
604
  if (before === null) return caret;
624
- return /\S/.test(before.text) ? { ...caret, assoc: -1 } : chunkVZZPCYA3_cjs.textSelection({ ...pos, offset: pos.offset - 1 });
605
+ return /\S/.test(before.text) ? { ...caret, assoc: -1 } : chunkFK7EBZPX_cjs.textSelection({ ...pos, offset: pos.offset - 1 });
625
606
  }
626
607
 
627
608
  // src/view/navigation/clicked-side.ts
628
609
  function keepClickedSide(controller, y) {
629
610
  controller.readSelectionFromDom();
630
611
  const { selection } = controller.editor.state;
631
- if (selection?.kind !== "text" || !chunkVZZPCYA3_cjs.isCollapsed(selection)) return;
612
+ if (selection?.kind !== "text" || !chunkFK7EBZPX_cjs.isCollapsed(selection)) return;
632
613
  const upstream = wrapsAt(selection.head, y, glyphsAround(controller.registry, selection.head)) !== null;
633
614
  if (upstream !== (selection.assoc === -1)) {
634
- const caret = chunkVZZPCYA3_cjs.textSelection(selection.head);
615
+ const caret = chunkFK7EBZPX_cjs.textSelection(selection.head);
635
616
  dispatchSelection(controller, upstream ? { ...caret, assoc: -1 } : caret);
636
617
  }
637
618
  }
@@ -681,8 +662,8 @@ var known = /* @__PURE__ */ new WeakMap();
681
662
  function hidersOf(doc) {
682
663
  let hiders = known.get(doc);
683
664
  if (hiders === void 0) {
684
- const first = doc.blocks.findIndex(chunkVZZPCYA3_cjs.isClosedToggle);
685
- hiders = doc.blocks.map((_, index) => first < 0 || index <= first ? null : chunkVZZPCYA3_cjs.hidingToggle(doc, index + 1));
665
+ const first = doc.blocks.findIndex(chunkFK7EBZPX_cjs.isClosedToggle);
666
+ hiders = doc.blocks.map((_, index) => first < 0 || index <= first ? null : chunkFK7EBZPX_cjs.hidingToggle(doc, index + 1));
686
667
  known.set(doc, hiders);
687
668
  }
688
669
  return hiders;
@@ -691,7 +672,7 @@ var hidingToggleAt = (doc, index) => hidersOf(doc)[index] ?? null;
691
672
  function isHiddenAt(doc, index, choices) {
692
673
  if (choices.size === 0) return hidingToggleAt(doc, index) !== null;
693
674
  const closed = (block) => block.type === "TOGGLE" && !shownOpen(block, choices);
694
- return chunkVZZPCYA3_cjs.hidingToggle(doc, index + 1, closed) !== null;
675
+ return chunkFK7EBZPX_cjs.hidingToggle(doc, index + 1, closed) !== null;
695
676
  }
696
677
  var visibleBlockIndexes = (doc) => hidersOf(doc).flatMap((hider, index) => hider === null ? [index] : []);
697
678
  function drawnBlockCount(doc, start = 0, end = doc.blocks.length) {
@@ -713,18 +694,18 @@ function neighbourBlock(doc, from, direction, accept = anyBlock) {
713
694
  }
714
695
  function entryEdge(controller, block, direction) {
715
696
  const { doc, schema } = controller.editor.state;
716
- const edge = direction < 0 ? chunkVZZPCYA3_cjs.endOf(doc, schema, block) : chunkVZZPCYA3_cjs.startOf(doc, schema, block);
697
+ const edge = direction < 0 ? chunkFK7EBZPX_cjs.endOf(doc, schema, block) : chunkFK7EBZPX_cjs.startOf(doc, schema, block);
717
698
  if (edge.kind !== "text") return edge;
718
699
  const drawn = controller.registry.get(edge.head.block, edge.head.region) !== void 0;
719
- return drawn && !entersAsNode(controller, block) ? edge : chunkVZZPCYA3_cjs.nodeSelection(block);
700
+ return drawn && !entersAsNode(controller, block) ? edge : chunkFK7EBZPX_cjs.nodeSelection(block);
720
701
  }
721
- var ownNode = (controller, block, direction) => direction < 0 && entersAsNode(controller, block) ? chunkVZZPCYA3_cjs.nodeSelection(block) : null;
702
+ var ownNode = (controller, block, direction) => direction < 0 && entersAsNode(controller, block) ? chunkFK7EBZPX_cjs.nodeSelection(block) : null;
722
703
  var canBeEntered = (controller) => (block) => {
723
704
  const { schema } = controller.editor.state;
724
- const region = chunkVZZPCYA3_cjs.isTextFlow(schema, block) ? chunkVZZPCYA3_cjs.primaryRegion(schema, block) : null;
705
+ const region = chunkFK7EBZPX_cjs.isTextFlow(schema, block) ? chunkFK7EBZPX_cjs.primaryRegion(schema, block) : null;
725
706
  return region === null || controller.registry.get(block.id, region) !== void 0 || entersAsNode(controller, block.id);
726
707
  };
727
- var holdsTextHead = (controller) => (block) => chunkVZZPCYA3_cjs.isTextFlow(controller.editor.state.schema, block) && entryEdge(controller, block.id, 1).kind === "text";
708
+ var holdsTextHead = (controller) => (block) => chunkFK7EBZPX_cjs.isTextFlow(controller.editor.state.schema, block) && entryEdge(controller, block.id, 1).kind === "text";
728
709
  function neighbourHead(controller, from, direction) {
729
710
  const target = neighbourBlock(controller.editor.state.doc, from, direction, holdsTextHead(controller));
730
711
  const edge = target && entryEdge(controller, target.id, direction);
@@ -839,6 +820,25 @@ function caretPosAt(controller, host, x, y) {
839
820
  // src/view/selection/native-interaction.ts
840
821
  var NATIVE_INTERACTION = "data-quoin-native";
841
822
 
823
+ // src/view/selection/selection-decorations.ts
824
+ var SELECTED = { class: "quoin-selected" };
825
+ function isCrossSelection(selection) {
826
+ if (selection?.kind !== "text") return false;
827
+ const { anchor, head } = selection;
828
+ return anchor.block !== head.block || anchor.region !== head.region;
829
+ }
830
+ function selectionDecorations(state, mode) {
831
+ if (mode !== "decorations" || !isCrossSelection(state.selection)) return [];
832
+ return chunkFK7EBZPX_cjs.markRanges(state).map(({ block, region, from, to }) => ({
833
+ kind: "inline",
834
+ block,
835
+ region,
836
+ from,
837
+ to,
838
+ attrs: SELECTED
839
+ }));
840
+ }
841
+
842
842
  // src/view/selection/cross-block-pointer.ts
843
843
  var DRAGGING = "data-quoin-dragging";
844
844
  var DRAG_DISTANCE = 4;
@@ -863,7 +863,7 @@ function createCrossBlockPointer(controller) {
863
863
  let preventMouseDown = false;
864
864
  const scroll = createAutoScroll(root, () => follow(last.x, last.y));
865
865
  function select(selection) {
866
- if (chunkVZZPCYA3_cjs.sameSelection(selection, controller.editor.state.selection)) return;
866
+ if (chunkFK7EBZPX_cjs.sameSelection(selection, controller.editor.state.selection)) return;
867
867
  dispatchSelection(controller, selection);
868
868
  }
869
869
  function startDragging() {
@@ -879,14 +879,14 @@ function createCrossBlockPointer(controller) {
879
879
  if (current.anchor === null) return;
880
880
  startDragging();
881
881
  }
882
- select(chunkVZZPCYA3_cjs.textSelection(current.anchor, caretPosAt(controller, target, x, y)));
882
+ select(chunkFK7EBZPX_cjs.textSelection(current.anchor, caretPosAt(controller, target, x, y)));
883
883
  }
884
884
  function followBlocks(current, x, y) {
885
885
  if (!controller.dragging && Math.hypot(x - current.x, y - current.y) < DRAG_DISTANCE) return;
886
886
  const block = blockAt(controller, x, y);
887
887
  if (block === null) return;
888
888
  startDragging();
889
- select(chunkVZZPCYA3_cjs.blockRangeSelection(current.start, block));
889
+ select(chunkFK7EBZPX_cjs.blockRangeSelection(current.start, block));
890
890
  }
891
891
  function follow(x, y) {
892
892
  if (press?.kind === "text") followText(press, x, y);
@@ -926,10 +926,10 @@ function createCrossBlockPointer(controller) {
926
926
  }
927
927
  function pressWhole(block) {
928
928
  if (entryEdge(controller, block, 1).kind !== "node") return;
929
- const pressed = chunkWZA5S5EJ_cjs.blockById(controller.editor.state.doc, block);
930
- if (pressed !== void 0 && !canBeEntered(controller)(pressed)) return select(chunkVZZPCYA3_cjs.blockRangeSelection(block));
929
+ const pressed = chunkI7X7B3WD_cjs.blockById(controller.editor.state.doc, block);
930
+ if (pressed !== void 0 && !canBeEntered(controller)(pressed)) return select(chunkFK7EBZPX_cjs.blockRangeSelection(block));
931
931
  controller.nodeReveal.pressed(block);
932
- select(chunkVZZPCYA3_cjs.nodeSelection(block));
932
+ select(chunkFK7EBZPX_cjs.nodeSelection(block));
933
933
  }
934
934
  function onPointerDown(event) {
935
935
  end();
@@ -975,7 +975,7 @@ function createCrossBlockPointer(controller) {
975
975
  // src/view/selection/paint-selection.ts
976
976
  var NAME = "quoin-selection";
977
977
  function coveredRanges(controller) {
978
- return chunkVZZPCYA3_cjs.markRanges(controller.editor.state).flatMap(({ block, region, from, to }) => {
978
+ return chunkFK7EBZPX_cjs.markRanges(controller.editor.state).flatMap(({ block, region, from, to }) => {
979
979
  const host = controller.registry.get(block, region);
980
980
  const map = host && domMapOf(host);
981
981
  if (!host || !map) return [];
@@ -1035,7 +1035,7 @@ function inPlace(element, change) {
1035
1035
  change();
1036
1036
  for (const { at, left, top } of before) {
1037
1037
  const now = scrollOf(at);
1038
- if (now.left !== left || now.top !== top) at.scrollTo({ left, top, behavior: "instant" });
1038
+ if (now.left !== left || now.top !== top) at.scrollTo?.({ left, top, behavior: "instant" });
1039
1039
  }
1040
1040
  }
1041
1041
 
@@ -1046,7 +1046,7 @@ function heldBySink(selection) {
1046
1046
  }
1047
1047
  var NO_TEXT = "\xA0";
1048
1048
  function selectionText(state) {
1049
- const text = chunkVZZPCYA3_cjs.markRanges(state).map((range) => chunkWZA5S5EJ_cjs.inlinePlainText(chunkVZZPCYA3_cjs.rangeContent(state, range), state.schema)).join("\n");
1049
+ const text = chunkFK7EBZPX_cjs.markRanges(state).map((range) => chunkI7X7B3WD_cjs.inlinePlainText(chunkFK7EBZPX_cjs.rangeContent(state, range), state.schema)).join("\n");
1050
1050
  return text === "" ? NO_TEXT : text;
1051
1051
  }
1052
1052
  var focusInPlace = (sink) => inPlace(sink, () => sink.focus({ preventScroll: true }));
@@ -1069,7 +1069,7 @@ function focusSink(controller) {
1069
1069
  sink.ownerDocument.getSelection()?.selectAllChildren(sink);
1070
1070
  }
1071
1071
  function selectedBlockName({ doc, schema, selection }, blockLabel) {
1072
- const block = selection?.kind === "node" ? chunkWZA5S5EJ_cjs.blockById(doc, selection.block) : void 0;
1072
+ const block = selection?.kind === "node" ? chunkI7X7B3WD_cjs.blockById(doc, selection.block) : void 0;
1073
1073
  return block === void 0 ? null : blockLabel?.(block, schema) ?? "";
1074
1074
  }
1075
1075
  function clearSink(controller) {
@@ -1156,7 +1156,7 @@ function createNodeReveal(element) {
1156
1156
  show(selection, local) {
1157
1157
  const block = nodeOf(selection);
1158
1158
  if (block !== null && block !== pressed && (block !== shown || local && block === owed)) {
1159
- element(block)?.scrollIntoView({ block: "nearest" });
1159
+ element(block)?.scrollIntoView?.({ block: "nearest" });
1160
1160
  }
1161
1161
  if (local) owed = null;
1162
1162
  shown = block;
@@ -1206,7 +1206,7 @@ function createElementSlot(changed) {
1206
1206
 
1207
1207
  // src/view/controller/selection-element.ts
1208
1208
  function elementFor({ doc }, selection, rendered) {
1209
- const id = chunkVZZPCYA3_cjs.headBlockId(selection);
1209
+ const id = chunkFK7EBZPX_cjs.headBlockId(selection);
1210
1210
  const index = id === null ? void 0 : doc.index.get(id);
1211
1211
  if (id === null || index === void 0) return void 0;
1212
1212
  const hiding = hidingToggleAt(doc, index);
@@ -1219,7 +1219,7 @@ function selectionElement(state, rendered) {
1219
1219
  if (doc.blocks.length === 0) return rendered.empty?.() ?? void 0;
1220
1220
  const sink = heldBySink(selection) ? rendered.sink?.() : null;
1221
1221
  if (sink) return sink;
1222
- return elementFor(state, selection, rendered) ?? elementFor(state, chunkVZZPCYA3_cjs.startOf(doc, schema, doc.blocks[0].id), rendered);
1222
+ return elementFor(state, selection, rendered) ?? elementFor(state, chunkFK7EBZPX_cjs.startOf(doc, schema, doc.blocks[0].id), rendered);
1223
1223
  }
1224
1224
 
1225
1225
  // src/view/controller/tab-stop.ts
@@ -1273,7 +1273,7 @@ function createDrawnElements(hosts, state) {
1273
1273
  }
1274
1274
 
1275
1275
  // src/view/controller/engagement.ts
1276
- var chosenHere = (tr) => tr !== null && tr.selectionSet && !chunkVZZPCYA3_cjs.foreignOrigins.includes(tr.origin);
1276
+ var chosenHere = (tr) => tr !== null && tr.selectionSet && !chunkFK7EBZPX_cjs.foreignOrigins.includes(tr.origin);
1277
1277
  function createEngagement(editor) {
1278
1278
  let engaged = false;
1279
1279
  const listeners = /* @__PURE__ */ new Set();
@@ -1311,9 +1311,9 @@ function ownsFocus(controller, doc) {
1311
1311
  function focusTarget(state, target) {
1312
1312
  const { doc, schema, selection } = state;
1313
1313
  if (doc.blocks.length === 0) return null;
1314
- if (target === "end") return chunkVZZPCYA3_cjs.endOf(doc, schema, doc.blocks[doc.blocks.length - 1].id);
1315
- if (target === "start" || target === void 0 && selection === null) return chunkVZZPCYA3_cjs.startOf(doc, schema, doc.blocks[0].id);
1316
- return target === void 0 ? selection : chunkVZZPCYA3_cjs.textSelection(target);
1314
+ if (target === "end") return chunkFK7EBZPX_cjs.endOf(doc, schema, doc.blocks[doc.blocks.length - 1].id);
1315
+ if (target === "start" || target === void 0 && selection === null) return chunkFK7EBZPX_cjs.startOf(doc, schema, doc.blocks[0].id);
1316
+ return target === void 0 ? selection : chunkFK7EBZPX_cjs.textSelection(target);
1317
1317
  }
1318
1318
 
1319
1319
  // src/view/controller/host-decorations.ts
@@ -1329,7 +1329,7 @@ function decorationsByHost(decorations) {
1329
1329
  return byHost;
1330
1330
  }
1331
1331
  function sameDecoration(a, b) {
1332
- if (a.kind !== b.kind || a.block !== b.block || !chunkWZA5S5EJ_cjs.sameAttrs(a.attrs, b.attrs)) return false;
1332
+ if (a.kind !== b.kind || a.block !== b.block || !chunkI7X7B3WD_cjs.sameAttrs(a.attrs, b.attrs)) return false;
1333
1333
  if (a.kind === "inline" && b.kind === "inline") {
1334
1334
  return a.region === b.region && a.from === b.from && a.to === b.to;
1335
1335
  }
@@ -1340,7 +1340,7 @@ function sameDecoration(a, b) {
1340
1340
  return true;
1341
1341
  }
1342
1342
  function sameDecorations(a, b) {
1343
- return a === b || chunkWZA5S5EJ_cjs.sameItems(a, b, sameDecoration);
1343
+ return a === b || chunkI7X7B3WD_cjs.sameItems(a, b, sameDecoration);
1344
1344
  }
1345
1345
  var byMode = { highlight: /* @__PURE__ */ new WeakMap(), decorations: /* @__PURE__ */ new WeakMap() };
1346
1346
  function hostDecorations(editor, block, region, mode = "highlight") {
@@ -1356,7 +1356,7 @@ function hostDecorations(editor, block, region, mode = "highlight") {
1356
1356
 
1357
1357
  // src/view/controller/region-inline.ts
1358
1358
  function regionInline(state, block, region) {
1359
- const regions = chunkWZA5S5EJ_cjs.blockById(state.doc, block)?.regions;
1359
+ const regions = chunkI7X7B3WD_cjs.blockById(state.doc, block)?.regions;
1360
1360
  return regions && Object.hasOwn(regions, region) ? regions[region] : void 0;
1361
1361
  }
1362
1362
 
@@ -1406,7 +1406,7 @@ function createOutsideChanges(editorHasFocus, movedFrom) {
1406
1406
  }
1407
1407
  const from = moved ?? (outside && !settled ? movedFrom(tr.before.selection) : null);
1408
1408
  settled ||= outside;
1409
- moved = from && chunkVZZPCYA3_cjs.mapSelection(from, (pos, assoc) => tr.mapPos(pos, assoc), tr.before.doc);
1409
+ moved = from && chunkFK7EBZPX_cjs.mapSelection(from, (pos, assoc) => tr.mapPos(pos, assoc), tr.before.doc);
1410
1410
  },
1411
1411
  takeFocused() {
1412
1412
  const value = focused;
@@ -1499,7 +1499,7 @@ function handleCopy(controller, event, cut) {
1499
1499
  clipboardData.setData("text/plain", copied.text);
1500
1500
  clipboardData.setData("text/html", wrapSliceHTML(copied.html, copied.json));
1501
1501
  clipboardData.setData(QUOIN_SLICE_TYPE, copied.json);
1502
- if (cut) controller.run(chunkVZZPCYA3_cjs.deleteSelection);
1502
+ if (cut) controller.run(chunkFK7EBZPX_cjs.deleteSelection);
1503
1503
  }
1504
1504
  function handlePaste(controller, event) {
1505
1505
  if (!event.clipboardData) return;
@@ -1531,7 +1531,7 @@ function handleDrop(controller, event) {
1531
1531
  return;
1532
1532
  }
1533
1533
  const pos = dropPos(controller, event.clientX, event.clientY);
1534
- if (pos) controller.dispatch(controller.editor.createTransaction().setSelection(chunkVZZPCYA3_cjs.textSelection(pos)).setOrigin("drop"));
1534
+ if (pos) controller.dispatch(controller.editor.createTransaction().setSelection(chunkFK7EBZPX_cjs.textSelection(pos)).setOrigin("drop"));
1535
1535
  pasteTransfer(controller, dataTransfer);
1536
1536
  }
1537
1537
  function handleDragOver(event) {
@@ -1661,29 +1661,29 @@ function createSinkComposition(controller, settled = () => {
1661
1661
  var LINE_BREAK = "\n";
1662
1662
  var transposeChars = (state, dispatch) => {
1663
1663
  const { selection } = state;
1664
- if (selection?.kind !== "text" || !chunkVZZPCYA3_cjs.isCollapsed(selection)) return false;
1664
+ if (selection?.kind !== "text" || !chunkFK7EBZPX_cjs.isCollapsed(selection)) return false;
1665
1665
  const { head } = selection;
1666
- const inline = chunkWZA5S5EJ_cjs.blockById(state.doc, head.block)?.regions[head.region];
1666
+ const inline = chunkI7X7B3WD_cjs.blockById(state.doc, head.block)?.regions[head.region];
1667
1667
  if (inline === void 0) return false;
1668
- const value = chunkWZA5S5EJ_cjs.inlineText(inline);
1668
+ const value = chunkI7X7B3WD_cjs.inlineText(inline);
1669
1669
  const atLineEnd = head.offset === value.length || value[head.offset] === LINE_BREAK;
1670
- const end = atLineEnd ? head.offset : chunkVZZPCYA3_cjs.nextGraphemeOffset(value, head.offset);
1671
- const middle = chunkVZZPCYA3_cjs.prevGraphemeOffset(value, end);
1672
- const start = chunkVZZPCYA3_cjs.prevGraphemeOffset(value, middle);
1670
+ const end = atLineEnd ? head.offset : chunkFK7EBZPX_cjs.nextGraphemeOffset(value, head.offset);
1671
+ const middle = chunkFK7EBZPX_cjs.prevGraphemeOffset(value, end);
1672
+ const start = chunkFK7EBZPX_cjs.prevGraphemeOffset(value, middle);
1673
1673
  if (start === middle || value.slice(start, end).includes(LINE_BREAK)) return false;
1674
- const swapped = [...chunkWZA5S5EJ_cjs.sliceInline(inline, middle, end), ...chunkWZA5S5EJ_cjs.sliceInline(inline, start, middle)];
1675
- const tr = new chunkVZZPCYA3_cjs.Transaction(state).setOrigin("input");
1676
- tr.step(chunkVZZPCYA3_cjs.replaceInlineStep(head.block, head.region, start, end, swapped));
1677
- dispatch?.(tr.setSelection(chunkVZZPCYA3_cjs.textSelection({ ...head, offset: end })));
1674
+ const swapped = [...chunkI7X7B3WD_cjs.sliceInline(inline, middle, end), ...chunkI7X7B3WD_cjs.sliceInline(inline, start, middle)];
1675
+ const tr = new chunkFK7EBZPX_cjs.Transaction(state).setOrigin("input");
1676
+ tr.step(chunkFK7EBZPX_cjs.replaceInlineStep(head.block, head.region, start, end, swapped));
1677
+ dispatch?.(tr.setSelection(chunkFK7EBZPX_cjs.textSelection({ ...head, offset: end })));
1678
1678
  return true;
1679
1679
  };
1680
1680
 
1681
1681
  // src/view/input/replace-range.ts
1682
1682
  function replaceRange(editor, range, text, withRules) {
1683
1683
  const dispatch = (tr) => editor.dispatch(tr);
1684
- dispatch(editor.createTransaction().setSelection(chunkVZZPCYA3_cjs.textSelection(range.from, range.to)).setOrigin("input"));
1685
- if (text === "") return chunkVZZPCYA3_cjs.deleteSelection(editor.state, (tr) => dispatch(tr.setOrigin("input")));
1686
- return withRules ? editor.insertText(text) : chunkVZZPCYA3_cjs.insertText(text, { origin: "input" })(editor.state, dispatch);
1684
+ dispatch(editor.createTransaction().setSelection(chunkFK7EBZPX_cjs.textSelection(range.from, range.to)).setOrigin("input"));
1685
+ if (text === "") return chunkFK7EBZPX_cjs.deleteSelection(editor.state, (tr) => dispatch(tr.setOrigin("input")));
1686
+ return withRules ? editor.insertText(text) : chunkFK7EBZPX_cjs.insertText(text, { origin: "input" })(editor.state, dispatch);
1687
1687
  }
1688
1688
 
1689
1689
  // src/view/input/target-range.ts
@@ -1694,13 +1694,13 @@ function targetRangeToModel(controller, event) {
1694
1694
  const to = domToPos(controller.registry, range.endContainer, range.endOffset);
1695
1695
  return from && to && { from, to };
1696
1696
  }
1697
- var isEmpty = ({ from, to }) => chunkVZZPCYA3_cjs.sameSelection(chunkVZZPCYA3_cjs.textSelection(from), chunkVZZPCYA3_cjs.textSelection(to));
1697
+ var isEmpty = ({ from, to }) => chunkFK7EBZPX_cjs.sameSelection(chunkFK7EBZPX_cjs.textSelection(from), chunkFK7EBZPX_cjs.textSelection(to));
1698
1698
  function targetBeyondSelection(controller, event) {
1699
1699
  const range = targetRangeToModel(controller, event);
1700
1700
  if (range === null || isEmpty(range)) return null;
1701
1701
  const { doc, selection } = controller.editor.state;
1702
- const selected = chunkVZZPCYA3_cjs.selectionRange(doc, selection);
1703
- const same = selected !== null && chunkVZZPCYA3_cjs.sameSelection(chunkVZZPCYA3_cjs.textSelection(selected.from, selected.to), chunkVZZPCYA3_cjs.textSelection(range.from, range.to));
1702
+ const selected = chunkFK7EBZPX_cjs.selectionRange(doc, selection);
1703
+ const same = selected !== null && chunkFK7EBZPX_cjs.sameSelection(chunkFK7EBZPX_cjs.textSelection(selected.from, selected.to), chunkFK7EBZPX_cjs.textSelection(range.from, range.to));
1704
1704
  return same ? null : range;
1705
1705
  }
1706
1706
 
@@ -1722,34 +1722,34 @@ function insertTypedText(controller, event) {
1722
1722
  else controller.edit(() => replaceRange(controller.editor, range, text, false));
1723
1723
  }
1724
1724
  function deleteContentBackward(controller, event) {
1725
- if (!controller.run(chunkVZZPCYA3_cjs.undoInputRule)) targetOr(chunkVZZPCYA3_cjs.deleteBackward)(controller, event);
1725
+ if (!controller.run(chunkFK7EBZPX_cjs.undoInputRule)) targetOr(chunkFK7EBZPX_cjs.deleteBackward)(controller, event);
1726
1726
  }
1727
1727
  function insertReplacementText(controller, event) {
1728
1728
  const text = event.dataTransfer?.getData("text/plain") || event.data;
1729
1729
  if (!text) return;
1730
1730
  const range = targetRangeToModel(controller, event);
1731
- if (range === null) controller.run(chunkVZZPCYA3_cjs.insertText(text, { origin: "input" }));
1731
+ if (range === null) controller.run(chunkFK7EBZPX_cjs.insertText(text, { origin: "input" }));
1732
1732
  else controller.edit(() => replaceRange(controller.editor, range, text, false));
1733
1733
  }
1734
1734
  var actions = {
1735
1735
  insertText: insertTypedText,
1736
1736
  insertReplacementText,
1737
1737
  insertParagraph: (controller) => void controller.edit(() => controller.editor.handleKey(ENTER)),
1738
- insertLineBreak: run(chunkVZZPCYA3_cjs.insertHardBreak),
1738
+ insertLineBreak: run(chunkFK7EBZPX_cjs.insertHardBreak),
1739
1739
  deleteContentBackward,
1740
- deleteContentForward: targetOr(chunkVZZPCYA3_cjs.deleteForward),
1741
- deleteWordBackward: targetOr(chunkVZZPCYA3_cjs.deleteWordBackward),
1742
- deleteWordForward: targetOr(chunkVZZPCYA3_cjs.deleteWordForward),
1743
- deleteSoftLineBackward: targetOr(chunkVZZPCYA3_cjs.deleteToLineStart),
1744
- deleteHardLineBackward: targetOr(chunkVZZPCYA3_cjs.deleteToLineStart),
1745
- deleteSoftLineForward: targetOr(chunkVZZPCYA3_cjs.deleteToLineEnd),
1746
- deleteHardLineForward: targetOr(chunkVZZPCYA3_cjs.deleteToLineEnd),
1747
- formatBold: run(chunkVZZPCYA3_cjs.toggleMark("bold")),
1748
- formatItalic: run(chunkVZZPCYA3_cjs.toggleMark("italic")),
1749
- formatUnderline: run(chunkVZZPCYA3_cjs.toggleMark("underline")),
1750
- formatStrikeThrough: run(chunkVZZPCYA3_cjs.toggleMark("strike")),
1751
- historyUndo: run(chunkVZZPCYA3_cjs.undo),
1752
- historyRedo: run(chunkVZZPCYA3_cjs.redo),
1740
+ deleteContentForward: targetOr(chunkFK7EBZPX_cjs.deleteForward),
1741
+ deleteWordBackward: targetOr(chunkFK7EBZPX_cjs.deleteWordBackward),
1742
+ deleteWordForward: targetOr(chunkFK7EBZPX_cjs.deleteWordForward),
1743
+ deleteSoftLineBackward: targetOr(chunkFK7EBZPX_cjs.deleteToLineStart),
1744
+ deleteHardLineBackward: targetOr(chunkFK7EBZPX_cjs.deleteToLineStart),
1745
+ deleteSoftLineForward: targetOr(chunkFK7EBZPX_cjs.deleteToLineEnd),
1746
+ deleteHardLineForward: targetOr(chunkFK7EBZPX_cjs.deleteToLineEnd),
1747
+ formatBold: run(chunkFK7EBZPX_cjs.toggleMark("bold")),
1748
+ formatItalic: run(chunkFK7EBZPX_cjs.toggleMark("italic")),
1749
+ formatUnderline: run(chunkFK7EBZPX_cjs.toggleMark("underline")),
1750
+ formatStrikeThrough: run(chunkFK7EBZPX_cjs.toggleMark("strike")),
1751
+ historyUndo: run(chunkFK7EBZPX_cjs.undo),
1752
+ historyRedo: run(chunkFK7EBZPX_cjs.redo),
1753
1753
  insertTranspose: run(transposeChars),
1754
1754
  insertFromPaste: leaveToHandlers,
1755
1755
  insertFromDrop: leaveToHandlers,
@@ -1850,7 +1850,7 @@ function snapshotComposition(controller, block, region) {
1850
1850
  const element = controller.registry.get(block, region);
1851
1851
  const inline = regionInline(editor.state, block, region);
1852
1852
  if (element === void 0 || inline === void 0) return null;
1853
- const text = chunkWZA5S5EJ_cjs.inlineText(inline);
1853
+ const text = chunkI7X7B3WD_cjs.inlineText(inline);
1854
1854
  const end = composedEnd(controller, block, region);
1855
1855
  const since = [];
1856
1856
  const release = editor.subscribe((_, tr) => void (tr && since.push(tr)));
@@ -1964,7 +1964,7 @@ function reconcileHost(controller, block, region, caretHint) {
1964
1964
  const element = controller.registry.get(block, region);
1965
1965
  const inline = regionInline(controller.editor.state, block, region);
1966
1966
  if (element === void 0 || inline === void 0) return false;
1967
- const before = chunkWZA5S5EJ_cjs.inlineText(inline);
1967
+ const before = chunkI7X7B3WD_cjs.inlineText(inline);
1968
1968
  const after = readDomText(element);
1969
1969
  const edit = before === after ? null : textDiff(before, after, domCaretOffset(element));
1970
1970
  if (edit === null) return false;
@@ -2030,33 +2030,33 @@ function createDomInputFallback(controller) {
2030
2030
 
2031
2031
  // src/view/navigation/cross-moves.ts
2032
2032
  function moveHead(controller, { anchor }, head) {
2033
- dispatchSelection(controller, chunkVZZPCYA3_cjs.textSelection(anchor, head));
2033
+ dispatchSelection(controller, chunkFK7EBZPX_cjs.textSelection(anchor, head));
2034
2034
  return true;
2035
2035
  }
2036
2036
  function blockOf(controller, { block }) {
2037
2037
  const { doc } = controller.editor.state;
2038
- return doc.blocks[chunkWZA5S5EJ_cjs.requireBlockIndex(doc, block)];
2038
+ return doc.blocks[chunkI7X7B3WD_cjs.requireBlockIndex(doc, block)];
2039
2039
  }
2040
2040
  function collapseCross(controller, selection, direction) {
2041
- const { from, to } = chunkVZZPCYA3_cjs.selectionRange(controller.editor.state.doc, selection);
2042
- dispatchSelection(controller, chunkVZZPCYA3_cjs.textSelection(direction < 0 ? from : to));
2041
+ const { from, to } = chunkFK7EBZPX_cjs.selectionRange(controller.editor.state.doc, selection);
2042
+ dispatchSelection(controller, chunkFK7EBZPX_cjs.textSelection(direction < 0 ? from : to));
2043
2043
  return true;
2044
2044
  }
2045
2045
  function crossHeadVertically(controller, selection, direction) {
2046
2046
  const { head } = selection;
2047
2047
  const edge = neighbourHead(controller, head.block, direction);
2048
2048
  if (edge !== null) {
2049
- const end2 = chunkVZZPCYA3_cjs.regionLength(blockOf(controller, edge), edge.region);
2049
+ const end2 = chunkFK7EBZPX_cjs.regionLength(blockOf(controller, edge), edge.region);
2050
2050
  return moveHead(controller, selection, { ...edge, offset: Math.min(head.offset, end2) });
2051
2051
  }
2052
- const end = chunkVZZPCYA3_cjs.regionLength(blockOf(controller, head), head.region);
2052
+ const end = chunkFK7EBZPX_cjs.regionLength(blockOf(controller, head), head.region);
2053
2053
  return moveHead(controller, selection, { ...head, offset: direction < 0 ? 0 : end });
2054
2054
  }
2055
2055
  function crossHeadHorizontally(controller, selection, direction) {
2056
2056
  const { head } = selection;
2057
- const text = chunkWZA5S5EJ_cjs.inlineText(blockOf(controller, head).regions[head.region] ?? []);
2057
+ const text = chunkI7X7B3WD_cjs.inlineText(blockOf(controller, head).regions[head.region] ?? []);
2058
2058
  if (direction < 0 ? head.offset > 0 : head.offset < text.length) {
2059
- const offset = direction < 0 ? chunkVZZPCYA3_cjs.prevGraphemeOffset(text, head.offset) : chunkVZZPCYA3_cjs.nextGraphemeOffset(text, head.offset);
2059
+ const offset = direction < 0 ? chunkFK7EBZPX_cjs.prevGraphemeOffset(text, head.offset) : chunkFK7EBZPX_cjs.nextGraphemeOffset(text, head.offset);
2060
2060
  return moveHead(controller, selection, { ...head, offset });
2061
2061
  }
2062
2062
  const edge = neighbourHead(controller, head.block, direction);
@@ -2075,9 +2075,9 @@ function moveHorizontally(controller, direction, extend) {
2075
2075
  const move = extend ? crossHeadHorizontally : collapseCross;
2076
2076
  return move(controller, selection, direction);
2077
2077
  }
2078
- if (!extend && !chunkVZZPCYA3_cjs.isCollapsed(selection)) return false;
2078
+ if (!extend && !chunkFK7EBZPX_cjs.isCollapsed(selection)) return false;
2079
2079
  const { head } = selection;
2080
- const length = chunkVZZPCYA3_cjs.regionLength(doc.blocks[chunkWZA5S5EJ_cjs.requireBlockIndex(doc, head.block)], head.region);
2080
+ const length = chunkFK7EBZPX_cjs.regionLength(doc.blocks[chunkI7X7B3WD_cjs.requireBlockIndex(doc, head.block)], head.region);
2081
2081
  if (direction < 0 ? head.offset > 0 : head.offset < length) return false;
2082
2082
  const own2 = extend ? null : ownNode(controller, head.block, direction);
2083
2083
  if (own2 !== null) {
@@ -2158,7 +2158,7 @@ function lineInView(host, last) {
2158
2158
  const line = lineEdgeRect(host, last);
2159
2159
  const view = host.ownerDocument.defaultView;
2160
2160
  if (!line || !view || line.top >= 0 && line.bottom <= view.innerHeight) return line;
2161
- host.scrollIntoView({ block: "nearest" });
2161
+ host.scrollIntoView?.({ block: "nearest" });
2162
2162
  return lineEdgeRect(host, last);
2163
2163
  }
2164
2164
  function caretAtGoal(controller, host, at, y) {
@@ -2170,7 +2170,7 @@ function caretAtGoal(controller, host, at, y) {
2170
2170
  var keepOnLine = ({ registry }, pos, y) => stayOnLine(pos, y, glyphsAround(registry, pos));
2171
2171
  function landAtGoal(controller, block, direction) {
2172
2172
  const { schema } = controller.editor.state;
2173
- const region = chunkVZZPCYA3_cjs.isTextFlow(schema, block) ? chunkVZZPCYA3_cjs.primaryRegion(schema, block) : null;
2173
+ const region = chunkFK7EBZPX_cjs.isTextFlow(schema, block) ? chunkFK7EBZPX_cjs.primaryRegion(schema, block) : null;
2174
2174
  const host = region === null ? void 0 : controller.registry.get(block.id, region);
2175
2175
  if (!host || region === null || controller.goalX === null) return null;
2176
2176
  const line = lineInView(host, direction < 0);
@@ -2221,7 +2221,7 @@ function moveText(controller, selection, direction, extend) {
2221
2221
  function extendBlocks(controller, { anchor, head }, direction) {
2222
2222
  const next = neighbourBlock(controller.editor.state.doc, head, direction);
2223
2223
  if (next === null) return false;
2224
- dispatchSelection(controller, chunkVZZPCYA3_cjs.blockRangeSelection(anchor, next.id));
2224
+ dispatchSelection(controller, chunkFK7EBZPX_cjs.blockRangeSelection(anchor, next.id));
2225
2225
  return true;
2226
2226
  }
2227
2227
  function moveVertically(controller, direction, extend) {
@@ -2237,8 +2237,8 @@ function moveVertically(controller, direction, extend) {
2237
2237
  // src/view/input/flip-block.ts
2238
2238
  var isTask = ({ type, attrs }) => type === "MARKDOWN" && attrs.kind === "task";
2239
2239
  function flipCommand(block) {
2240
- if (isTask(block)) return chunkVZZPCYA3_cjs.toggleTask;
2241
- return block.type === "TOGGLE" ? chunkVZZPCYA3_cjs.setAttrs({ open: block.attrs.open !== true }) : null;
2240
+ if (isTask(block)) return chunkFK7EBZPX_cjs.toggleTask;
2241
+ return block.type === "TOGGLE" ? chunkFK7EBZPX_cjs.setAttrs({ open: block.attrs.open !== true }) : null;
2242
2242
  }
2243
2243
  var toggleState = (open) => open ? "expanded" : "collapsed";
2244
2244
  function stateName(block) {
@@ -2247,7 +2247,7 @@ function stateName(block) {
2247
2247
  }
2248
2248
  function blockHoldingCaret({ doc, selection }) {
2249
2249
  if (selection?.kind !== "text" || selection.anchor.block !== selection.head.block) return null;
2250
- return chunkWZA5S5EJ_cjs.blockById(doc, selection.head.block) ?? null;
2250
+ return chunkI7X7B3WD_cjs.blockById(doc, selection.head.block) ?? null;
2251
2251
  }
2252
2252
  function flipForReader(controller, block) {
2253
2253
  if (block?.type !== "TOGGLE") return false;
@@ -2262,7 +2262,7 @@ function flipSelectedBlock(controller) {
2262
2262
  if (controller.readOnly) return flipForReader(controller, block);
2263
2263
  const command = block && flipCommand(block);
2264
2264
  if (!block || !command || !controller.run(command)) return false;
2265
- const after = chunkWZA5S5EJ_cjs.blockById(editor.state.doc, block.id);
2265
+ const after = chunkI7X7B3WD_cjs.blockById(editor.state.doc, block.id);
2266
2266
  if (after) controller.announce(stateName(after));
2267
2267
  return true;
2268
2268
  }
@@ -2336,7 +2336,7 @@ function attachInput(controller, root) {
2336
2336
  const { editor } = controller;
2337
2337
  let { selection } = editor.state;
2338
2338
  const stop = editor.subscribe((_, tr) => {
2339
- if (tr && selection) selection = chunkVZZPCYA3_cjs.mapSelection(selection, (pos, assoc) => tr.mapPos(pos, assoc));
2339
+ if (tr && selection) selection = chunkFK7EBZPX_cjs.mapSelection(selection, (pos, assoc) => tr.mapPos(pos, assoc));
2340
2340
  });
2341
2341
  fallback.flush();
2342
2342
  stop();
@@ -2494,7 +2494,7 @@ function movedSelection(controller, doc, model) {
2494
2494
  if (controller.composingKey !== null || controller.dragging || !doc || !ownsFocus(controller, doc)) return null;
2495
2495
  const selection = readSelection(controller.registry, doc.getSelection(), (node) => controller.blockAt(node));
2496
2496
  const sided = selection?.kind === "text" && model?.kind === "text" ? { ...selection, assoc: model.assoc } : selection;
2497
- return sided === null || chunkVZZPCYA3_cjs.sameSelection(sided, model) ? null : selection;
2497
+ return sided === null || chunkFK7EBZPX_cjs.sameSelection(sided, model) ? null : selection;
2498
2498
  }
2499
2499
  function writeModelSelection(controller, doc, moved, local) {
2500
2500
  const domSelection = doc?.getSelection();
@@ -2554,7 +2554,7 @@ var ViewController = class {
2554
2554
  this.engagement = createEngagement(options.editor);
2555
2555
  this.#flush = options.flush ?? runNow;
2556
2556
  this.onFiles = options.onFiles;
2557
- this.isMac = options.isMac ?? chunkVZZPCYA3_cjs.detectMac();
2557
+ this.isMac = options.isMac ?? chunkFK7EBZPX_cjs.detectMac();
2558
2558
  const decorationsOf = (block, region) => this.decorationsFor(block, region);
2559
2559
  const drain = (element) => this.#binding?.input.drain(element);
2560
2560
  this.#hosts = createHostRenderer(options.editor, options.render, decorationsOf, drain);
@@ -2707,7 +2707,7 @@ var ViewController = class {
2707
2707
  focus(target) {
2708
2708
  const { editor } = this;
2709
2709
  const selection = focusTarget(editor.state, target);
2710
- if (selection !== null && !chunkVZZPCYA3_cjs.sameSelection(selection, editor.state.selection)) dispatchSelection(this, selection);
2710
+ if (selection !== null && !chunkFK7EBZPX_cjs.sameSelection(selection, editor.state.selection)) dispatchSelection(this, selection);
2711
2711
  this.#takeFocus();
2712
2712
  this.syncSelectionToDom();
2713
2713
  }
@@ -2755,7 +2755,7 @@ function useQuoinEditor(options) {
2755
2755
  const { blocks, readOnly = false } = options;
2756
2756
  const callbacks = react.useRef(options);
2757
2757
  const [controller] = react.useState(() => {
2758
- const editor = chunkVZZPCYA3_cjs.createEditor({
2758
+ const editor = chunkFK7EBZPX_cjs.createEditor({
2759
2759
  blocks,
2760
2760
  extensions: options.extensions,
2761
2761
  onChange: (next) => callbacks.current.onChange(next),
@@ -2781,49 +2781,17 @@ function useQuoinEditor(options) {
2781
2781
  react.useEffect(() => () => controller.destroy(), [controller]);
2782
2782
  return controller;
2783
2783
  }
2784
+ var headingPlaceholder = (_state, { type, attrs }) => type === "MARKDOWN" && attrs.kind === "heading" ? `Heading ${chunkI7X7B3WD_cjs.headingLevel(attrs.level)}` : void 0;
2785
+ var BlockPlaceholderContext = react.createContext(headingPlaceholder);
2786
+ function regionPlaceholder(state, blockId, region, placeholderOf) {
2787
+ const block = chunkI7X7B3WD_cjs.blockById(state.doc, blockId);
2788
+ return block !== void 0 && chunkFK7EBZPX_cjs.primaryRegion(state.schema, block) === region ? placeholderOf(state, block) : void 0;
2789
+ }
2784
2790
  function useReadOnly(controller) {
2785
2791
  const subscribe = react.useCallback((notify) => controller.subscribeReadOnly(notify), [controller]);
2786
2792
  const read = react.useCallback(() => controller.readOnly, [controller]);
2787
2793
  return react.useSyncExternalStore(subscribe, read, read);
2788
2794
  }
2789
- function SelectionSink({ label = "Selected content", blockLabel }) {
2790
- const controller = useViewController();
2791
- const ref = react.useRef(null);
2792
- const readOnly = useReadOnly(controller);
2793
- const name = useEditorState(
2794
- controller,
2795
- react.useCallback((state) => selectedBlockName(state, blockLabel), [blockLabel])
2796
- );
2797
- useIsomorphicLayoutEffect(() => {
2798
- const sink = ref.current;
2799
- return sink ? controller.registerSink(sink) : void 0;
2800
- }, [controller]);
2801
- return /* @__PURE__ */ jsxRuntime.jsx(
2802
- "div",
2803
- {
2804
- ref,
2805
- contentEditable: !readOnly,
2806
- suppressContentEditableWarning: true,
2807
- role: "textbox",
2808
- "aria-label": name || label,
2809
- inputMode: name === null ? void 0 : "none",
2810
- "aria-multiline": name === null ? "true" : void 0,
2811
- "aria-readonly": readOnly ? "true" : void 0,
2812
- tabIndex: -1,
2813
- spellCheck: false,
2814
- "data-quoin-sink": "",
2815
- onFocus: () => {
2816
- if (heldBySink(controller.editor.state.selection)) focusSink(controller);
2817
- }
2818
- }
2819
- );
2820
- }
2821
- var headingPlaceholder = (_state, { type, attrs }) => type === "MARKDOWN" && attrs.kind === "heading" ? `Heading ${chunkWZA5S5EJ_cjs.headingLevel(attrs.level)}` : void 0;
2822
- var BlockPlaceholderContext = react.createContext(headingPlaceholder);
2823
- function regionPlaceholder(state, blockId, region, placeholderOf) {
2824
- const block = chunkWZA5S5EJ_cjs.blockById(state.doc, blockId);
2825
- return block !== void 0 && chunkVZZPCYA3_cjs.primaryRegion(state.schema, block) === region ? placeholderOf(state, block) : void 0;
2826
- }
2827
2795
  var samePainted = (a, b) => a.inline === b.inline && a.placeholder === b.placeholder && sameDecorations(a.decorations, b.decorations);
2828
2796
  function EditableRegion({ block, region, label, id, placeholder, className }) {
2829
2797
  const controller = useViewController();
@@ -2833,7 +2801,7 @@ function EditableRegion({ block, region, label, id, placeholder, className }) {
2833
2801
  const select = react.useCallback(
2834
2802
  (state) => {
2835
2803
  const inline2 = regionInline(state, block, region);
2836
- const empty = inline2 === void 0 || chunkWZA5S5EJ_cjs.inlineLength(inline2) === 0;
2804
+ const empty = inline2 === void 0 || chunkI7X7B3WD_cjs.inlineLength(inline2) === 0;
2837
2805
  return {
2838
2806
  inline: inline2,
2839
2807
  decorations: controller.decorationsFor(block, region),
@@ -2870,6 +2838,178 @@ function EditableRegion({ block, region, label, id, placeholder, className }) {
2870
2838
  }
2871
2839
  );
2872
2840
  }
2841
+ var BLOCK_ERROR = "Block could not be drawn";
2842
+ var BlockErrorContext = react.createContext({ label: BLOCK_ERROR });
2843
+ var BlockDomIdScope = react.createContext("quoin");
2844
+ function useBlockDomId() {
2845
+ const scope = react.useContext(BlockDomIdScope);
2846
+ return react.useCallback((block) => `${scope}-${encodeURIComponent(block)}`, [scope]);
2847
+ }
2848
+ function useRegionDomId(block, region) {
2849
+ return `${useBlockDomId()(block)}/${encodeURIComponent(region)}`;
2850
+ }
2851
+ function EmptyDocumentHost({ placeholder, label = "Paragraph" }) {
2852
+ const controller = useViewController();
2853
+ const ref = react.useRef(null);
2854
+ const readOnly = useReadOnly(controller);
2855
+ useIsomorphicLayoutEffect(() => {
2856
+ const host = ref.current;
2857
+ if (host === null) return void 0;
2858
+ renderInline(host, [], []);
2859
+ return controller.registerEmptyHost(host);
2860
+ }, [controller]);
2861
+ return /* @__PURE__ */ jsxRuntime.jsx(
2862
+ "div",
2863
+ {
2864
+ ref,
2865
+ contentEditable: !readOnly,
2866
+ suppressContentEditableWarning: true,
2867
+ role: "textbox",
2868
+ "aria-multiline": "true",
2869
+ "aria-readonly": readOnly ? "true" : void 0,
2870
+ "aria-label": label,
2871
+ "data-quoin-host": "",
2872
+ "data-quoin-empty": "",
2873
+ "data-placeholder": readOnly ? void 0 : placeholder,
2874
+ "aria-placeholder": readOnly ? void 0 : placeholder,
2875
+ spellCheck: true,
2876
+ onClick: () => ref.current?.focus()
2877
+ }
2878
+ );
2879
+ }
2880
+
2881
+ // src/view/react/focus-owners.ts
2882
+ var focusOwners = /* @__PURE__ */ new WeakMap();
2883
+
2884
+ // src/view/selection/selection-announcement.ts
2885
+ var SILENCE = { key: "", message: "" };
2886
+ function selectionAnnouncement({ doc, selection }, blocksSelected) {
2887
+ if (selection === null || selection.kind === "text" && !isCrossSelection(selection)) return SILENCE;
2888
+ if (selection.kind === "node") return { key: `node:${selection.block}`, message: blocksSelected(1) };
2889
+ const anchor = selection.kind === "blocks" ? selection.anchor : selection.anchor.block;
2890
+ const head = selection.kind === "blocks" ? selection.head : selection.head.block;
2891
+ const first = doc.index.get(anchor);
2892
+ const last = doc.index.get(head);
2893
+ if (first === void 0 || last === void 0) return SILENCE;
2894
+ const count = drawnBlockCount(doc, Math.min(first, last), Math.max(first, last) + 1);
2895
+ return { key: `${selection.kind}:${anchor}:${head}`, message: blocksSelected(count) };
2896
+ }
2897
+ function heardNow({ editor, announcer, engagement }, blocksSelected) {
2898
+ const spoken = announcer.current();
2899
+ if (spoken !== null) return { key: `said:${spoken.serial}`, message: spoken.message };
2900
+ return engagement.engaged ? selectionAnnouncement(editor.state, blocksSelected) : SILENCE;
2901
+ }
2902
+ function LiveRegion({ blocksSelected }) {
2903
+ const controller = useViewController();
2904
+ const subscribe = react.useCallback(
2905
+ (notify) => {
2906
+ const stopState = controller.editor.subscribe(() => notify());
2907
+ const stopSpoken = controller.announcer.subscribe(notify);
2908
+ const stopEngaged = controller.engagement.subscribe(notify);
2909
+ return () => {
2910
+ stopState();
2911
+ stopSpoken();
2912
+ stopEngaged();
2913
+ };
2914
+ },
2915
+ [controller]
2916
+ );
2917
+ const read = react.useMemo(() => {
2918
+ let last = SILENCE;
2919
+ return () => {
2920
+ const next = heardNow(controller, blocksSelected);
2921
+ if (next.key !== last.key || next.message !== last.message) last = next;
2922
+ return last;
2923
+ };
2924
+ }, [controller, blocksSelected]);
2925
+ const { key, message } = react.useSyncExternalStore(subscribe, read, read);
2926
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "quoin-visually-hidden", role: "status", "aria-live": "polite", "aria-atomic": "true", children: message !== "" && /* @__PURE__ */ jsxRuntime.jsx("span", { children: message }, key) });
2927
+ }
2928
+ function SelectionSink({ label = "Selected content", blockLabel }) {
2929
+ const controller = useViewController();
2930
+ const ref = react.useRef(null);
2931
+ const readOnly = useReadOnly(controller);
2932
+ const name = useEditorState(
2933
+ controller,
2934
+ react.useCallback((state) => selectedBlockName(state, blockLabel), [blockLabel])
2935
+ );
2936
+ useIsomorphicLayoutEffect(() => {
2937
+ const sink = ref.current;
2938
+ return sink ? controller.registerSink(sink) : void 0;
2939
+ }, [controller]);
2940
+ return /* @__PURE__ */ jsxRuntime.jsx(
2941
+ "div",
2942
+ {
2943
+ ref,
2944
+ contentEditable: !readOnly,
2945
+ suppressContentEditableWarning: true,
2946
+ role: "textbox",
2947
+ "aria-label": name || label,
2948
+ inputMode: name === null ? void 0 : "none",
2949
+ "aria-multiline": name === null ? "true" : void 0,
2950
+ "aria-readonly": readOnly ? "true" : void 0,
2951
+ tabIndex: -1,
2952
+ spellCheck: false,
2953
+ "data-quoin-sink": "",
2954
+ onFocus: () => {
2955
+ if (heldBySink(controller.editor.state.selection)) focusSink(controller);
2956
+ }
2957
+ }
2958
+ );
2959
+ }
2960
+
2961
+ // src/view/react/SelectionWriter.tsx
2962
+ function SelectionWriter() {
2963
+ const controller = useViewController();
2964
+ const state = useEditorState(controller, wholeState);
2965
+ useIsomorphicLayoutEffect(() => controller.afterRender(), [controller, state]);
2966
+ return null;
2967
+ }
2968
+ var UNSUPPORTED_BLOCK = "Unsupported block";
2969
+ var UnsupportedBlockLabel = react.createContext(UNSUPPORTED_BLOCK);
2970
+ var Boundary = class extends react.Component {
2971
+ state = { block: this.props.block, renderer: this.props.renderer, failed: false };
2972
+ static getDerivedStateFromError() {
2973
+ return { failed: true };
2974
+ }
2975
+ static getDerivedStateFromProps(props, state) {
2976
+ const same = props.block === state.block && props.renderer === state.renderer;
2977
+ return same ? null : { block: props.block, renderer: props.renderer, failed: false };
2978
+ }
2979
+ componentDidCatch(error) {
2980
+ this.props.report?.(error instanceof Error ? error : new Error(String(error)));
2981
+ }
2982
+ render() {
2983
+ if (!this.state.failed) return this.props.children;
2984
+ const { label } = this.props;
2985
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "quoin-void", contentEditable: false, role: "group", "aria-label": label, children: label });
2986
+ }
2987
+ };
2988
+ function BlockErrorBoundary({ block, renderer, children }) {
2989
+ const { label, report } = react.useContext(BlockErrorContext);
2990
+ return /* @__PURE__ */ jsxRuntime.jsx(Boundary, { block, renderer, label, report, children });
2991
+ }
2992
+
2993
+ // src/view/react/block-status.ts
2994
+ function within(state, index, ends) {
2995
+ const [anchor, head] = ends.map((id) => state.doc.index.get(id));
2996
+ if (anchor === void 0 || head === void 0) return false;
2997
+ return index >= Math.min(anchor, head) && index <= Math.max(anchor, head);
2998
+ }
2999
+ function covers(state, id, index) {
3000
+ const { doc, schema, selection } = state;
3001
+ if (selection === null) return false;
3002
+ if (selection.kind === "node") return selection.block === id;
3003
+ if (selection.kind === "blocks") return within(state, index, [selection.anchor, selection.head]);
3004
+ if (!isCrossSelection(selection) || chunkFK7EBZPX_cjs.isTextFlow(schema, doc.blocks[index])) return false;
3005
+ return within(state, index, [selection.anchor.block, selection.head.block]);
3006
+ }
3007
+ function blockStatus(state, id, choices = NO_CHOICES) {
3008
+ const index = state.doc.index.get(id);
3009
+ if (index === void 0) return "plain";
3010
+ if (isHiddenAt(state.doc, index, choices)) return "hidden";
3011
+ return covers(state, id, index) ? "selected" : "plain";
3012
+ }
2873
3013
  var CalloutBlock = ({ block }) => {
2874
3014
  const tone = typeof block.attrs.tone === "string" && block.attrs.tone !== "" ? block.attrs.tone : "info";
2875
3015
  return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "quoin-callout", "data-tone": tone, children: /* @__PURE__ */ jsxRuntime.jsx(EditableRegion, { block: block.id, region: "body", label: `Callout, ${tone}` }) });
@@ -2878,7 +3018,7 @@ var CalloutBlock = ({ block }) => {
2878
3018
  // src/view/react/block-command.ts
2879
3019
  function onBlock(id, command) {
2880
3020
  return (state, dispatch) => {
2881
- const { ok, tr } = chunkVZZPCYA3_cjs.runCommands(state, [chunkVZZPCYA3_cjs.setSelection(chunkVZZPCYA3_cjs.blockRangeSelection(id)), command]);
3021
+ const { ok, tr } = chunkFK7EBZPX_cjs.runCommands(state, [chunkFK7EBZPX_cjs.setSelection(chunkFK7EBZPX_cjs.blockRangeSelection(id)), command]);
2882
3022
  if (!ok || tr === null) return false;
2883
3023
  dispatch?.(tr.setSelection(state.selection));
2884
3024
  return true;
@@ -2898,7 +3038,7 @@ function TaskCheckbox({ block, controller, label, labelledBy }) {
2898
3038
  role: "checkbox",
2899
3039
  "aria-checked": checked,
2900
3040
  "aria-readonly": readOnly ? "true" : void 0,
2901
- "aria-label": chunkWZA5S5EJ_cjs.firstNamed(label, "Task"),
3041
+ "aria-label": chunkI7X7B3WD_cjs.firstNamed(label, "Task"),
2902
3042
  "aria-labelledby": labelledBy,
2903
3043
  className: "quoin-task-box",
2904
3044
  contentEditable: false,
@@ -2929,7 +3069,7 @@ function numberDoc(doc) {
2929
3069
  numbers[index] = run2.next++;
2930
3070
  return;
2931
3071
  }
2932
- const start = chunkWZA5S5EJ_cjs.orderedStart(block.attrs.start);
3072
+ const start = chunkI7X7B3WD_cjs.orderedStart(block.attrs.start);
2933
3073
  numbers[index] = start;
2934
3074
  runs.push({ indent: block.indent, next: start + 1 });
2935
3075
  });
@@ -2967,7 +3107,7 @@ var MarkdownBlock = (props) => {
2967
3107
  const { block } = props;
2968
3108
  switch (block.attrs.kind) {
2969
3109
  case "heading": {
2970
- const level = chunkWZA5S5EJ_cjs.headingLevel(block.attrs.level);
3110
+ const level = chunkI7X7B3WD_cjs.headingLevel(block.attrs.level);
2971
3111
  return /* @__PURE__ */ jsxRuntime.jsx("div", { role: "heading", "aria-level": level, className: "quoin-heading", children: /* @__PURE__ */ jsxRuntime.jsx(TextRegion, { block, label: `Heading ${level}` }) });
2972
3112
  }
2973
3113
  case "bullet":
@@ -3025,8 +3165,6 @@ var ToggleBlock = ({ block, controller }) => {
3025
3165
  /* @__PURE__ */ jsxRuntime.jsx(EditableRegion, { block: block.id, region: "text", label: "Toggle" })
3026
3166
  ] });
3027
3167
  };
3028
- var UNSUPPORTED_BLOCK = "Unsupported block";
3029
- var UnsupportedBlockLabel = react.createContext(UNSUPPORTED_BLOCK);
3030
3168
  var defaultRenderers = {
3031
3169
  MARKDOWN: MarkdownBlock,
3032
3170
  CALLOUT: CalloutBlock,
@@ -3037,59 +3175,6 @@ var VoidBlockFallback = ({ block }) => {
3037
3175
  if (block.type === "DIVIDER") return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "quoin-void", contentEditable: false, role: "separator" });
3038
3176
  return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "quoin-void", contentEditable: false, role: "group", "aria-label": label, children: label });
3039
3177
  };
3040
- var BLOCK_ERROR = "Block could not be drawn";
3041
- var BlockErrorContext = react.createContext({ label: BLOCK_ERROR });
3042
- var Boundary = class extends react.Component {
3043
- state = { block: this.props.block, renderer: this.props.renderer, failed: false };
3044
- static getDerivedStateFromError() {
3045
- return { failed: true };
3046
- }
3047
- static getDerivedStateFromProps(props, state) {
3048
- const same = props.block === state.block && props.renderer === state.renderer;
3049
- return same ? null : { block: props.block, renderer: props.renderer, failed: false };
3050
- }
3051
- componentDidCatch(error) {
3052
- this.props.report?.(error instanceof Error ? error : new Error(String(error)));
3053
- }
3054
- render() {
3055
- if (!this.state.failed) return this.props.children;
3056
- const { label } = this.props;
3057
- return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "quoin-void", contentEditable: false, role: "group", "aria-label": label, children: label });
3058
- }
3059
- };
3060
- function BlockErrorBoundary({ block, renderer, children }) {
3061
- const { label, report } = react.useContext(BlockErrorContext);
3062
- return /* @__PURE__ */ jsxRuntime.jsx(Boundary, { block, renderer, label, report, children });
3063
- }
3064
- var BlockDomIdScope = react.createContext("quoin");
3065
- function useBlockDomId() {
3066
- const scope = react.useContext(BlockDomIdScope);
3067
- return react.useCallback((block) => `${scope}-${encodeURIComponent(block)}`, [scope]);
3068
- }
3069
- function useRegionDomId(block, region) {
3070
- return `${useBlockDomId()(block)}/${encodeURIComponent(region)}`;
3071
- }
3072
-
3073
- // src/view/react/block-status.ts
3074
- function within(state, index, ends) {
3075
- const [anchor, head] = ends.map((id) => state.doc.index.get(id));
3076
- if (anchor === void 0 || head === void 0) return false;
3077
- return index >= Math.min(anchor, head) && index <= Math.max(anchor, head);
3078
- }
3079
- function covers(state, id, index) {
3080
- const { doc, schema, selection } = state;
3081
- if (selection === null) return false;
3082
- if (selection.kind === "node") return selection.block === id;
3083
- if (selection.kind === "blocks") return within(state, index, [selection.anchor, selection.head]);
3084
- if (!isCrossSelection(selection) || chunkVZZPCYA3_cjs.isTextFlow(schema, doc.blocks[index])) return false;
3085
- return within(state, index, [selection.anchor.block, selection.head.block]);
3086
- }
3087
- function blockStatus(state, id, choices = NO_CHOICES) {
3088
- const index = state.doc.index.get(id);
3089
- if (index === void 0) return "plain";
3090
- if (isHiddenAt(state.doc, index, choices)) return "hidden";
3091
- return covers(state, id, index) ? "selected" : "plain";
3092
- }
3093
3178
  var unwatched = () => () => {
3094
3179
  };
3095
3180
  function useEngaged(controller, watching) {
@@ -3131,11 +3216,11 @@ var BlockShell = react.memo(function BlockShell2({ block, renderers }) {
3131
3216
  "data-quoin-block": "",
3132
3217
  "data-block-id": block.id,
3133
3218
  "data-type": block.type,
3134
- "data-kind": chunkWZA5S5EJ_cjs.optionalString(kind),
3219
+ "data-kind": chunkI7X7B3WD_cjs.optionalString(kind),
3135
3220
  "data-indent": block.indent,
3136
- "data-color": chunkWZA5S5EJ_cjs.paletteOrUndefined(color),
3137
- "data-bg": chunkWZA5S5EJ_cjs.paletteOrUndefined(background),
3138
- "data-align": chunkWZA5S5EJ_cjs.alignOrUndefined(align),
3221
+ "data-color": chunkI7X7B3WD_cjs.paletteOrUndefined(color),
3222
+ "data-bg": chunkI7X7B3WD_cjs.paletteOrUndefined(background),
3223
+ "data-align": chunkI7X7B3WD_cjs.alignOrUndefined(align),
3139
3224
  style: { "--quoin-indent": block.indent },
3140
3225
  tabIndex: -1,
3141
3226
  "data-selected": status === "selected" && engaged ? "true" : void 0,
@@ -3143,91 +3228,6 @@ var BlockShell = react.memo(function BlockShell2({ block, renderers }) {
3143
3228
  }
3144
3229
  );
3145
3230
  });
3146
- function EmptyDocumentHost({ placeholder, label = "Paragraph" }) {
3147
- const controller = useViewController();
3148
- const ref = react.useRef(null);
3149
- const readOnly = useReadOnly(controller);
3150
- useIsomorphicLayoutEffect(() => {
3151
- const host = ref.current;
3152
- if (host === null) return void 0;
3153
- renderInline(host, [], []);
3154
- return controller.registerEmptyHost(host);
3155
- }, [controller]);
3156
- return /* @__PURE__ */ jsxRuntime.jsx(
3157
- "div",
3158
- {
3159
- ref,
3160
- contentEditable: !readOnly,
3161
- suppressContentEditableWarning: true,
3162
- role: "textbox",
3163
- "aria-multiline": "true",
3164
- "aria-readonly": readOnly ? "true" : void 0,
3165
- "aria-label": label,
3166
- "data-quoin-host": "",
3167
- "data-quoin-empty": "",
3168
- "data-placeholder": readOnly ? void 0 : placeholder,
3169
- "aria-placeholder": readOnly ? void 0 : placeholder,
3170
- spellCheck: true,
3171
- onClick: () => ref.current?.focus()
3172
- }
3173
- );
3174
- }
3175
-
3176
- // src/view/react/focus-owners.ts
3177
- var focusOwners = /* @__PURE__ */ new WeakMap();
3178
-
3179
- // src/view/selection/selection-announcement.ts
3180
- var SILENCE = { key: "", message: "" };
3181
- function selectionAnnouncement({ doc, selection }, blocksSelected) {
3182
- if (selection === null || selection.kind === "text" && !isCrossSelection(selection)) return SILENCE;
3183
- if (selection.kind === "node") return { key: `node:${selection.block}`, message: blocksSelected(1) };
3184
- const anchor = selection.kind === "blocks" ? selection.anchor : selection.anchor.block;
3185
- const head = selection.kind === "blocks" ? selection.head : selection.head.block;
3186
- const first = doc.index.get(anchor);
3187
- const last = doc.index.get(head);
3188
- if (first === void 0 || last === void 0) return SILENCE;
3189
- const count = drawnBlockCount(doc, Math.min(first, last), Math.max(first, last) + 1);
3190
- return { key: `${selection.kind}:${anchor}:${head}`, message: blocksSelected(count) };
3191
- }
3192
- function heardNow({ editor, announcer, engagement }, blocksSelected) {
3193
- const spoken = announcer.current();
3194
- if (spoken !== null) return { key: `said:${spoken.serial}`, message: spoken.message };
3195
- return engagement.engaged ? selectionAnnouncement(editor.state, blocksSelected) : SILENCE;
3196
- }
3197
- function LiveRegion({ blocksSelected }) {
3198
- const controller = useViewController();
3199
- const subscribe = react.useCallback(
3200
- (notify) => {
3201
- const stopState = controller.editor.subscribe(() => notify());
3202
- const stopSpoken = controller.announcer.subscribe(notify);
3203
- const stopEngaged = controller.engagement.subscribe(notify);
3204
- return () => {
3205
- stopState();
3206
- stopSpoken();
3207
- stopEngaged();
3208
- };
3209
- },
3210
- [controller]
3211
- );
3212
- const read = react.useMemo(() => {
3213
- let last = SILENCE;
3214
- return () => {
3215
- const next = heardNow(controller, blocksSelected);
3216
- if (next.key !== last.key || next.message !== last.message) last = next;
3217
- return last;
3218
- };
3219
- }, [controller, blocksSelected]);
3220
- const { key, message } = react.useSyncExternalStore(subscribe, read, read);
3221
- return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "quoin-visually-hidden", role: "status", "aria-live": "polite", "aria-atomic": "true", children: message !== "" && /* @__PURE__ */ jsxRuntime.jsx("span", { children: message }, key) });
3222
- }
3223
-
3224
- // src/view/react/SelectionWriter.tsx
3225
- function SelectionWriter() {
3226
- const controller = useViewController();
3227
- const state = useEditorState(controller, wholeState);
3228
- useIsomorphicLayoutEffect(() => controller.afterRender(), [controller, state]);
3229
- return null;
3230
- }
3231
3231
  function useBlockElements(blocks, renderers) {
3232
3232
  const [made] = react.useState(() => /* @__PURE__ */ new WeakMap());
3233
3233
  return blocks.map((block) => {
@@ -3292,20 +3292,16 @@ function EditorView({
3292
3292
  }
3293
3293
 
3294
3294
  exports.BlockErrorContext = BlockErrorContext;
3295
- exports.BlockShell = BlockShell;
3296
3295
  exports.EditableRegion = EditableRegion;
3297
3296
  exports.EditorView = EditorView;
3298
3297
  exports.NATIVE_INTERACTION = NATIVE_INTERACTION;
3299
3298
  exports.NODE_ENTRY = NODE_ENTRY;
3300
- exports.SelectionSink = SelectionSink;
3301
3299
  exports.TaskCheckbox = TaskCheckbox;
3302
3300
  exports.ToggleChevron = ToggleChevron;
3303
3301
  exports.ViewController = ViewController;
3304
- exports.VoidBlockFallback = VoidBlockFallback;
3305
3302
  exports.caretClientRect = caretClientRect;
3306
3303
  exports.caretFromPoint = caretFromPoint;
3307
3304
  exports.createAutoScroll = createAutoScroll;
3308
- exports.defaultRenderers = defaultRenderers;
3309
3305
  exports.dispatchSelection = dispatchSelection;
3310
3306
  exports.domMapOf = domMapOf;
3311
3307
  exports.domToPos = domToPos;
@@ -3314,7 +3310,6 @@ exports.focusOwners = focusOwners;
3314
3310
  exports.handleCopy = handleCopy;
3315
3311
  exports.hostKey = hostKey;
3316
3312
  exports.isComposingKey = isComposingKey;
3317
- exports.isCrossSelection = isCrossSelection;
3318
3313
  exports.isOnFirstLine = isOnFirstLine;
3319
3314
  exports.isOnLastLine = isOnLastLine;
3320
3315
  exports.lineEdgeRect = lineEdgeRect;