@stll/folio-core 0.60.0 → 0.62.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 (173) hide show
  1. package/README.md +13 -0
  2. package/dist/ai-edits/apply.js +139 -32
  3. package/dist/ai-edits/headless.d.ts +3 -0
  4. package/dist/ai-edits/headless.js +70 -75
  5. package/dist/ai-edits/note-story-inventory.d.ts +7 -0
  6. package/dist/ai-edits/note-story-inventory.js +11 -0
  7. package/dist/ai-edits/read.js +16 -9
  8. package/dist/ai-edits/revisionStretches.js +52 -1
  9. package/dist/ai-edits/table-row-column-mutations.js +6 -1
  10. package/dist/compare/reproducible-package.js +2 -1
  11. package/dist/compare/verification.js +1 -0
  12. package/dist/compat/eigenpal.d.ts +3 -1
  13. package/dist/controller/canonicalClipboard.js +2 -1
  14. package/dist/controller/canonicalListRendering.d.ts +4 -6
  15. package/dist/controller/canonicalListRendering.js +3 -157
  16. package/dist/controller/headerFooterEditorManager.d.ts +1 -0
  17. package/dist/controller/headerFooterEditorManager.js +11 -0
  18. package/dist/controller/hiddenEditorManager.d.ts +1 -1
  19. package/dist/controller/hiddenEditorManager.js +3 -1
  20. package/dist/controller/layoutPipeline.d.ts +3 -1
  21. package/dist/controller/layoutPipeline.js +13 -4
  22. package/dist/controller/layoutSession.d.ts +2 -1
  23. package/dist/controller/noteEditorManager.d.ts +1 -1
  24. package/dist/display-list/build/imagePrimitives.js +28 -12
  25. package/dist/display-list/build/paragraphPrimitives.js +15 -2
  26. package/dist/display-list/dom/renderDisplayListToDom.js +8 -5
  27. package/dist/display-list/types.d.ts +7 -3
  28. package/dist/docx/canonicalStoryRepack.js +3 -2
  29. package/dist/docx/commentTextParagraph.d.ts +6 -0
  30. package/dist/docx/commentTextParagraph.js +15 -0
  31. package/dist/docx/conformance.js +6 -1
  32. package/dist/docx/diagramPreview.js +2 -1
  33. package/dist/docx/documentParser.d.ts +13 -1
  34. package/dist/docx/documentParser.js +1 -1
  35. package/dist/docx/encryption/compoundFile.d.ts +0 -8
  36. package/dist/docx/encryption/compoundFile.js +2 -1
  37. package/dist/docx/encryption/cryptoBytes.d.ts +2 -2
  38. package/dist/docx/encryption/cryptoBytes.js +3 -18
  39. package/dist/docx/encryption/encryptionInfo.d.ts +0 -5
  40. package/dist/docx/encryption/encryptionInfo.js +2 -1
  41. package/dist/docx/ensureParaIds.js +2 -1
  42. package/dist/docx/groupDrawingParser.js +28 -13
  43. package/dist/docx/listModelNormalization.d.ts +10 -0
  44. package/dist/docx/listModelNormalization.js +166 -0
  45. package/dist/docx/metadataPrivacy.js +3 -2
  46. package/dist/docx/metafileRaster.js +2 -1
  47. package/dist/docx/packageParts.js +6 -5
  48. package/dist/docx/paragraphParser.js +6 -4
  49. package/dist/docx/parser.js +5 -4
  50. package/dist/docx/preservedRunContent.js +11 -2
  51. package/dist/docx/removeHeaderFooterParts.js +8 -7
  52. package/dist/docx/replyToComment.js +3 -13
  53. package/dist/docx/rezip.js +88 -89
  54. package/dist/docx/runParser.js +12 -6
  55. package/dist/docx/runPropertyPresence.d.ts +11 -0
  56. package/dist/docx/runPropertyPresence.js +14 -0
  57. package/dist/docx/selectiveSave.js +15 -14
  58. package/dist/docx/serializer/runSerializer.js +3 -2
  59. package/dist/docx/serializer/tableSerializer.js +2 -1
  60. package/dist/docx/server/applyDocxXmlPatchProposal.js +2 -2
  61. package/dist/docx/server/boundedArchive.js +2 -1
  62. package/dist/docx/server/evaluateDocxXmlPatchProposal.js +2 -1
  63. package/dist/docx/server/inspectDocxPackage.js +5 -1
  64. package/dist/docx/server/validateDocxConformance.js +2 -1
  65. package/dist/docx/tableParser.js +7 -4
  66. package/dist/docx/tableRowPropertyPresence.d.ts +9 -0
  67. package/dist/docx/tableRowPropertyPresence.js +15 -0
  68. package/dist/docx/unzip.js +2 -1
  69. package/dist/docx/xmlEncoding.js +6 -5
  70. package/dist/fonts/fontsourceFaces.js +2 -1
  71. package/dist/fonts/sfnt/parse.js +6 -9
  72. package/dist/fonts/sfnt/subset.js +2 -1
  73. package/dist/fonts/sfnt/tables.js +2 -3
  74. package/dist/fonts/sfnt/woff.js +2 -1
  75. package/dist/i18n/messages/ar.gen.js +1 -0
  76. package/dist/i18n/messages/catalogs.gen.d.ts +17 -0
  77. package/dist/i18n/messages/catalogs.gen.js +17 -0
  78. package/dist/i18n/messages/cs.gen.js +1 -0
  79. package/dist/i18n/messages/de.gen.js +1 -0
  80. package/dist/i18n/messages/en.gen.js +1 -0
  81. package/dist/i18n/messages/es.gen.js +1 -0
  82. package/dist/i18n/messages/et.gen.js +1 -0
  83. package/dist/i18n/messages/fr.gen.js +1 -0
  84. package/dist/i18n/messages/he.gen.js +1 -0
  85. package/dist/i18n/messages/hi.gen.js +1 -0
  86. package/dist/i18n/messages/hu.gen.js +1 -0
  87. package/dist/i18n/messages/lt.gen.js +1 -0
  88. package/dist/i18n/messages/lv.gen.js +1 -0
  89. package/dist/i18n/messages/messages.gen.d.ts +1 -0
  90. package/dist/i18n/messages/pl.gen.js +1 -0
  91. package/dist/i18n/messages/pt-BR.gen.js +1 -0
  92. package/dist/i18n/messages/sk.gen.js +1 -0
  93. package/dist/i18n/messages/tr.gen.js +1 -0
  94. package/dist/i18n/messages/zh-CN.gen.js +1 -0
  95. package/dist/index.d.ts +3 -1
  96. package/dist/internal/revisionResolutionInline.d.ts +2 -1
  97. package/dist/internal/revisionResolutionInline.js +22 -1
  98. package/dist/internal/wholeStoryRevisionResolution.js +24 -7
  99. package/dist/layout-bridge/convert/endnoteLayout.d.ts +1 -1
  100. package/dist/layout-bridge/convert/endnoteLayout.js +1 -3
  101. package/dist/layout-bridge/convert/flowConversionShared.d.ts +2 -0
  102. package/dist/layout-bridge/convert/footnoteLayout.d.ts +4 -0
  103. package/dist/layout-bridge/convert/footnoteLayout.js +13 -3
  104. package/dist/layout-bridge/convert/headerFooterLayout.d.ts +5 -0
  105. package/dist/layout-bridge/convert/headerFooterLayout.js +12 -15
  106. package/dist/layout-bridge/convert/paragraphRuns.js +2 -1
  107. package/dist/layout-engine/index.js +2 -2
  108. package/dist/layout-engine/measure/crossRunWords.js +12 -2
  109. package/dist/layout-engine/noteAreaFlow.d.ts +4 -4
  110. package/dist/layout-engine/noteAreaFlow.js +12 -6
  111. package/dist/layout-engine/types.d.ts +5 -2
  112. package/dist/layout-painter/index.d.ts +1 -1
  113. package/dist/managers/AutoSaveManager.js +2 -1
  114. package/dist/managers/EditorModeManager.d.ts +10 -1
  115. package/dist/managers/EditorModeManager.js +15 -1
  116. package/dist/managers/FindReplaceManager.d.ts +13 -6
  117. package/dist/managers/FindReplaceManager.js +15 -9
  118. package/dist/managers/TableSelectionManager.d.ts +1 -1
  119. package/dist/managers/autoSaveCodec.js +2 -6
  120. package/dist/managers/reviewDisplayMode.d.ts +8 -0
  121. package/dist/managers/reviewDisplayMode.js +15 -0
  122. package/dist/paged-layout/editorScrollRoot.d.ts +3 -1
  123. package/dist/paged-layout/editorScrollRoot.js +2 -2
  124. package/dist/paged-layout/pageText.d.ts +11 -2
  125. package/dist/paged-layout/pageText.js +8 -3
  126. package/dist/pdf/fonts.js +5 -14
  127. package/dist/pdf/images.js +4 -2
  128. package/dist/pdf/objects.d.ts +0 -11
  129. package/dist/pdf/objects.js +7 -9
  130. package/dist/pdf/writePdf.js +2 -1
  131. package/dist/prosemirror/commands/comments.js +51 -13
  132. package/dist/prosemirror/commentRangeInlineAtoms.d.ts +40 -0
  133. package/dist/prosemirror/commentRangeInlineAtoms.js +33 -0
  134. package/dist/prosemirror/containerFinalParagraph.d.ts +8 -8
  135. package/dist/prosemirror/containerFinalParagraph.js +8 -8
  136. package/dist/prosemirror/conversion/fromProseDoc.js +14 -8
  137. package/dist/prosemirror/conversion/toProseDoc.js +16 -23
  138. package/dist/prosemirror/extensions/nodes/CommentReferenceExtension.js +16 -2
  139. package/dist/prosemirror/fieldRepresentation.js +4 -2
  140. package/dist/prosemirror/findReplaceSelection.d.ts +48 -2
  141. package/dist/prosemirror/findReplaceSelection.js +153 -38
  142. package/dist/prosemirror/inlineDisplayText.d.ts +10 -0
  143. package/dist/prosemirror/inlineDisplayText.js +29 -0
  144. package/dist/prosemirror/markupViewProjection.d.ts +10 -1
  145. package/dist/prosemirror/markupViewProjection.js +21 -3
  146. package/dist/prosemirror/plugins/transactionInvariants.js +6 -1
  147. package/dist/prosemirror/replacedAnnotations.d.ts +15 -1
  148. package/dist/prosemirror/replacedAnnotations.js +71 -12
  149. package/dist/prosemirror/runFormattingReconciliation.d.ts +3 -1
  150. package/dist/prosemirror/runFormattingReconciliation.js +10 -2
  151. package/dist/prosemirror/runIdentityAcrossRevisions.d.ts +5 -7
  152. package/dist/prosemirror/runIdentityAcrossRevisions.js +66 -38
  153. package/dist/prosemirror/runPropertyChangeResolution.js +13 -1
  154. package/dist/prosemirror/trackedRunInlineAtoms.d.ts +1 -1
  155. package/dist/prosemirror/trackedRunInlineAtoms.js +1 -1
  156. package/dist/utils/base64.d.ts +1 -31
  157. package/dist/utils/base64.js +19 -33
  158. package/dist/utils/clipboard.js +5 -4
  159. package/dist/utils/colorResolver.js +11 -2
  160. package/dist/utils/findMatchView.d.ts +32 -0
  161. package/dist/utils/findMatchView.js +406 -0
  162. package/dist/utils/findReplace.d.ts +67 -4
  163. package/dist/utils/findReplace.js +359 -37
  164. package/dist/utils/findSearchKey.d.ts +29 -0
  165. package/dist/utils/findSearchKey.js +34 -0
  166. package/dist/utils/replaceText.js +138 -94
  167. package/dist/utils/sliceText.d.ts +2 -0
  168. package/dist/utils/sliceText.js +2 -0
  169. package/dist/utils/textEncoding.d.ts +2 -0
  170. package/dist/utils/textEncoding.js +2 -0
  171. package/dist/utils/tiffConverter.d.ts +0 -9
  172. package/dist/utils/tiffConverter.js +2 -4
  173. package/package.json +51 -25
@@ -1,4 +1,6 @@
1
1
  import { cloneDocumentWithParagraphPropertySources } from "../docx/paragraphPropertySource.js";
2
+ import { getFindParagraphText } from "./findReplace.js";
3
+ import { panic } from "better-result";
2
4
  //#region src/utils/replaceText.ts
3
5
  /** Replace text within a range in the document. Returns a new document. */
4
6
  function replaceTextInDocument(doc, range, text, formatting) {
@@ -8,14 +10,24 @@ function replaceTextInDocument(doc, range, text, formatting) {
8
10
  if (start.paragraphIndex === end.paragraphIndex) {
9
11
  const paragraph = getParagraphByIndex(body, start.paragraphIndex);
10
12
  if (!paragraph) return newDoc;
11
- paragraph.content = deleteTextInParagraph(paragraph, start.offset, end.offset);
12
- paragraph.content = insertTextAtOffset(paragraph, start.offset, text, formatting);
13
+ replaceTextInParagraph({
14
+ paragraph,
15
+ startOffset: start.offset,
16
+ endOffset: end.offset,
17
+ text,
18
+ ...formatting && { formatting }
19
+ });
13
20
  } else {
14
21
  const startParagraph = getParagraphByIndex(body, start.paragraphIndex);
15
22
  if (!startParagraph) return newDoc;
16
- const startText = getParagraphText(startParagraph);
17
- startParagraph.content = deleteTextInParagraph(startParagraph, start.offset, startText.length);
18
- startParagraph.content = insertTextAtOffset(startParagraph, start.offset, text, formatting);
23
+ const startText = getFindParagraphText(startParagraph);
24
+ replaceTextInParagraph({
25
+ paragraph: startParagraph,
26
+ startOffset: start.offset,
27
+ endOffset: startText.length,
28
+ text,
29
+ ...formatting && { formatting }
30
+ });
19
31
  const paragraphsToRemove = [];
20
32
  for (let i = start.paragraphIndex + 1; i <= end.paragraphIndex; i++) paragraphsToRemove.push(getTopLevelParagraphBlockIndex(body, i));
21
33
  for (let i = paragraphsToRemove.length - 1; i >= 0; i--) {
@@ -57,107 +69,139 @@ function getParagraphByIndex(body, paragraphIndex) {
57
69
  };
58
70
  return walkBlocks(body.content);
59
71
  }
60
- function getParagraphText(paragraph) {
61
- let text = "";
62
- for (const item of paragraph.content) if (item.type === "run") {
63
- for (const c of item.content) if (c.type === "text") text += c.text;
64
- } else if (item.type === "hyperlink") for (const child of item.children) {
65
- if (child.type !== "run") continue;
66
- for (const c of child.content) if (c.type === "text") text += c.text;
67
- }
68
- return text;
69
- }
70
- function deleteTextInParagraph(paragraph, startOffset, endOffset) {
71
- const result = [];
72
- let currentOffset = 0;
73
- for (const item of paragraph.content) if (item.type === "run") {
74
- const newContent = [];
75
- for (const content of item.content) if (content.type === "text") {
76
- const textStart = currentOffset;
77
- const textEnd = currentOffset + content.text.length;
78
- if (textEnd <= startOffset || textStart >= endOffset) newContent.push(content);
79
- else {
80
- let newText = "";
81
- if (textStart < startOffset) newText += content.text.slice(0, startOffset - textStart);
82
- if (textEnd > endOffset) newText += content.text.slice(endOffset - textStart);
83
- if (newText) newContent.push({
84
- ...content,
85
- text: newText
86
- });
87
- }
88
- currentOffset = textEnd;
89
- } else newContent.push(content);
90
- if (newContent.length > 0) result.push({
91
- ...item,
92
- content: newContent
93
- });
94
- } else result.push(item);
95
- return result;
96
- }
97
- function insertTextAtOffset(paragraph, offset, text, formatting) {
98
- if (!text) return paragraph.content;
72
+ const itemTextLength = (item) => getFindParagraphText({
73
+ type: "paragraph",
74
+ content: [item]
75
+ }).length;
76
+ /** Walk authored offsets once, preserving wrappers and opaque source units. */
77
+ const replaceTextInParagraph = ({ paragraph, startOffset, endOffset, text, formatting }) => {
99
78
  let currentOffset = 0;
100
- for (const item of paragraph.content) if (item.type === "run") for (let ci = 0; ci < item.content.length; ci++) {
101
- const content = item.content[ci];
102
- if (content.type === "text") {
103
- const textStart = currentOffset;
104
- const textEnd = currentOffset + content.text.length;
105
- if (offset >= textStart && offset <= textEnd) {
106
- const relOffset = offset - textStart;
107
- if (formatting) {
108
- const before = content.text.slice(0, relOffset);
109
- const after = content.text.slice(relOffset);
110
- const newContent = [];
111
- if (before) newContent.push({
112
- type: "text",
113
- text: before
79
+ let inserted = false;
80
+ const visit = (items) => {
81
+ for (let itemIndex = 0; itemIndex < items.length; itemIndex++) {
82
+ const item = items.at(itemIndex);
83
+ if (!item) continue;
84
+ switch (item.type) {
85
+ case "run": {
86
+ const before = [];
87
+ const after = [];
88
+ let splitAtInsertion = false;
89
+ for (const unit of item.content) {
90
+ const unitStart = currentOffset;
91
+ const unitText = getFindParagraphText({
92
+ type: "paragraph",
93
+ content: [{
94
+ type: "run",
95
+ content: [unit]
96
+ }]
97
+ });
98
+ const unitLength = unitText.length;
99
+ const unitEnd = unitStart + unitLength;
100
+ currentOffset = unitEnd;
101
+ const output = splitAtInsertion ? after : before;
102
+ if (unit.type === "preservedXml" || unitLength === 0) {
103
+ output.push(unit);
104
+ continue;
105
+ }
106
+ const overlaps = unitEnd > startOffset && unitStart < endOffset;
107
+ if (!overlaps && !(!inserted && startOffset === endOffset && startOffset >= unitStart && startOffset <= unitEnd)) {
108
+ output.push(unit);
109
+ continue;
110
+ }
111
+ if (unit.type !== "text" && !overlaps) {
112
+ if (startOffset === unitEnd) output.push(unit);
113
+ inserted = true;
114
+ if (formatting) splitAtInsertion = true;
115
+ else if (text) output.push({
116
+ type: "text",
117
+ text
118
+ });
119
+ if (startOffset === unitStart) (splitAtInsertion ? after : before).push(unit);
120
+ continue;
121
+ }
122
+ const prefix = unitText.slice(0, Math.max(0, startOffset - unitStart));
123
+ const suffix = unitText.slice(Math.max(0, endOffset - unitStart));
124
+ if (prefix) output.push({
125
+ type: "text",
126
+ text: prefix
127
+ });
128
+ if (!inserted) {
129
+ inserted = true;
130
+ if (formatting) splitAtInsertion = true;
131
+ else if (text) output.push({
132
+ type: "text",
133
+ text
134
+ });
135
+ }
136
+ if (suffix) (splitAtInsertion ? after : before).push({
137
+ type: "text",
138
+ text: suffix
139
+ });
140
+ }
141
+ if (!splitAtInsertion) {
142
+ item.content = before;
143
+ break;
144
+ }
145
+ const replacement = [];
146
+ if (before.length > 0) replacement.push({
147
+ ...item,
148
+ content: before
114
149
  });
115
- const newRun = {
116
- type: "text",
117
- text
118
- };
119
- item.content.splice(ci, 1, ...newContent);
120
- const insertRun = {
150
+ if (text) replacement.push({
121
151
  type: "run",
122
- content: [newRun],
123
- formatting
124
- };
125
- const afterItems = [];
126
- if (after) afterItems.push({
127
- type: "text",
128
- text: after
152
+ content: [{
153
+ type: "text",
154
+ text
155
+ }],
156
+ ...formatting && { formatting }
129
157
  });
130
- const remaining = item.content.splice(ci + newContent.length);
131
- const afterRun = {
132
- type: "run",
133
- content: [...remaining, ...afterItems],
134
- ...item.formatting !== void 0 ? { formatting: item.formatting } : {}
135
- };
136
- const idx = paragraph.content.indexOf(item);
137
- paragraph.content.splice(idx + 1, 0, insertRun);
138
- if (afterItems.length > 0 || remaining.length > 0) paragraph.content.splice(idx + 2, 0, afterRun);
139
- return paragraph.content;
158
+ if (after.length > 0) replacement.push({
159
+ ...item,
160
+ content: after
161
+ });
162
+ items.splice(itemIndex, 1, ...replacement);
163
+ itemIndex += replacement.length - 1;
164
+ break;
140
165
  }
141
- content.text = content.text.slice(0, relOffset) + text + content.text.slice(relOffset);
142
- return paragraph.content;
166
+ case "hyperlink":
167
+ visit(item.children);
168
+ break;
169
+ case "inlineWrapper":
170
+ case "inlineSdt":
171
+ case "insertion":
172
+ case "deletion":
173
+ case "moveFrom":
174
+ case "moveTo":
175
+ visit(item.content);
176
+ break;
177
+ case "simpleField":
178
+ case "complexField":
179
+ case "preservedInline":
180
+ case "mathEquation":
181
+ case "bookmarkStart":
182
+ case "bookmarkEnd":
183
+ case "commentRangeStart":
184
+ case "commentRangeEnd":
185
+ case "commentReference":
186
+ case "moveFromRangeStart":
187
+ case "moveFromRangeEnd":
188
+ case "moveToRangeStart":
189
+ case "moveToRangeEnd":
190
+ currentOffset += itemTextLength(item);
191
+ break;
192
+ default: panic("Unsupported replacement paragraph content", { content: item });
143
193
  }
144
- currentOffset = textEnd;
145
194
  }
146
- }
147
- const lastRun = paragraph.content.findLast((item) => item.type === "run");
148
- if (lastRun) lastRun.content.push({
149
- type: "text",
150
- text
151
- });
152
- else paragraph.content.push({
195
+ };
196
+ visit(paragraph.content);
197
+ if (!inserted && startOffset === endOffset && startOffset === currentOffset && text) paragraph.content.push({
153
198
  type: "run",
154
199
  content: [{
155
200
  type: "text",
156
201
  text
157
202
  }],
158
- formatting: formatting ?? {}
203
+ ...formatting ? { formatting } : {}
159
204
  });
160
- return paragraph.content;
161
- }
205
+ };
162
206
  //#endregion
163
207
  export { replaceTextInDocument };
@@ -0,0 +1,2 @@
1
+ import { sliceText } from "@stll/utf8-boundaries";
2
+ export { sliceText };
@@ -0,0 +1,2 @@
1
+ import { sliceText } from "@stll/utf8-boundaries";
2
+ export { sliceText };
@@ -0,0 +1,2 @@
1
+ import { base64ToBytes, bytesToBase64, bytesToBase64Url, bytesToHex, createTextReader, decodeText, encodeBinaryString, encodeUtf16BE, encodeUtf16LE, encodeUtf8, readBlobText } from "@stll/utf8-boundaries";
2
+ export { base64ToBytes, bytesToBase64, bytesToBase64Url, bytesToHex, createTextReader, decodeText, encodeBinaryString, encodeUtf16BE, encodeUtf16LE, encodeUtf8, readBlobText };
@@ -0,0 +1,2 @@
1
+ import { base64ToBytes, bytesToBase64, bytesToBase64Url, bytesToHex, createTextReader, decodeText, encodeBinaryString, encodeUtf16BE, encodeUtf16LE, encodeUtf8, readBlobText } from "@stll/utf8-boundaries";
2
+ export { base64ToBytes, bytesToBase64, bytesToBase64Url, bytesToHex, createTextReader, decodeText, encodeBinaryString, encodeUtf16BE, encodeUtf16LE, encodeUtf8, readBlobText };
@@ -1,13 +1,4 @@
1
1
  //#region src/utils/tiffConverter.d.ts
2
- /**
3
- * TIFF to PNG Converter
4
- *
5
- * Browsers don't support TIFF in `<img>` tags, so DOCX-embedded TIFFs are
6
- * decoded with utif2 and re-encoded as PNG via the Canvas API. Returns
7
- * null in environments without Canvas (Node.js parsing); callers fall
8
- * back to the raw TIFF data URL, which won't render in browsers but is
9
- * fine for headless round-trips.
10
- */
11
2
  /**
12
3
  * Budget shared by every TIFF in one package. The per-image cap bounds a single
13
4
  * decode; without a running total a package of many large TIFFs still adds up.
@@ -1,3 +1,4 @@
1
+ import { base64ToBytes } from "./textEncoding.js";
1
2
  //#region src/utils/tiffConverter.ts
2
3
  /**
3
4
  * TIFF to PNG Converter
@@ -79,10 +80,7 @@ function dataUrlToArrayBuffer(dataUrl) {
79
80
  const base64 = dataUrl.split(",", 2)[1];
80
81
  if (!base64) return null;
81
82
  try {
82
- const binary = atob(base64);
83
- const bytes = new Uint8Array(binary.length);
84
- for (let i = 0; i < binary.length; i++) bytes[i] = binary.codePointAt(i) ?? 0;
85
- return bytes.buffer;
83
+ return base64ToBytes(base64).buffer;
86
84
  } catch {
87
85
  return null;
88
86
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@stll/folio-core",
3
- "version": "0.60.0",
3
+ "version": "0.62.0",
4
4
  "description": "Headless, framework-neutral core of folio: the OOXML (.docx) parser, document model, ProseMirror integration, and page-layout engine. No React.",
5
5
  "keywords": [
6
6
  "document-model",
@@ -36,98 +36,123 @@
36
36
  "exports": {
37
37
  ".": {
38
38
  "types": "./dist/index.d.ts",
39
- "import": "./dist/index.js"
39
+ "import": "./dist/index.js",
40
+ "default": "./dist/index.js"
40
41
  },
41
42
  "./i18n/messages/*": {
42
43
  "types": "./dist/i18n/messages/*.gen.d.ts",
43
- "import": "./dist/i18n/messages/*.gen.js"
44
+ "import": "./dist/i18n/messages/*.gen.js",
45
+ "default": "./dist/i18n/messages/*.gen.js"
44
46
  },
45
47
  "./i18n/messages/*.gen": {
46
48
  "types": "./dist/i18n/messages/*.gen.d.ts",
47
- "import": "./dist/i18n/messages/*.gen.js"
49
+ "import": "./dist/i18n/messages/*.gen.js",
50
+ "default": "./dist/i18n/messages/*.gen.js"
48
51
  },
49
52
  "./i18n/messages/locales": {
50
53
  "types": "./dist/i18n/messages/locales.d.ts",
51
- "import": "./dist/i18n/messages/locales.js"
54
+ "import": "./dist/i18n/messages/locales.js",
55
+ "default": "./dist/i18n/messages/locales.js"
52
56
  },
53
57
  "./markdown": {
54
58
  "types": "./dist/markdown/index.d.ts",
55
- "import": "./dist/markdown/index.js"
59
+ "import": "./dist/markdown/index.js",
60
+ "default": "./dist/markdown/index.js"
56
61
  },
57
62
  "./server": {
58
63
  "types": "./dist/server.d.ts",
59
- "import": "./dist/server.js"
64
+ "import": "./dist/server.js",
65
+ "default": "./dist/server.js"
60
66
  },
61
67
  "./redline": {
62
68
  "types": "./dist/redline.d.ts",
63
- "import": "./dist/redline.js"
69
+ "import": "./dist/redline.js",
70
+ "default": "./dist/redline.js"
64
71
  },
65
72
  "./ai-edits": {
66
73
  "types": "./dist/ai-edits/index.d.ts",
67
- "import": "./dist/ai-edits/index.js"
74
+ "import": "./dist/ai-edits/index.js",
75
+ "default": "./dist/ai-edits/index.js"
68
76
  },
69
77
  "./content-controls": {
70
78
  "types": "./dist/content-controls/index.d.ts",
71
- "import": "./dist/content-controls/index.js"
79
+ "import": "./dist/content-controls/index.js",
80
+ "default": "./dist/content-controls/index.js"
72
81
  },
73
82
  "./compat/eigenpal": {
74
83
  "types": "./dist/compat/eigenpal.d.ts",
75
- "import": "./dist/compat/eigenpal.js"
84
+ "import": "./dist/compat/eigenpal.js",
85
+ "default": "./dist/compat/eigenpal.js"
76
86
  },
77
87
  "./watermark": {
78
88
  "types": "./dist/watermark/index.d.ts",
79
- "import": "./dist/watermark/index.js"
89
+ "import": "./dist/watermark/index.js",
90
+ "default": "./dist/watermark/index.js"
80
91
  },
81
92
  "./layout-engine": {
82
93
  "types": "./dist/layout-engine/index.d.ts",
83
- "import": "./dist/layout-engine/index.js"
94
+ "import": "./dist/layout-engine/index.js",
95
+ "default": "./dist/layout-engine/index.js"
84
96
  },
85
97
  "./layout-painter": {
86
98
  "types": "./dist/layout-painter/index.d.ts",
87
- "import": "./dist/layout-painter/index.js"
99
+ "import": "./dist/layout-painter/index.js",
100
+ "default": "./dist/layout-painter/index.js"
88
101
  },
89
102
  "./layout-bridge/engine/measuring": {
90
103
  "types": "./dist/layout-bridge/engine/measuring/index.d.ts",
91
- "import": "./dist/layout-bridge/engine/measuring/index.js"
104
+ "import": "./dist/layout-bridge/engine/measuring/index.js",
105
+ "default": "./dist/layout-bridge/engine/measuring/index.js"
92
106
  },
93
107
  "./prosemirror": {
94
108
  "types": "./dist/prosemirror/index.d.ts",
95
- "import": "./dist/prosemirror/index.js"
109
+ "import": "./dist/prosemirror/index.js",
110
+ "default": "./dist/prosemirror/index.js"
96
111
  },
97
112
  "./prosemirror/attrs": {
98
113
  "types": "./dist/prosemirror/attrs/index.d.ts",
99
- "import": "./dist/prosemirror/attrs/index.js"
114
+ "import": "./dist/prosemirror/attrs/index.js",
115
+ "default": "./dist/prosemirror/attrs/index.js"
100
116
  },
101
117
  "./prosemirror/conversion": {
102
118
  "types": "./dist/prosemirror/conversion/index.d.ts",
103
- "import": "./dist/prosemirror/conversion/index.js"
119
+ "import": "./dist/prosemirror/conversion/index.js",
120
+ "default": "./dist/prosemirror/conversion/index.js"
104
121
  },
105
122
  "./prosemirror/extensions": {
106
123
  "types": "./dist/prosemirror/extensions/index.d.ts",
107
- "import": "./dist/prosemirror/extensions/index.js"
124
+ "import": "./dist/prosemirror/extensions/index.js",
125
+ "default": "./dist/prosemirror/extensions/index.js"
108
126
  },
109
127
  "./prosemirror/schema": {
110
128
  "types": "./dist/prosemirror/schema/index.d.ts",
111
- "import": "./dist/prosemirror/schema/index.js"
129
+ "import": "./dist/prosemirror/schema/index.js",
130
+ "default": "./dist/prosemirror/schema/index.js"
112
131
  },
113
132
  "./docx": {
114
133
  "types": "./dist/docx/index.d.ts",
115
- "import": "./dist/docx/index.js"
134
+ "import": "./dist/docx/index.js",
135
+ "default": "./dist/docx/index.js"
116
136
  },
117
137
  "./docx/document-clone": {
118
138
  "types": "./dist/docx/documentClone.d.ts",
119
- "import": "./dist/docx/documentClone.js"
139
+ "import": "./dist/docx/documentClone.js",
140
+ "default": "./dist/docx/documentClone.js"
120
141
  },
121
142
  "./text-shaping": {
122
143
  "types": "./dist/text-shaping.d.ts",
123
- "import": "./dist/text-shaping.js"
144
+ "import": "./dist/text-shaping.js",
145
+ "default": "./dist/text-shaping.js"
124
146
  },
125
147
  "./text-shaping/wasm": "./dist/generated/text_shaper_bg.wasm",
126
148
  "./docx/paragraphPropertySource": null,
127
149
  "./internal/*": null,
150
+ "./_virtual/*": null,
151
+ "./generated/*": null,
128
152
  "./*": {
129
153
  "types": "./dist/*.d.ts",
130
- "import": "./dist/*.js"
154
+ "import": "./dist/*.js",
155
+ "default": "./dist/*.js"
131
156
  }
132
157
  },
133
158
  "publishConfig": {
@@ -146,9 +171,10 @@
146
171
  "perf": "bun scripts/profile-editor.ts"
147
172
  },
148
173
  "dependencies": {
149
- "@stll/docx-core": "^0.37.0",
174
+ "@stll/docx-core": "^0.38.0",
150
175
  "@stll/docx-utils": "^0.1.0",
151
176
  "@stll/template-conditions": "^0.6.2",
177
+ "@stll/utf8-boundaries": "0.1.0",
152
178
  "better-result": "3.0.1",
153
179
  "csstype": "^3.1.3",
154
180
  "dompurify": "^3.4.16",