authorgravatar for git@paperclover.netclover caruso <git@paperclover.net> 2026-09-08 01:47:36-07:00
committergravatar for git@paperclover.netclover caruso <git@paperclover.net> 2026-09-08 01:47:36-07:00
log5f00c02e9903b23fca73277fcdd3b6aa4fe2ea5a
treead7b80476af6f3a55a5f51bb631b5d4e43f0acfe
parent7b15af16ba1b2e7f785f9346b9f39159a79ae44b
signature Signed by SSH key SHA256:52mNGHRsVFBDED9IAX5pe+LRWUefqTbxEReunq21QvU

feat: split ordinary paragraphs with stable identities

Publish text partitions, child transfer, list clones, tags and title metadata in one revision. Retain original left identities and history; reject generated fields and unsupported run metadata before I/O. Validated at every scalar boundary across twelve native cases, ordinary/checkpoint publication interruptions, 29,316 ASan executions, cold OneNote rendering and four subsequent native typing actions. The full public regression lane passes. Assisted-by: gpt-6-astra

87 files changed, 1889 insertions(+), 12 deletions(-)

corpus/paragraph-edit/README.md+10-2
......@@ -26,6 +26,14 @@ notebook before completing inspection. Cold-open the split notebook for the join
2626pass. Captured COM IDs belong to their originating sessions; discover fresh IDs
2727when regenerating the corpus.
2828
29`tools/test_paragraph_edit.py` verifies these native controls without a VM. They
30establish application behavior; they do not advertise a library split/join API.
29`rust-split` retains twelve `ParagraphSplit` outputs, their cold native captures,
30and a second native session typing into four empty boundary paragraphs. The
31hyperlink case stays unchanged because this operation rejects fields. The Rust
32test `export_native_paragraph_splits` generates candidate notebooks; its output
33directory comes from `ONESTORE_PARAGRAPH_OUTPUT`. Native character/style comparisons
34use both the keyboard-generated controls and the Rust-written notebooks. Empty
35typing checks extend the preexisting empty run in an independent expected model.
36
37`tools/test_paragraph_edit.py` verifies these controls without a VM. The native
38join captures establish behavior for subsequent join implementation.
3139Identical captured files link to one canonical copy within this corpus.
corpus/paragraph-edit/rust-split/candidate/synthetic.one created
Binary files /dev/null and b/corpus/paragraph-edit/rust-split/candidate/synthetic.one differ
corpus/paragraph-edit/rust-split/manifest.json created+352
......@@ -0,0 +1,352 @@
1{
2 "cases": [
3 {
4 "case": "Split middle",
5 "intent": {
6 "author": "Rust split author",
7 "created": 1473324660,
8 "guid": [
9 228,
10 60,
11 65,
12 246,
13 194,
14 244,
15 184,
16 76,
17 170,
18 5,
19 19,
20 130,
21 32,
22 122,
23 148,
24 241
25 ],
26 "offset": 2,
27 "text": "{DFE950EF-6BEB-0F5B-2403-7B74F1AE5002},44"
28 },
29 "new_paragraph": "{F6413CE4-F4C2-4CB8-AA05-1382207A94F1},1",
30 "new_text": "{F6413CE4-F4C2-4CB8-AA05-1382207A94F1},2"
31 },
32 {
33 "case": "Split style boundary",
34 "intent": {
35 "author": "Rust split author",
36 "created": 1473324660,
37 "guid": [
38 163,
39 91,
40 197,
41 73,
42 195,
43 225,
44 53,
45 68,
46 140,
47 152,
48 83,
49 168,
50 172,
51 124,
52 226,
53 213
54 ],
55 "offset": 4,
56 "text": "{5FB484E2-1E3E-0A9D-1989-271A3EBBEC42},44"
57 },
58 "new_paragraph": "{49C55BA3-E1C3-4435-8C98-53A8AC7CE2D5},1",
59 "new_text": "{49C55BA3-E1C3-4435-8C98-53A8AC7CE2D5},2"
60 },
61 {
62 "case": "Split start",
63 "intent": {
64 "author": "Rust split author",
65 "created": 1473324660,
66 "guid": [
67 135,
68 16,
69 214,
70 248,
71 73,
72 35,
73 2,
74 69,
75 148,
76 213,
77 125,
78 28,
79 43,
80 124,
81 81,
82 35
83 ],
84 "offset": 0,
85 "text": "{012ED94B-43B3-079A-3050-B1CBE25C1C09},44"
86 },
87 "new_paragraph": "{F8D61087-2349-4502-94D5-7D1C2B7C5123},1",
88 "new_text": "{F8D61087-2349-4502-94D5-7D1C2B7C5123},2"
89 },
90 {
91 "case": "Split end",
92 "intent": {
93 "author": "Rust split author",
94 "created": 1473324660,
95 "guid": [
96 37,
97 220,
98 149,
99 138,
100 85,
101 3,
102 106,
103 69,
104 168,
105 172,
106 49,
107 82,
108 247,
109 99,
110 160,
111 139
112 ],
113 "offset": 22,
114 "text": "{DAF723A3-C2A3-0798-2EAB-34613166A794},44"
115 },
116 "new_paragraph": "{8A95DC25-0355-456A-A8AC-3152F763A08B},1",
117 "new_text": "{8A95DC25-0355-456A-A8AC-3152F763A08B},2"
118 },
119 {
120 "case": "Split empty",
121 "intent": {
122 "author": "Rust split author",
123 "created": 1473324660,
124 "guid": [
125 232,
126 204,
127 91,
128 132,
129 180,
130 27,
131 239,
132 79,
133 158,
134 115,
135 213,
136 165,
137 40,
138 35,
139 189,
140 93
141 ],
142 "offset": 0,
143 "text": "{0B467F31-D287-08CD-09F4-A6FBB2F5418F},45"
144 },
145 "new_paragraph": "{845BCCE8-1BB4-4FEF-9E73-D5A52823BD5D},1",
146 "new_text": "{845BCCE8-1BB4-4FEF-9E73-D5A52823BD5D},2"
147 },
148 {
149 "case": "Split parent",
150 "intent": {
151 "author": "Rust split author",
152 "created": 1473324660,
153 "guid": [
154 54,
155 186,
156 114,
157 171,
158 44,
159 189,
160 95,
161 71,
162 135,
163 190,
164 71,
165 95,
166 23,
167 246,
168 37,
169 157
170 ],
171 "offset": 2,
172 "text": "{3860EA13-D444-0598-35D6-CF96769C6A21},44"
173 },
174 "new_paragraph": "{AB72BA36-BD2C-475F-87BE-475F17F6259D},1",
175 "new_text": "{AB72BA36-BD2C-475F-87BE-475F17F6259D},2"
176 },
177 {
178 "case": "Split child",
179 "intent": {
180 "author": "Rust split author",
181 "created": 1473324660,
182 "guid": [
183 160,
184 247,
185 235,
186 152,
187 30,
188 98,
189 166,
190 77,
191 157,
192 204,
193 141,
194 45,
195 114,
196 151,
197 225,
198 195
199 ],
200 "offset": 2,
201 "text": "{B587CBC6-0BCC-0A23-16F6-E1B0B3C5D061},49"
202 },
203 "new_paragraph": "{98EBF7A0-621E-4DA6-9DCC-8D2D7297E1C3},1",
204 "new_text": "{98EBF7A0-621E-4DA6-9DCC-8D2D7297E1C3},2"
205 },
206 {
207 "case": "Split bullet",
208 "intent": {
209 "author": "Rust split author",
210 "created": 1473324660,
211 "guid": [
212 53,
213 245,
214 214,
215 76,
216 159,
217 56,
218 134,
219 76,
220 178,
221 90,
222 131,
223 182,
224 74,
225 114,
226 31,
227 24
228 ],
229 "offset": 2,
230 "text": "{8C65E427-477C-02ED-1807-2F10E277019D},44"
231 },
232 "new_paragraph": "{4CD6F535-389F-4C86-B25A-83B64A721F18},1",
233 "new_text": "{4CD6F535-389F-4C86-B25A-83B64A721F18},2"
234 },
235 {
236 "case": "Split number",
237 "intent": {
238 "author": "Rust split author",
239 "created": 1473324661,
240 "guid": [
241 196,
242 133,
243 251,
244 251,
245 193,
246 175,
247 8,
248 65,
249 175,
250 180,
251 126,
252 16,
253 31,
254 185,
255 237,
256 66
257 ],
258 "offset": 2,
259 "text": "{D4ABBE4F-2165-0122-1F9F-ACE3FE92C703},44"
260 },
261 "new_paragraph": "{FBFB85C4-AFC1-4108-AFB4-7E101FB9ED42},1",
262 "new_text": "{FBFB85C4-AFC1-4108-AFB4-7E101FB9ED42},2"
263 },
264 {
265 "case": "Split tag",
266 "intent": {
267 "author": "Rust split author",
268 "created": 1473324661,
269 "guid": [
270 40,
271 122,
272 110,
273 77,
274 185,
275 255,
276 122,
277 69,
278 128,
279 15,
280 14,
281 166,
282 54,
283 156,
284 154,
285 91
286 ],
287 "offset": 2,
288 "text": "{37AA5877-2980-0227-169F-8B1E8EE0795A},44"
289 },
290 "new_paragraph": "{4D6E7A28-FFB9-457A-800F-0EA6369C9A5B},1",
291 "new_text": "{4D6E7A28-FFB9-457A-800F-0EA6369C9A5B},2"
292 },
293 {
294 "case": "Split cell",
295 "intent": {
296 "author": "Rust split author",
297 "created": 1473324661,
298 "guid": [
299 150,
300 222,
301 89,
302 134,
303 80,
304 167,
305 167,
306 67,
307 179,
308 23,
309 93,
310 176,
311 27,
312 184,
313 119,
314 185
315 ],
316 "offset": 2,
317 "text": "{F0832BC9-1578-0A96-08AF-99344644FFB8},50"
318 },
319 "new_paragraph": "{8659DE96-A750-43A7-B317-5DB01BB877B9},1",
320 "new_text": "{8659DE96-A750-43A7-B317-5DB01BB877B9},2"
321 },
322 {
323 "case": "Split soft break",
324 "intent": {
325 "author": "Rust split author",
326 "created": 1473324661,
327 "guid": [
328 199,
329 62,
330 94,
331 81,
332 29,
333 157,
334 236,
335 77,
336 159,
337 34,
338 22,
339 137,
340 163,
341 57,
342 215,
343 79
344 ],
345 "offset": 2,
346 "text": "{88189BA1-2F19-0282-05ED-A0B83153F143},44"
347 },
348 "new_paragraph": "{515E3EC7-9D1D-4DEC-9F22-1689A339D74F},1",
349 "new_text": "{515E3EC7-9D1D-4DEC-9F22-1689A339D74F},2"
350 }
351 ]
352}
corpus/paragraph-edit/rust-split/native/notebook/Open Notebook.onetoc2 created
Binary files /dev/null and b/corpus/paragraph-edit/rust-split/native/notebook/Open Notebook.onetoc2 differ
corpus/paragraph-edit/rust-split/native/notebook/synthetic.one created
Binary files /dev/null and b/corpus/paragraph-edit/rust-split/native/notebook/synthetic.one differ
corpus/paragraph-edit/rust-split/native/read/environment.json created+7
......@@ -0,0 +1,7 @@
1{
2 "powershell": "5.1.14409.1005",
3 "schema": "xs2010",
4 "hostname": "ONE-M6-AA441F91",
5 "cold": true,
6 "onenote": "14.0.4763.1000"
7}
corpus/paragraph-edit/rust-split/native/read/hierarchy.xml created+2
......@@ -0,0 +1,2 @@
1<?xml version="1.0"?>
2<one:Notebook xmlns:one="http://schemas.microsoft.com/office/onenote/2010/onenote" name="notebook" nickname="notebook" ID="{A5E609F0-7B8E-4650-8008-F78195DDC594}{1}{B0}" path="C:\one-tests\runs\capture\notebook" lastModifiedTime="2026-09-08T08:52:39.000Z" color="#B49EDE"><one:Section name="synthetic" ID="{3FA69981-21D0-0FBE-12CF-2BD2FC0B5E0C}{1}{B0}" path="C:\one-tests\runs\capture\notebook\synthetic.one" lastModifiedTime="2026-09-08T08:52:39.000Z" color="#8AA8E4"><one:Page ID="{13EF6A07-A81B-4CAF-95A8-834300334213}{1}{B0}" name="Bold 🦀 italic é color 東京" dateTime="2026-09-05T05:06:54.000Z" lastModifiedTime="2026-09-08T08:52:39.000Z" pageLevel="1"/><one:Page ID="{89D51190-5315-422F-A5E6-92B8A673E329}{1}{B0}" name="Split middle" dateTime="2026-09-08T08:09:29.000Z" lastModifiedTime="2026-09-08T08:52:39.000Z" pageLevel="1"/><one:Page ID="{A923DEF6-EBB3-4703-A0FE-029F6B7EEA4E}{1}{B0}" name="Split style boundary" dateTime="2026-09-08T08:09:32.000Z" lastModifiedTime="2026-09-08T08:52:39.000Z" pageLevel="1"/><one:Page ID="{0EEEBDC0-EE0B-40C9-BFC7-A9AA93C7916F}{1}{B0}" name="Split start" dateTime="2026-09-08T08:09:32.000Z" lastModifiedTime="2026-09-08T08:52:39.000Z" pageLevel="1"/><one:Page ID="{E5887CFA-F13E-437F-9F25-6B1A4169BE2C}{1}{B0}" name="Split end" dateTime="2026-09-08T08:09:32.000Z" lastModifiedTime="2026-09-08T08:52:39.000Z" pageLevel="1"/><one:Page ID="{932F903F-B689-44C3-9E5D-CE04DE3437CB}{1}{B0}" name="Split empty" dateTime="2026-09-08T08:09:33.000Z" lastModifiedTime="2026-09-08T08:52:39.000Z" pageLevel="1"/><one:Page ID="{0DC169BF-95C0-4AAF-A1A2-ED4A3D767051}{1}{B0}" name="Split parent" dateTime="2026-09-08T08:09:33.000Z" lastModifiedTime="2026-09-08T08:52:39.000Z" pageLevel="1"/><one:Page ID="{4B35902F-8318-47D8-87E8-3CE071853AC5}{1}{B0}" name="Split child" dateTime="2026-09-08T08:09:33.000Z" lastModifiedTime="2026-09-08T08:52:39.000Z" pageLevel="1"/><one:Page ID="{E3D9A117-19D3-4FF5-8B41-7F959E73BEB2}{1}{B0}" name="Split bullet" dateTime="2026-09-08T08:09:33.000Z" lastModifiedTime="2026-09-08T08:52:39.000Z" pageLevel="1"/><one:Page ID="{D359140C-3B82-4012-80C5-1C643EBAD29E}{1}{B0}" name="Split number" dateTime="2026-09-08T08:09:34.000Z" lastModifiedTime="2026-09-08T08:52:39.000Z" pageLevel="1"/><one:Page ID="{046AE778-A43B-4A6D-8EC1-45EE4AC75F37}{1}{B0}" name="Split tag" dateTime="2026-09-08T08:09:34.000Z" lastModifiedTime="2026-09-08T08:52:39.000Z" pageLevel="1"/><one:Page ID="{33C5B71F-B85D-4A15-899B-E21ED69D12E3}{1}{B0}" name="Split cell" dateTime="2026-09-08T08:09:34.000Z" lastModifiedTime="2026-09-08T08:52:39.000Z" pageLevel="1"/><one:Page ID="{AF160280-425C-4905-8189-7CDBD4C4E616}{1}{B0}" name="Split soft break" dateTime="2026-09-08T08:09:34.000Z" lastModifiedTime="2026-09-08T08:52:39.000Z" pageLevel="1"/><one:Page ID="{05360577-7E8B-474B-8EF6-8D6059015DA8}{1}{B0}" name="Split before hyperlink" dateTime="2026-09-08T08:09:34.000Z" lastModifiedTime="2026-09-08T08:52:39.000Z" pageLevel="1"/></one:Section></one:Notebook>
corpus/paragraph-edit/rust-split/native/read/page-000.xml created+6
......@@ -0,0 +1,6 @@
1<?xml version="1.0"?>
2<one:Page xmlns:one="http://schemas.microsoft.com/office/onenote/2010/onenote" ID="{046AE778-A43B-4A6D-8EC1-45EE4AC75F37}{1}{B0}" name="Split tag" dateTime="2026-09-08T08:09:34.000Z" lastModifiedTime="2026-09-08T08:52:39.000Z" pageLevel="1" lang="en-US"><one:TagDef index="0" type="0" symbol="3" fontColor="automatic" highlightColor="none" name="Fixture task"/><one:QuickStyleDef index="0" name="p" fontColor="automatic" highlightColor="automatic" font="Calibri" fontSize="11.0" spaceBefore="0.0" spaceAfter="0.0"/><one:PageSettings RTL="false" color="automatic"><one:PageSize><one:Automatic/></one:PageSize><one:RuleLines visible="false"/></one:PageSettings><one:Title lang="en-US"><one:OE author="virtual" authorInitials="V" lastModifiedBy="virtual" lastModifiedByInitials="V" creationTime="2026-09-08T08:09:34.000Z" lastModifiedTime="2026-09-08T08:09:34.000Z" objectID="{405D0C84-CF82-4236-BE0C-80A29906B055}{33}{B0}" alignment="left" quickStyleIndex="0" style="font-family:Calibri;font-size:17.0pt"><one:T><![CDATA[Split tag]]></one:T></one:OE></one:Title><one:Outline author="virtual" authorInitials="V" lastModifiedBy="Rust split author" lastModifiedTime="2026-09-08T08:51:01.000Z" objectID="{405D0C84-CF82-4236-BE0C-80A29906B055}{39}{B0}"><one:Position x="72.0" y="108.0" z="0"/><one:Size width="115.6704788208008" height="40.28315734863281"/><one:OEChildren><one:OE creationTime="2026-09-08T08:09:34.000Z" lastModifiedTime="2026-09-08T08:51:01.000Z" objectID="{405D0C84-CF82-4236-BE0C-80A29906B055}{40}{B0}" alignment="left" quickStyleIndex="0" style="font-family:Calibri;font-size:11.0pt"><one:Tag index="0" completed="true" disabled="false" creationDate="2020-01-02T03:04:05.000Z" completionDate="2020-01-02T04:05:06.000Z"/><one:T><![CDATA[<span
3style='font-weight:bold'>Bo</span>]]></one:T></one:OE><one:OE author="Rust split author" creationTime="2026-09-08T08:51:01.000Z" lastModifiedTime="2026-09-08T08:51:01.000Z" objectID="{3A992EDB-19BB-056B-289C-051A217A5354}{1}{B0}" alignment="left" quickStyleIndex="0"><one:T><![CDATA[<span
4style='font-weight:bold' lang=en-US>ld</span><span lang=en-US> </span><span
5style='font-style:italic' lang=en-US>italic</span><span lang=en-US> &#129408; é </span><span
6style='color:#123456' lang=x-none>tail</span>]]></one:T></one:OE><one:OE lastModifiedBy="virtual" lastModifiedByInitials="V" creationTime="2026-09-08T08:09:34.000Z" lastModifiedTime="2026-09-08T08:09:34.000Z" objectID="{405D0C84-CF82-4236-BE0C-80A29906B055}{49}{B0}" alignment="left" quickStyleIndex="0"><one:T><![CDATA[Preserved sibling]]></one:T></one:OE></one:OEChildren></one:Outline></one:Page>
corpus/paragraph-edit/rust-split/native/read/page-001.xml created+3
......@@ -0,0 +1,3 @@
1<?xml version="1.0"?>
2<one:Page xmlns:one="http://schemas.microsoft.com/office/onenote/2010/onenote" ID="{05360577-7E8B-474B-8EF6-8D6059015DA8}{1}{B0}" name="Split before hyperlink" dateTime="2026-09-08T08:09:34.000Z" lastModifiedTime="2026-09-08T08:52:39.000Z" pageLevel="1" lang="en-US"><one:QuickStyleDef index="0" name="p" fontColor="automatic" highlightColor="automatic" font="Calibri" fontSize="11.0" spaceBefore="0.0" spaceAfter="0.0"/><one:PageSettings RTL="false" color="automatic"><one:PageSize><one:Automatic/></one:PageSize><one:RuleLines visible="false"/></one:PageSettings><one:Title lang="en-US"><one:OE author="virtual" authorInitials="V" lastModifiedBy="virtual" lastModifiedByInitials="V" creationTime="2026-09-08T08:09:34.000Z" lastModifiedTime="2026-09-08T08:09:34.000Z" objectID="{23C44D14-BCC5-4A65-B879-325BBEAC1989}{33}{B0}" alignment="left" quickStyleIndex="0" style="font-family:Calibri;font-size:17.0pt"><one:T><![CDATA[Split before hyperlink]]></one:T></one:OE></one:Title><one:Outline author="virtual" authorInitials="V" lastModifiedBy="virtual" lastModifiedByInitials="V" lastModifiedTime="2026-09-08T08:09:37.000Z" objectID="{23C44D14-BCC5-4A65-B879-325BBEAC1989}{39}{B0}"><one:Position x="72.0" y="108.0" z="0"/><one:Size width="130.6343231201172" height="26.85543441772461"/><one:OEChildren><one:OE creationTime="2026-09-08T08:09:34.000Z" lastModifiedTime="2026-09-08T08:09:34.000Z" objectID="{23C44D14-BCC5-4A65-B879-325BBEAC1989}{40}{B0}" alignment="left" quickStyleIndex="0"><one:T><![CDATA[Before <a
3href="https://example.invalid/paragraph">Link label</a> tail]]></one:T></one:OE><one:OE creationTime="2026-09-08T08:09:34.000Z" lastModifiedTime="2026-09-08T08:09:34.000Z" objectID="{23C44D14-BCC5-4A65-B879-325BBEAC1989}{47}{B0}" alignment="left" quickStyleIndex="0"><one:T><![CDATA[Preserved sibling]]></one:T></one:OE></one:OEChildren></one:Outline></one:Page>
corpus/paragraph-edit/rust-split/native/read/page-002.xml created+6
......@@ -0,0 +1,6 @@
1<?xml version="1.0"?>
2<one:Page xmlns:one="http://schemas.microsoft.com/office/onenote/2010/onenote" ID="{0DC169BF-95C0-4AAF-A1A2-ED4A3D767051}{1}{B0}" name="Split parent" dateTime="2026-09-08T08:09:33.000Z" lastModifiedTime="2026-09-08T08:52:39.000Z" pageLevel="1" lang="en-US"><one:QuickStyleDef index="0" name="p" fontColor="automatic" highlightColor="automatic" font="Calibri" fontSize="11.0" spaceBefore="0.0" spaceAfter="0.0"/><one:PageSettings RTL="false" color="automatic"><one:PageSize><one:Automatic/></one:PageSize><one:RuleLines visible="false"/></one:PageSettings><one:Title lang="en-US"><one:OE author="virtual" authorInitials="V" lastModifiedBy="virtual" lastModifiedByInitials="V" creationTime="2026-09-08T08:09:33.000Z" lastModifiedTime="2026-09-08T08:09:33.000Z" objectID="{4F97BEE0-3246-4589-9D45-C42A617AA32E}{33}{B0}" alignment="left" quickStyleIndex="0" style="font-family:Calibri;font-size:17.0pt"><one:T><![CDATA[Split parent]]></one:T></one:OE></one:Title><one:Outline author="virtual" authorInitials="V" lastModifiedBy="Rust split author" lastModifiedTime="2026-09-08T08:51:00.000Z" objectID="{4F97BEE0-3246-4589-9D45-C42A617AA32E}{39}{B0}"><one:Position x="72.0" y="108.0" z="0"/><one:Size width="135.3173980712891" height="53.71086883544922"/><one:OEChildren><one:OE creationTime="2026-09-08T08:09:33.000Z" lastModifiedTime="2026-09-08T08:51:00.000Z" objectID="{4F97BEE0-3246-4589-9D45-C42A617AA32E}{40}{B0}" alignment="left" quickStyleIndex="0" style="font-family:Calibri;font-size:11.0pt"><one:T><![CDATA[<span
3style='font-weight:bold'>Bo</span>]]></one:T></one:OE><one:OE author="Rust split author" creationTime="2026-09-08T08:51:00.000Z" lastModifiedTime="2026-09-08T08:51:00.000Z" objectID="{DC85EEC5-5B2E-074E-2F2D-4CE30010EC92}{1}{B0}" alignment="left" quickStyleIndex="0"><one:T><![CDATA[<span
4style='font-weight:bold' lang=en-US>ld</span><span lang=en-US> </span><span
5style='font-style:italic' lang=en-US>italic</span><span lang=en-US> &#129408; é </span><span
6style='color:#123456' lang=x-none>tail</span>]]></one:T><one:OEChildren><one:OE lastModifiedBy="virtual" lastModifiedByInitials="V" creationTime="2026-09-08T08:09:33.000Z" lastModifiedTime="2026-09-08T08:09:33.000Z" objectID="{4F97BEE0-3246-4589-9D45-C42A617AA32E}{48}{B0}" alignment="left" quickStyleIndex="0"><one:T><![CDATA[Preserved child]]></one:T></one:OE></one:OEChildren></one:OE><one:OE lastModifiedBy="virtual" lastModifiedByInitials="V" creationTime="2026-09-08T08:09:33.000Z" lastModifiedTime="2026-09-08T08:09:33.000Z" objectID="{4F97BEE0-3246-4589-9D45-C42A617AA32E}{53}{B0}" alignment="left" quickStyleIndex="0"><one:T><![CDATA[Preserved sibling]]></one:T></one:OE></one:OEChildren></one:Outline></one:Page>
corpus/paragraph-edit/rust-split/native/read/page-003.xml created+5
......@@ -0,0 +1,5 @@
1<?xml version="1.0"?>
2<one:Page xmlns:one="http://schemas.microsoft.com/office/onenote/2010/onenote" ID="{0EEEBDC0-EE0B-40C9-BFC7-A9AA93C7916F}{1}{B0}" name="Split start" dateTime="2026-09-08T08:09:32.000Z" lastModifiedTime="2026-09-08T08:52:39.000Z" pageLevel="1" lang="en-US"><one:QuickStyleDef index="0" name="p" fontColor="automatic" highlightColor="automatic" font="Calibri" fontSize="11.0" spaceBefore="0.0" spaceAfter="0.0"/><one:PageSettings RTL="false" color="automatic"><one:PageSize><one:Automatic/></one:PageSize><one:RuleLines visible="false"/></one:PageSettings><one:Title lang="en-US"><one:OE author="virtual" authorInitials="V" lastModifiedBy="virtual" lastModifiedByInitials="V" creationTime="2026-09-08T08:09:32.000Z" lastModifiedTime="2026-09-08T08:09:32.000Z" objectID="{76D98DB8-A5B1-478B-98C3-BA77F5BAD506}{33}{B0}" alignment="left" quickStyleIndex="0" style="font-family:Calibri;font-size:17.0pt"><one:T><![CDATA[Split start]]></one:T></one:OE></one:Title><one:Outline author="virtual" authorInitials="V" lastModifiedBy="Rust split author" lastModifiedTime="2026-09-08T08:51:00.000Z" objectID="{76D98DB8-A5B1-478B-98C3-BA77F5BAD506}{39}{B0}"><one:Position x="72.0" y="108.0" z="0"/><one:Size width="116.921875" height="40.28315734863281"/><one:OEChildren><one:OE creationTime="2026-09-08T08:09:32.000Z" lastModifiedTime="2026-09-08T08:51:00.000Z" objectID="{76D98DB8-A5B1-478B-98C3-BA77F5BAD506}{40}{B0}" alignment="left" quickStyleIndex="0"><one:T><![CDATA[]]></one:T></one:OE><one:OE author="Rust split author" creationTime="2026-09-08T08:51:00.000Z" lastModifiedTime="2026-09-08T08:51:00.000Z" objectID="{8F214474-C54B-0513-3C46-76A03C9A982C}{1}{B0}" alignment="left" quickStyleIndex="0"><one:T><![CDATA[<span
3style='font-weight:bold' lang=en-US>Bold</span><span lang=en-US> </span><span
4style='font-style:italic' lang=en-US>italic</span><span lang=en-US> &#129408; é </span><span
5style='color:#123456' lang=x-none>tail</span>]]></one:T></one:OE><one:OE lastModifiedBy="virtual" lastModifiedByInitials="V" creationTime="2026-09-08T08:09:32.000Z" lastModifiedTime="2026-09-08T08:09:32.000Z" objectID="{76D98DB8-A5B1-478B-98C3-BA77F5BAD506}{48}{B0}" alignment="left" quickStyleIndex="0"><one:T><![CDATA[Preserved sibling]]></one:T></one:OE></one:OEChildren></one:Outline></one:Page>
corpus/paragraph-edit/rust-split/native/read/page-004.xml created+20
......@@ -0,0 +1,20 @@
1<?xml version="1.0"?>
2<one:Page xmlns:one="http://schemas.microsoft.com/office/onenote/2010/onenote" ID="{13EF6A07-A81B-4CAF-95A8-834300334213}{1}{B0}" name="Bold 🦀 italic é color 東京" dateTime="2026-09-05T05:06:54.000Z" lastModifiedTime="2026-09-08T08:52:39.000Z" pageLevel="1" lang="en-US"><one:QuickStyleDef index="0" name="p" fontColor="automatic" highlightColor="automatic" font="Calibri" fontSize="11.0" spaceBefore="0.0" spaceAfter="0.0"/><one:PageSettings RTL="false" color="automatic"><one:PageSize><one:Automatic/></one:PageSize><one:RuleLines visible="false"/></one:PageSettings><one:Outline author="Rich author" lastModifiedBy="Rich author" lastModifiedTime="2026-09-08T04:47:24.000Z" objectID="{7423C2BB-E36E-4F19-9A5A-0F98FFAFA772}{10}{B0}"><one:Position x="36.0" y="14.40000057220459" z="0"/><one:Size width="127.5136947631836" height="42.90299224853515"/><one:OEChildren><one:OE creationTime="2026-09-08T04:47:24.000Z" lastModifiedTime="2026-09-08T04:47:24.000Z" objectID="{73466A4C-1013-0413-2A0E-CC9234C4D584}{1}{B0}" alignment="left"><one:T><![CDATA[<span style='font-weight:bold;
3text-decoration:underline;font-family:Calibri;font-size:11.0pt'>Bold</span><span
4style='font-family:Calibri;font-size:11.0pt'> </span><span style='font-family:
5Arial;font-size:13.5pt'>&#129408;</span><span style='font-family:Calibri;
6font-size:11.0pt'> </span><span style='font-style:italic;text-decoration:line-through;
7font-family:Calibri;font-size:11.0pt'>italic</span><span style='font-family:
8Calibri;font-size:11.0pt'> </span><span style='vertical-align:super;font-family:
9Calibri;font-size:11.0pt'>é</span><span style='font-family:Calibri;font-size:
1011.0pt'> </span><span style='font-family:Calibri;font-size:11.0pt;color:#0C2238;
11background:yellow;mso-highlight:yellow'>color</span><span style='font-family:
12Calibri;font-size:11.0pt'> </span><span style='vertical-align:sub;font-family:
13Calibri;font-size:11.0pt'>東京</span><span style='font-family:Calibri;font-size:
1411.0pt'><br>
15End</span>]]></one:T></one:OE><one:OE author="snow" authorInitials="S" lastModifiedBy="snow" lastModifiedByInitials="S" creationTime="2026-09-05T05:06:55.000Z" lastModifiedTime="2026-09-05T05:06:56.000Z" objectID="{7423C2BB-E36E-4F19-9A5A-0F98FFAFA772}{11}{B0}" alignment="left" quickStyleIndex="0" style="font-size:11.0pt;color:#1F4E79"><one:T><![CDATA[<span
16style='font-weight:bold;font-family:Calibri' lang=en-US>Fictitious: café, </span><span
17style='font-weight:bold;font-family:SimSun' lang=en-US>東京</span><span
18style='font-weight:bold;font-family:Calibri' lang=en-US>, </span><span
19style='font-weight:bold;font-family:Arial;direction:rtl;unicode-bidi:embed'
20lang=ar-SA>مرحبا</span>]]></one:T></one:OE></one:OEChildren></one:Outline></one:Page>
corpus/paragraph-edit/rust-split/native/read/page-005.xml created+6
......@@ -0,0 +1,6 @@
1<?xml version="1.0"?>
2<one:Page xmlns:one="http://schemas.microsoft.com/office/onenote/2010/onenote" ID="{33C5B71F-B85D-4A15-899B-E21ED69D12E3}{1}{B0}" name="Split cell" dateTime="2026-09-08T08:09:34.000Z" lastModifiedTime="2026-09-08T08:52:39.000Z" pageLevel="1" lang="en-US"><one:QuickStyleDef index="0" name="p" fontColor="automatic" highlightColor="automatic" font="Calibri" fontSize="11.0" spaceBefore="0.0" spaceAfter="0.0"/><one:PageSettings RTL="false" color="automatic"><one:PageSize><one:Automatic/></one:PageSize><one:RuleLines visible="false"/></one:PageSettings><one:Title lang="en-US"><one:OE author="virtual" authorInitials="V" lastModifiedBy="virtual" lastModifiedByInitials="V" creationTime="2026-09-08T08:09:34.000Z" lastModifiedTime="2026-09-08T08:09:34.000Z" objectID="{87747F3A-F37A-4A87-A03C-928851A236B7}{33}{B0}" alignment="left" quickStyleIndex="0" style="font-family:Calibri;font-size:17.0pt"><one:T><![CDATA[Split cell]]></one:T></one:OE></one:Title><one:Outline author="virtual" authorInitials="V" lastModifiedBy="virtual" lastModifiedByInitials="V" lastModifiedTime="2026-09-08T08:51:01.000Z" objectID="{87747F3A-F37A-4A87-A03C-928851A236B7}{39}{B0}"><one:Position x="72.0" y="108.0" z="0"/><one:Size width="254.9588165283203" height="48.80315780639648"/><one:OEChildren><one:OE creationTime="2026-09-08T08:09:34.000Z" lastModifiedTime="2026-09-08T08:51:01.000Z" objectID="{87747F3A-F37A-4A87-A03C-928851A236B7}{40}{B0}" alignment="left"><one:Table bordersVisible="true" lastModifiedTime="2026-09-08T08:51:01.000Z" objectID="{87747F3A-F37A-4A87-A03C-928851A236B7}{41}{B0}"><one:Columns><one:Column index="0" width="180.0" isLocked="true"/><one:Column index="1" width="66.82881927490234"/></one:Columns><one:Row objectID="{87747F3A-F37A-4A87-A03C-928851A236B7}{42}{B0}" lastModifiedTime="2026-09-08T08:51:01.000Z"><one:Cell lastModifiedTime="2026-09-08T08:51:01.000Z" objectID="{87747F3A-F37A-4A87-A03C-928851A236B7}{43}{B0}"><one:OEChildren><one:OE creationTime="2026-09-08T08:09:34.000Z" lastModifiedTime="2026-09-08T08:51:01.000Z" objectID="{87747F3A-F37A-4A87-A03C-928851A236B7}{46}{B0}" alignment="left" quickStyleIndex="0" style="font-family:Calibri;font-size:11.0pt"><one:T><![CDATA[<span
3style='font-weight:bold'>Bo</span>]]></one:T></one:OE><one:OE author="Rust split author" creationTime="2026-09-08T08:51:01.000Z" lastModifiedTime="2026-09-08T08:51:01.000Z" objectID="{F1AE8A65-4152-03B6-1B84-560C0C5EBEB6}{1}{B0}" alignment="left" quickStyleIndex="0"><one:T><![CDATA[<span
4style='font-weight:bold' lang=en-US>ld</span><span lang=en-US> </span><span
5style='font-style:italic' lang=en-US>italic</span><span lang=en-US> &#129408; é </span><span
6style='color:#123456' lang=x-none>tail</span>]]></one:T></one:OE></one:OEChildren></one:Cell><one:Cell lastModifiedTime="2026-09-08T08:09:37.000Z" objectID="{87747F3A-F37A-4A87-A03C-928851A236B7}{54}{B0}" lastModifiedBy="virtual" lastModifiedByInitials="V"><one:OEChildren><one:OE creationTime="2026-09-08T08:09:34.000Z" lastModifiedTime="2026-09-08T08:09:34.000Z" objectID="{87747F3A-F37A-4A87-A03C-928851A236B7}{57}{B0}" alignment="left" quickStyleIndex="0"><one:T><![CDATA[Preserved cell]]></one:T></one:OE></one:OEChildren></one:Cell></one:Row></one:Table></one:OE><one:OE creationTime="2026-09-08T08:09:34.000Z" lastModifiedTime="2026-09-08T08:09:34.000Z" objectID="{87747F3A-F37A-4A87-A03C-928851A236B7}{62}{B0}" alignment="left" quickStyleIndex="0"><one:T><![CDATA[Preserved sibling]]></one:T></one:OE></one:OEChildren></one:Outline></one:Page>
corpus/paragraph-edit/rust-split/native/read/page-006.xml created+6
......@@ -0,0 +1,6 @@
1<?xml version="1.0"?>
2<one:Page xmlns:one="http://schemas.microsoft.com/office/onenote/2010/onenote" ID="{4B35902F-8318-47D8-87E8-3CE071853AC5}{1}{B0}" name="Split child" dateTime="2026-09-08T08:09:33.000Z" lastModifiedTime="2026-09-08T08:52:39.000Z" pageLevel="1" lang="en-US"><one:QuickStyleDef index="0" name="p" fontColor="automatic" highlightColor="automatic" font="Calibri" fontSize="11.0" spaceBefore="0.0" spaceAfter="0.0"/><one:PageSettings RTL="false" color="automatic"><one:PageSize><one:Automatic/></one:PageSize><one:RuleLines visible="false"/></one:PageSettings><one:Title lang="en-US"><one:OE author="virtual" authorInitials="V" lastModifiedBy="virtual" lastModifiedByInitials="V" creationTime="2026-09-08T08:09:33.000Z" lastModifiedTime="2026-09-08T08:09:33.000Z" objectID="{C2709F35-EDCE-4A32-BE65-EA0CA423196E}{33}{B0}" alignment="left" quickStyleIndex="0" style="font-family:Calibri;font-size:17.0pt"><one:T><![CDATA[Split child]]></one:T></one:OE></one:Title><one:Outline author="virtual" authorInitials="V" lastModifiedBy="virtual" lastModifiedByInitials="V" lastModifiedTime="2026-09-08T08:51:00.000Z" objectID="{C2709F35-EDCE-4A32-BE65-EA0CA423196E}{39}{B0}"><one:Position x="72.0" y="108.0" z="0"/><one:Size width="131.8423614501953" height="53.71086883544922"/><one:OEChildren><one:OE creationTime="2026-09-08T08:09:33.000Z" lastModifiedTime="2026-09-08T08:51:00.000Z" objectID="{C2709F35-EDCE-4A32-BE65-EA0CA423196E}{40}{B0}" alignment="left" quickStyleIndex="0"><one:T><![CDATA[Preserved parent]]></one:T><one:OEChildren><one:OE lastModifiedBy="Rust split author" creationTime="2026-09-08T08:09:33.000Z" lastModifiedTime="2026-09-08T08:51:00.000Z" objectID="{C2709F35-EDCE-4A32-BE65-EA0CA423196E}{45}{B0}" alignment="left" quickStyleIndex="0" style="font-family:Calibri;font-size:11.0pt"><one:T><![CDATA[<span
3style='font-weight:bold'>Bo</span>]]></one:T></one:OE><one:OE author="Rust split author" lastModifiedBy="Rust split author" creationTime="2026-09-08T08:51:00.000Z" lastModifiedTime="2026-09-08T08:51:00.000Z" objectID="{EF1CA353-841C-0DB7-355F-8691657128CC}{1}{B0}" alignment="left" quickStyleIndex="0"><one:T><![CDATA[<span
4style='font-weight:bold' lang=en-US>ld</span><span lang=en-US> </span><span
5style='font-style:italic' lang=en-US>italic</span><span lang=en-US> &#129408; é </span><span
6style='color:#123456' lang=x-none>tail</span>]]></one:T></one:OE></one:OEChildren></one:OE><one:OE creationTime="2026-09-08T08:09:33.000Z" lastModifiedTime="2026-09-08T08:09:33.000Z" objectID="{C2709F35-EDCE-4A32-BE65-EA0CA423196E}{53}{B0}" alignment="left" quickStyleIndex="0"><one:T><![CDATA[Preserved sibling]]></one:T></one:OE></one:OEChildren></one:Outline></one:Page>
corpus/paragraph-edit/rust-split/native/read/page-007.xml created+6
......@@ -0,0 +1,6 @@
1<?xml version="1.0"?>
2<one:Page xmlns:one="http://schemas.microsoft.com/office/onenote/2010/onenote" ID="{89D51190-5315-422F-A5E6-92B8A673E329}{1}{B0}" name="Split middle" dateTime="2026-09-08T08:09:29.000Z" lastModifiedTime="2026-09-08T08:52:39.000Z" pageLevel="1" lang="en-US"><one:QuickStyleDef index="0" name="p" fontColor="automatic" highlightColor="automatic" font="Calibri" fontSize="11.0" spaceBefore="0.0" spaceAfter="0.0"/><one:PageSettings RTL="false" color="automatic"><one:PageSize><one:Automatic/></one:PageSize><one:RuleLines visible="false"/></one:PageSettings><one:Title lang="en-US"><one:OE author="virtual" authorInitials="V" lastModifiedBy="virtual" lastModifiedByInitials="V" creationTime="2026-09-08T08:09:32.000Z" lastModifiedTime="2026-09-08T08:09:32.000Z" objectID="{A81E041C-8DE9-4F4A-8C90-70C8E648990D}{33}{B0}" alignment="left" quickStyleIndex="0" style="font-family:Calibri;font-size:17.0pt"><one:T><![CDATA[Split middle]]></one:T></one:OE></one:Title><one:Outline author="virtual" authorInitials="V" lastModifiedBy="Rust split author" lastModifiedTime="2026-09-08T08:51:00.000Z" objectID="{A81E041C-8DE9-4F4A-8C90-70C8E648990D}{39}{B0}"><one:Position x="72.0" y="108.0" z="0"/><one:Size width="115.6704635620117" height="40.28315734863281"/><one:OEChildren><one:OE creationTime="2026-09-08T08:09:30.000Z" lastModifiedTime="2026-09-08T08:51:00.000Z" objectID="{A81E041C-8DE9-4F4A-8C90-70C8E648990D}{40}{B0}" alignment="left" quickStyleIndex="0" style="font-family:Calibri;font-size:11.0pt"><one:T><![CDATA[<span
3style='font-weight:bold'>Bo</span>]]></one:T></one:OE><one:OE author="Rust split author" creationTime="2026-09-08T08:51:00.000Z" lastModifiedTime="2026-09-08T08:51:00.000Z" objectID="{81B66817-12C0-0CA9-0296-183E379C5DFE}{1}{B0}" alignment="left" quickStyleIndex="0"><one:T><![CDATA[<span
4style='font-weight:bold' lang=en-US>ld</span><span lang=en-US> </span><span
5style='font-style:italic' lang=en-US>italic</span><span lang=en-US> &#129408; é </span><span
6style='color:#123456' lang=x-none>tail</span>]]></one:T></one:OE><one:OE lastModifiedBy="virtual" lastModifiedByInitials="V" creationTime="2026-09-08T08:09:32.000Z" lastModifiedTime="2026-09-08T08:09:32.000Z" objectID="{A81E041C-8DE9-4F4A-8C90-70C8E648990D}{48}{B0}" alignment="left" quickStyleIndex="0"><one:T><![CDATA[Preserved sibling]]></one:T></one:OE></one:OEChildren></one:Outline></one:Page>
corpus/paragraph-edit/rust-split/native/read/page-008.xml created+2
......@@ -0,0 +1,2 @@
1<?xml version="1.0"?>
2<one:Page xmlns:one="http://schemas.microsoft.com/office/onenote/2010/onenote" ID="{932F903F-B689-44C3-9E5D-CE04DE3437CB}{1}{B0}" name="Split empty" dateTime="2026-09-08T08:09:33.000Z" lastModifiedTime="2026-09-08T08:52:39.000Z" pageLevel="1" lang="en-US"><one:QuickStyleDef index="0" name="p" fontColor="automatic" highlightColor="automatic" font="Calibri" fontSize="11.0" spaceBefore="0.0" spaceAfter="0.0"/><one:PageSettings RTL="false" color="automatic"><one:PageSize><one:Automatic/></one:PageSize><one:RuleLines visible="false"/></one:PageSettings><one:Title lang="en-US"><one:OE author="virtual" authorInitials="V" lastModifiedBy="virtual" lastModifiedByInitials="V" creationTime="2026-09-08T08:09:33.000Z" lastModifiedTime="2026-09-08T08:09:33.000Z" objectID="{7CB12BC2-3485-48DC-A167-AD47A5138880}{33}{B0}" alignment="left" quickStyleIndex="0" style="font-family:Calibri;font-size:17.0pt"><one:T><![CDATA[Split empty]]></one:T></one:OE></one:Title><one:Outline author="virtual" authorInitials="V" lastModifiedBy="Rust split author" lastModifiedTime="2026-09-08T08:51:00.000Z" objectID="{7CB12BC2-3485-48DC-A167-AD47A5138880}{39}{B0}"><one:Position x="72.0" y="108.0" z="0"/><one:Size width="115.6704635620117" height="40.28315734863281"/><one:OEChildren><one:OE creationTime="2026-09-08T08:09:33.000Z" lastModifiedTime="2026-09-08T08:51:00.000Z" objectID="{7CB12BC2-3485-48DC-A167-AD47A5138880}{40}{B0}" alignment="left" quickStyleIndex="0"><one:T><![CDATA[]]></one:T></one:OE><one:OE author="Rust split author" creationTime="2026-09-08T08:51:00.000Z" lastModifiedTime="2026-09-08T08:51:00.000Z" objectID="{F3AC981B-FDB6-0FFE-36E0-DE193FC57452}{1}{B0}" alignment="left" quickStyleIndex="0"><one:T><![CDATA[]]></one:T></one:OE><one:OE lastModifiedBy="virtual" lastModifiedByInitials="V" creationTime="2026-09-08T08:09:33.000Z" lastModifiedTime="2026-09-08T08:09:33.000Z" objectID="{7CB12BC2-3485-48DC-A167-AD47A5138880}{46}{B0}" alignment="left" quickStyleIndex="0"><one:T><![CDATA[Preserved sibling]]></one:T></one:OE></one:OEChildren></one:Outline></one:Page>
corpus/paragraph-edit/rust-split/native/read/page-009.xml created+5
......@@ -0,0 +1,5 @@
1<?xml version="1.0"?>
2<one:Page xmlns:one="http://schemas.microsoft.com/office/onenote/2010/onenote" ID="{A923DEF6-EBB3-4703-A0FE-029F6B7EEA4E}{1}{B0}" name="Split style boundary" dateTime="2026-09-08T08:09:32.000Z" lastModifiedTime="2026-09-08T08:52:39.000Z" pageLevel="1" lang="en-US"><one:QuickStyleDef index="0" name="p" fontColor="automatic" highlightColor="automatic" font="Calibri" fontSize="11.0" spaceBefore="0.0" spaceAfter="0.0"/><one:PageSettings RTL="false" color="automatic"><one:PageSize><one:Automatic/></one:PageSize><one:RuleLines visible="false"/></one:PageSettings><one:Title lang="en-US"><one:OE author="virtual" authorInitials="V" lastModifiedBy="virtual" lastModifiedByInitials="V" creationTime="2026-09-08T08:09:32.000Z" lastModifiedTime="2026-09-08T08:09:32.000Z" objectID="{2843D011-F83C-4A8C-B11A-2CA6295D254D}{33}{B0}" alignment="left" quickStyleIndex="0" style="font-family:Calibri;font-size:17.0pt"><one:T><![CDATA[Split style boundary]]></one:T></one:OE></one:Title><one:Outline author="virtual" authorInitials="V" lastModifiedBy="Rust split author" lastModifiedTime="2026-09-08T08:51:00.000Z" objectID="{2843D011-F83C-4A8C-B11A-2CA6295D254D}{39}{B0}"><one:Position x="72.0" y="108.0" z="0"/><one:Size width="115.6704635620117" height="40.28315734863281"/><one:OEChildren><one:OE creationTime="2026-09-08T08:09:32.000Z" lastModifiedTime="2026-09-08T08:51:00.000Z" objectID="{2843D011-F83C-4A8C-B11A-2CA6295D254D}{40}{B0}" alignment="left" quickStyleIndex="0" style="font-family:Calibri;font-size:11.0pt"><one:T><![CDATA[<span
3style='font-weight:bold'>Bold</span>]]></one:T></one:OE><one:OE author="Rust split author" creationTime="2026-09-08T08:51:00.000Z" lastModifiedTime="2026-09-08T08:51:00.000Z" objectID="{3E320F50-07C1-0424-240B-5814BB9A2BDA}{1}{B0}" alignment="left" quickStyleIndex="0"><one:T><![CDATA[<span
4lang=en-US> </span><span style='font-style:italic' lang=en-US>italic</span><span
5lang=en-US> &#129408; é </span><span style='color:#123456' lang=x-none>tail</span>]]></one:T></one:OE><one:OE lastModifiedBy="virtual" lastModifiedByInitials="V" creationTime="2026-09-08T08:09:32.000Z" lastModifiedTime="2026-09-08T08:09:32.000Z" objectID="{2843D011-F83C-4A8C-B11A-2CA6295D254D}{48}{B0}" alignment="left" quickStyleIndex="0"><one:T><![CDATA[Preserved sibling]]></one:T></one:OE></one:OEChildren></one:Outline></one:Page>
corpus/paragraph-edit/rust-split/native/read/page-010.xml created+3
......@@ -0,0 +1,3 @@
1<?xml version="1.0"?>
2<one:Page xmlns:one="http://schemas.microsoft.com/office/onenote/2010/onenote" ID="{AF160280-425C-4905-8189-7CDBD4C4E616}{1}{B0}" name="Split soft break" dateTime="2026-09-08T08:09:34.000Z" lastModifiedTime="2026-09-08T08:52:39.000Z" pageLevel="1" lang="en-US"><one:QuickStyleDef index="0" name="p" fontColor="automatic" highlightColor="automatic" font="Calibri" fontSize="11.0" spaceBefore="0.0" spaceAfter="0.0"/><one:PageSettings RTL="false" color="automatic"><one:PageSize><one:Automatic/></one:PageSize><one:RuleLines visible="false"/></one:PageSettings><one:Title lang="en-US"><one:OE author="virtual" authorInitials="V" lastModifiedBy="virtual" lastModifiedByInitials="V" creationTime="2026-09-08T08:09:34.000Z" lastModifiedTime="2026-09-08T08:09:34.000Z" objectID="{FFEFCF52-C91B-4293-AD7E-AB0426B5384C}{33}{B0}" alignment="left" quickStyleIndex="0" style="font-family:Calibri;font-size:17.0pt"><one:T><![CDATA[Split soft break]]></one:T></one:OE></one:Title><one:Outline author="virtual" authorInitials="V" lastModifiedBy="Rust split author" lastModifiedTime="2026-09-08T08:51:01.000Z" objectID="{FFEFCF52-C91B-4293-AD7E-AB0426B5384C}{39}{B0}"><one:Position x="72.0" y="108.0" z="0"/><one:Size width="468.0" height="53.71086883544922"/><one:OEChildren><one:OE creationTime="2026-09-08T08:09:34.000Z" lastModifiedTime="2026-09-08T08:51:01.000Z" objectID="{FFEFCF52-C91B-4293-AD7E-AB0426B5384C}{40}{B0}" alignment="left" quickStyleIndex="0"><one:T><![CDATA[Bo]]></one:T></one:OE><one:OE author="Rust split author" creationTime="2026-09-08T08:51:01.000Z" lastModifiedTime="2026-09-08T08:51:01.000Z" objectID="{26A96A34-7B1F-0DFD-37B1-1D35B4DF1E40}{1}{B0}" alignment="left" quickStyleIndex="0"><one:T><![CDATA[ld<br>
3soft break]]></one:T></one:OE><one:OE lastModifiedBy="virtual" lastModifiedByInitials="V" creationTime="2026-09-08T08:09:34.000Z" lastModifiedTime="2026-09-08T08:09:34.000Z" objectID="{FFEFCF52-C91B-4293-AD7E-AB0426B5384C}{45}{B0}" alignment="left" quickStyleIndex="0"><one:T><![CDATA[Preserved sibling]]></one:T></one:OE></one:OEChildren></one:Outline></one:Page>
corpus/paragraph-edit/rust-split/native/read/page-011.xml created+6
......@@ -0,0 +1,6 @@
1<?xml version="1.0"?>
2<one:Page xmlns:one="http://schemas.microsoft.com/office/onenote/2010/onenote" ID="{D359140C-3B82-4012-80C5-1C643EBAD29E}{1}{B0}" name="Split number" dateTime="2026-09-08T08:09:34.000Z" lastModifiedTime="2026-09-08T08:52:39.000Z" pageLevel="1" lang="en-US"><one:QuickStyleDef index="0" name="p" fontColor="automatic" highlightColor="automatic" font="Calibri" fontSize="11.0" spaceBefore="0.0" spaceAfter="0.0"/><one:PageSettings RTL="false" color="automatic"><one:PageSize><one:Automatic/></one:PageSize><one:RuleLines visible="false"/></one:PageSettings><one:Title lang="en-US"><one:OE author="virtual" authorInitials="V" lastModifiedBy="virtual" lastModifiedByInitials="V" creationTime="2026-09-08T08:09:34.000Z" lastModifiedTime="2026-09-08T08:09:34.000Z" objectID="{A35CEABC-C767-4133-B70C-A75FE9740E0C}{33}{B0}" alignment="left" quickStyleIndex="0" style="font-family:Calibri;font-size:17.0pt"><one:T><![CDATA[Split number]]></one:T></one:OE></one:Title><one:Outline author="virtual" authorInitials="V" lastModifiedBy="Rust split author" lastModifiedTime="2026-09-08T08:51:01.000Z" objectID="{A35CEABC-C767-4133-B70C-A75FE9740E0C}{39}{B0}"><one:Position x="72.0" y="108.0" z="0"/><one:Size width="115.6704635620117" height="40.28315734863281"/><one:OEChildren><one:OE creationTime="2026-09-08T08:09:34.000Z" lastModifiedTime="2026-09-08T08:51:01.000Z" objectID="{A35CEABC-C767-4133-B70C-A75FE9740E0C}{40}{B0}" alignment="left" quickStyleIndex="0" style="font-family:Calibri;font-size:11.0pt"><one:List><one:Number numberSequence="1" numberFormat="##." restartNumberingAt="3" fontSize="11.0" font="Calibri" text="III."/></one:List><one:T><![CDATA[<span
3style='font-weight:bold'>Bo</span>]]></one:T></one:OE><one:OE author="Rust split author" creationTime="2026-09-08T08:51:01.000Z" lastModifiedTime="2026-09-08T08:51:01.000Z" objectID="{8C0CD137-49C3-0119-0727-75AC085F244D}{1}{B0}" alignment="left" quickStyleIndex="0"><one:List><one:Number numberSequence="1" numberFormat="##." fontSize="11.0" font="Calibri" text="IV."/></one:List><one:T><![CDATA[<span
4style='font-weight:bold' lang=en-US>ld</span><span lang=en-US> </span><span
5style='font-style:italic' lang=en-US>italic</span><span lang=en-US> &#129408; é </span><span
6style='color:#123456' lang=x-none>tail</span>]]></one:T></one:OE><one:OE lastModifiedBy="virtual" lastModifiedByInitials="V" creationTime="2026-09-08T08:09:34.000Z" lastModifiedTime="2026-09-08T08:09:34.000Z" objectID="{A35CEABC-C767-4133-B70C-A75FE9740E0C}{49}{B0}" alignment="left" quickStyleIndex="0"><one:T><![CDATA[Preserved sibling]]></one:T></one:OE></one:OEChildren></one:Outline></one:Page>
corpus/paragraph-edit/rust-split/native/read/page-012.xml created+6
......@@ -0,0 +1,6 @@
1<?xml version="1.0"?>
2<one:Page xmlns:one="http://schemas.microsoft.com/office/onenote/2010/onenote" ID="{E3D9A117-19D3-4FF5-8B41-7F959E73BEB2}{1}{B0}" name="Split bullet" dateTime="2026-09-08T08:09:33.000Z" lastModifiedTime="2026-09-08T08:52:39.000Z" pageLevel="1" lang="en-US"><one:QuickStyleDef index="0" name="p" fontColor="automatic" highlightColor="automatic" font="Calibri" fontSize="11.0" spaceBefore="0.0" spaceAfter="0.0"/><one:PageSettings RTL="false" color="automatic"><one:PageSize><one:Automatic/></one:PageSize><one:RuleLines visible="false"/></one:PageSettings><one:Title lang="en-US"><one:OE author="virtual" authorInitials="V" lastModifiedBy="virtual" lastModifiedByInitials="V" creationTime="2026-09-08T08:09:33.000Z" lastModifiedTime="2026-09-08T08:09:33.000Z" objectID="{FB92B0D4-A17E-42FC-B094-24ACF591C892}{33}{B0}" alignment="left" quickStyleIndex="0" style="font-family:Calibri;font-size:17.0pt"><one:T><![CDATA[Split bullet]]></one:T></one:OE></one:Title><one:Outline author="virtual" authorInitials="V" lastModifiedBy="Rust split author" lastModifiedTime="2026-09-08T08:51:00.000Z" objectID="{FB92B0D4-A17E-42FC-B094-24ACF591C892}{39}{B0}"><one:Position x="72.0" y="108.0" z="0"/><one:Size width="135.3173980712891" height="53.71086883544922"/><one:OEChildren><one:OE creationTime="2026-09-08T08:09:33.000Z" lastModifiedTime="2026-09-08T08:51:00.000Z" objectID="{FB92B0D4-A17E-42FC-B094-24ACF591C892}{40}{B0}" alignment="left" quickStyleIndex="0" style="font-family:Calibri;font-size:11.0pt"><one:List><one:Bullet bullet="3" fontSize="11.0"/></one:List><one:T><![CDATA[<span
3style='font-weight:bold'>Bo</span>]]></one:T></one:OE><one:OE author="Rust split author" creationTime="2026-09-08T08:51:00.000Z" lastModifiedTime="2026-09-08T08:51:00.000Z" objectID="{3B21A1C6-DE9D-0C97-1AC9-880A5D94D617}{1}{B0}" alignment="left" quickStyleIndex="0"><one:List><one:Bullet bullet="3" fontSize="11.0"/></one:List><one:T><![CDATA[<span
4style='font-weight:bold' lang=en-US>ld</span><span lang=en-US> </span><span
5style='font-style:italic' lang=en-US>italic</span><span lang=en-US> &#129408; é </span><span
6style='color:#123456' lang=x-none>tail</span>]]></one:T><one:OEChildren><one:OE lastModifiedBy="virtual" lastModifiedByInitials="V" creationTime="2026-09-08T08:09:33.000Z" lastModifiedTime="2026-09-08T08:09:33.000Z" objectID="{FB92B0D4-A17E-42FC-B094-24ACF591C892}{48}{B0}" alignment="left" quickStyleIndex="0"><one:T><![CDATA[Preserved child]]></one:T></one:OE></one:OEChildren></one:OE><one:OE lastModifiedBy="virtual" lastModifiedByInitials="V" creationTime="2026-09-08T08:09:33.000Z" lastModifiedTime="2026-09-08T08:09:33.000Z" objectID="{FB92B0D4-A17E-42FC-B094-24ACF591C892}{54}{B0}" alignment="left" quickStyleIndex="0"><one:T><![CDATA[Preserved sibling]]></one:T></one:OE></one:OEChildren></one:Outline></one:Page>
corpus/paragraph-edit/rust-split/native/read/page-013.xml created+5
......@@ -0,0 +1,5 @@
1<?xml version="1.0"?>
2<one:Page xmlns:one="http://schemas.microsoft.com/office/onenote/2010/onenote" ID="{E5887CFA-F13E-437F-9F25-6B1A4169BE2C}{1}{B0}" name="Split end" dateTime="2026-09-08T08:09:32.000Z" lastModifiedTime="2026-09-08T08:52:39.000Z" pageLevel="1" lang="en-US"><one:QuickStyleDef index="0" name="p" fontColor="automatic" highlightColor="automatic" font="Calibri" fontSize="11.0" spaceBefore="0.0" spaceAfter="0.0"/><one:PageSettings RTL="false" color="automatic"><one:PageSize><one:Automatic/></one:PageSize><one:RuleLines visible="false"/></one:PageSettings><one:Title lang="en-US"><one:OE author="virtual" authorInitials="V" lastModifiedBy="virtual" lastModifiedByInitials="V" creationTime="2026-09-08T08:09:33.000Z" lastModifiedTime="2026-09-08T08:09:33.000Z" objectID="{AD007750-24A1-4789-8638-3FDD26806E9B}{33}{B0}" alignment="left" quickStyleIndex="0" style="font-family:Calibri;font-size:17.0pt"><one:T><![CDATA[Split end]]></one:T></one:OE></one:Title><one:Outline author="virtual" authorInitials="V" lastModifiedBy="Rust split author" lastModifiedTime="2026-09-08T08:51:00.000Z" objectID="{AD007750-24A1-4789-8638-3FDD26806E9B}{39}{B0}"><one:Position x="72.0" y="108.0" z="0"/><one:Size width="116.921875" height="40.28315734863281"/><one:OEChildren><one:OE creationTime="2026-09-08T08:09:33.000Z" lastModifiedTime="2026-09-08T08:51:00.000Z" objectID="{AD007750-24A1-4789-8638-3FDD26806E9B}{40}{B0}" alignment="left" quickStyleIndex="0"><one:T><![CDATA[<span
3style='font-weight:bold' lang=en-US>Bold</span><span lang=en-US> </span><span
4style='font-style:italic' lang=en-US>italic</span><span lang=en-US> &#129408; é </span><span
5style='color:#123456' lang=x-none>tail</span>]]></one:T></one:OE><one:OE author="Rust split author" creationTime="2026-09-08T08:51:00.000Z" lastModifiedTime="2026-09-08T08:51:00.000Z" objectID="{FD6288D6-E557-057B-003F-3AEEE0856984}{1}{B0}" alignment="left" quickStyleIndex="0" style="font-family:Calibri;font-size:11.0pt;color:#123456"><one:T><![CDATA[]]></one:T></one:OE><one:OE lastModifiedBy="virtual" lastModifiedByInitials="V" creationTime="2026-09-08T08:09:33.000Z" lastModifiedTime="2026-09-08T08:09:33.000Z" objectID="{AD007750-24A1-4789-8638-3FDD26806E9B}{48}{B0}" alignment="left" quickStyleIndex="0"><one:T><![CDATA[Preserved sibling]]></one:T></one:OE></one:OEChildren></one:Outline></one:Page>
corpus/paragraph-edit/rust-split/native/read/payloads.json created+1
......@@ -0,0 +1 @@
1../../../before/read/payloads.json
\ No newline at end of file
corpus/paragraph-edit/rust-split/native/run.json created+18
......@@ -0,0 +1,18 @@
1{
2 "notebook": "/Users/clo/dev/one/evidence/m10/paragraph-rust-split-01/candidate",
3 "expected_pages": 14,
4 "author": null,
5 "author_timeout_seconds": 600,
6 "inspect": false,
7 "collect_notebook": true,
8 "base": {
9 "file": "win7-office-base.qcow2",
10 "format": "qcow2",
11 "sha256": "a1a4f8fab782ee14885ff801ca2f6347c208fdcfc3513637096f314315c89346",
12 "virtual_size": 68719476736
13 },
14 "scripts": {
15 "cold.ps1": "c177fc72ae6c2634d186f5671a880de20b09f9716532c37c69cb13aa15c7e331",
16 "read.ps1": "04013bfcccee40a17e2a225f9b9e96f40a3a8daad9e350609654f8eda3ccbb41"
17 }
18}
corpus/paragraph-edit/rust-split/native/source.json created+8
......@@ -0,0 +1,8 @@
1[
2 {
3 "path": "synthetic.one",
4 "bytes": 110224,
5 "sha256": "c07cf1d31c658534b7cd3c6f77dd48dd52a1b9be4ef037b3d016b24336a4c3f4",
6 "mtime_ns": 1788857461138239881
7 }
8]
corpus/paragraph-edit/rust-split/native/teardown.json created+1
......@@ -0,0 +1 @@
1../../joined/teardown.json
\ No newline at end of file
corpus/paragraph-edit/rust-split/typed/before-read/environment.json created+7
......@@ -0,0 +1,7 @@
1{
2 "powershell": "5.1.14409.1005",
3 "schema": "xs2010",
4 "hostname": "ONE-M6-02D586B5",
5 "cold": true,
6 "onenote": "14.0.4763.1000"
7}
corpus/paragraph-edit/rust-split/typed/before-read/hierarchy.xml created+2
......@@ -0,0 +1,2 @@
1<?xml version="1.0"?>
2<one:Notebook xmlns:one="http://schemas.microsoft.com/office/onenote/2010/onenote" name="notebook" nickname="notebook" ID="{5F2547AA-6079-422C-929F-ACD159424C5F}{1}{B0}" path="C:\one-tests\runs\capture\notebook" lastModifiedTime="2026-09-08T08:57:31.000Z" color="#B49EDE"><one:Section name="synthetic" ID="{34C60088-AAFA-0664-3D80-161C07A5288F}{1}{B0}" path="C:\one-tests\runs\capture\notebook\synthetic.one" lastModifiedTime="2026-09-08T08:57:31.000Z" color="#8AA8E4"><one:Page ID="{188FF30E-2331-4575-BAE7-BE8DFB9D3490}{1}{B0}" name="Bold 🦀 italic é color 東京" dateTime="2026-09-05T05:06:54.000Z" lastModifiedTime="2026-09-08T08:57:31.000Z" pageLevel="1"/><one:Page ID="{82B58899-D83F-4BF5-8AA9-AF765DDD95AA}{1}{B0}" name="Split middle" dateTime="2026-09-08T08:09:29.000Z" lastModifiedTime="2026-09-08T08:57:31.000Z" pageLevel="1"/><one:Page ID="{A24347FF-6099-4ED9-8FB1-3F5190D09CCD}{1}{B0}" name="Split style boundary" dateTime="2026-09-08T08:09:32.000Z" lastModifiedTime="2026-09-08T08:57:31.000Z" pageLevel="1"/><one:Page ID="{058E24C9-6521-4913-9088-94646869E7EC}{1}{B0}" name="Split start" dateTime="2026-09-08T08:09:32.000Z" lastModifiedTime="2026-09-08T08:57:31.000Z" pageLevel="1"/><one:Page ID="{EEE8E5F3-7A14-4AA5-B06A-56D4BAC7C8AF}{1}{B0}" name="Split end" dateTime="2026-09-08T08:09:32.000Z" lastModifiedTime="2026-09-08T08:57:31.000Z" pageLevel="1"/><one:Page ID="{984F0936-3DA3-4D19-B112-F3CA259A4148}{1}{B0}" name="Split empty" dateTime="2026-09-08T08:09:33.000Z" lastModifiedTime="2026-09-08T08:57:31.000Z" pageLevel="1"/><one:Page ID="{06A1F0B6-1EEA-4375-8EED-D084C6D806D2}{1}{B0}" name="Split parent" dateTime="2026-09-08T08:09:33.000Z" lastModifiedTime="2026-09-08T08:57:31.000Z" pageLevel="1"/><one:Page ID="{40550926-0832-4E02-A8A7-012E8A2B4C46}{1}{B0}" name="Split child" dateTime="2026-09-08T08:09:33.000Z" lastModifiedTime="2026-09-08T08:57:31.000Z" pageLevel="1"/><one:Page ID="{E8B9381E-92F9-462F-A40E-425B65DDC831}{1}{B0}" name="Split bullet" dateTime="2026-09-08T08:09:33.000Z" lastModifiedTime="2026-09-08T08:57:31.000Z" pageLevel="1"/><one:Page ID="{D8398D05-B0A8-49C8-AF8A-21AAC514A41D}{1}{B0}" name="Split number" dateTime="2026-09-08T08:09:34.000Z" lastModifiedTime="2026-09-08T08:57:31.000Z" pageLevel="1"/><one:Page ID="{0F0A7E71-2F11-43B7-A18E-7820B16929B4}{1}{B0}" name="Split tag" dateTime="2026-09-08T08:09:34.000Z" lastModifiedTime="2026-09-08T08:57:31.000Z" pageLevel="1"/><one:Page ID="{38A52E16-3377-43CF-A6D4-DFD02D336460}{1}{B0}" name="Split cell" dateTime="2026-09-08T08:09:34.000Z" lastModifiedTime="2026-09-08T08:57:31.000Z" pageLevel="1"/><one:Page ID="{A4769B89-C976-40DF-AEC6-41152F6A9095}{1}{B0}" name="Split soft break" dateTime="2026-09-08T08:09:34.000Z" lastModifiedTime="2026-09-08T08:57:31.000Z" pageLevel="1"/><one:Page ID="{0E569C7E-F5A1-4E91-A1B9-B0AEA2AF2B2B}{1}{B0}" name="Split before hyperlink" dateTime="2026-09-08T08:09:34.000Z" lastModifiedTime="2026-09-08T08:57:31.000Z" pageLevel="1"/></one:Section></one:Notebook>
corpus/paragraph-edit/rust-split/typed/before-read/page-000.xml created+5
......@@ -0,0 +1,5 @@
1<?xml version="1.0"?>
2<one:Page xmlns:one="http://schemas.microsoft.com/office/onenote/2010/onenote" ID="{058E24C9-6521-4913-9088-94646869E7EC}{1}{B0}" name="Split start" dateTime="2026-09-08T08:09:32.000Z" lastModifiedTime="2026-09-08T08:57:31.000Z" pageLevel="1" lang="en-US"><one:QuickStyleDef index="0" name="p" fontColor="automatic" highlightColor="automatic" font="Calibri" fontSize="11.0" spaceBefore="0.0" spaceAfter="0.0"/><one:PageSettings RTL="false" color="automatic"><one:PageSize><one:Automatic/></one:PageSize><one:RuleLines visible="false"/></one:PageSettings><one:Title lang="en-US"><one:OE author="virtual" authorInitials="V" lastModifiedBy="virtual" lastModifiedByInitials="V" creationTime="2026-09-08T08:09:32.000Z" lastModifiedTime="2026-09-08T08:09:32.000Z" objectID="{7DB914B1-2E9B-4E51-B78C-87B90E14A385}{33}{B0}" alignment="left" quickStyleIndex="0" style="font-family:Calibri;font-size:17.0pt"><one:T><![CDATA[Split start]]></one:T></one:OE></one:Title><one:Outline author="virtual" authorInitials="V" lastModifiedBy="Rust split author" lastModifiedTime="2026-09-08T08:51:00.000Z" objectID="{7DB914B1-2E9B-4E51-B78C-87B90E14A385}{39}{B0}"><one:Position x="72.0" y="108.0" z="0"/><one:Size width="116.921875" height="40.28315734863281"/><one:OEChildren><one:OE creationTime="2026-09-08T08:09:32.000Z" lastModifiedTime="2026-09-08T08:51:00.000Z" objectID="{7DB914B1-2E9B-4E51-B78C-87B90E14A385}{40}{B0}" alignment="left" quickStyleIndex="0"><one:T><![CDATA[]]></one:T></one:OE><one:OE author="Rust split author" creationTime="2026-09-08T08:51:00.000Z" lastModifiedTime="2026-09-08T08:51:00.000Z" objectID="{8441DD7D-4E61-0CC9-1309-4B6EC734EEAF}{1}{B0}" alignment="left" quickStyleIndex="0"><one:T><![CDATA[<span
3style='font-weight:bold' lang=en-US>Bold</span><span lang=en-US> </span><span
4style='font-style:italic' lang=en-US>italic</span><span lang=en-US> &#129408; é </span><span
5style='color:#123456' lang=x-none>tail</span>]]></one:T></one:OE><one:OE lastModifiedBy="virtual" lastModifiedByInitials="V" creationTime="2026-09-08T08:09:32.000Z" lastModifiedTime="2026-09-08T08:09:32.000Z" objectID="{7DB914B1-2E9B-4E51-B78C-87B90E14A385}{48}{B0}" alignment="left" quickStyleIndex="0"><one:T><![CDATA[Preserved sibling]]></one:T></one:OE></one:OEChildren></one:Outline></one:Page>
corpus/paragraph-edit/rust-split/typed/before-read/page-001.xml created+6
......@@ -0,0 +1,6 @@
1<?xml version="1.0"?>
2<one:Page xmlns:one="http://schemas.microsoft.com/office/onenote/2010/onenote" ID="{06A1F0B6-1EEA-4375-8EED-D084C6D806D2}{1}{B0}" name="Split parent" dateTime="2026-09-08T08:09:33.000Z" lastModifiedTime="2026-09-08T08:57:31.000Z" pageLevel="1" lang="en-US"><one:QuickStyleDef index="0" name="p" fontColor="automatic" highlightColor="automatic" font="Calibri" fontSize="11.0" spaceBefore="0.0" spaceAfter="0.0"/><one:PageSettings RTL="false" color="automatic"><one:PageSize><one:Automatic/></one:PageSize><one:RuleLines visible="false"/></one:PageSettings><one:Title lang="en-US"><one:OE author="virtual" authorInitials="V" lastModifiedBy="virtual" lastModifiedByInitials="V" creationTime="2026-09-08T08:09:33.000Z" lastModifiedTime="2026-09-08T08:09:33.000Z" objectID="{44F727E9-B96C-4C53-B20A-F9E49AD4D5AD}{33}{B0}" alignment="left" quickStyleIndex="0" style="font-family:Calibri;font-size:17.0pt"><one:T><![CDATA[Split parent]]></one:T></one:OE></one:Title><one:Outline author="virtual" authorInitials="V" lastModifiedBy="Rust split author" lastModifiedTime="2026-09-08T08:51:00.000Z" objectID="{44F727E9-B96C-4C53-B20A-F9E49AD4D5AD}{39}{B0}"><one:Position x="72.0" y="108.0" z="0"/><one:Size width="135.3173980712891" height="53.71086883544922"/><one:OEChildren><one:OE creationTime="2026-09-08T08:09:33.000Z" lastModifiedTime="2026-09-08T08:51:00.000Z" objectID="{44F727E9-B96C-4C53-B20A-F9E49AD4D5AD}{40}{B0}" alignment="left" quickStyleIndex="0" style="font-family:Calibri;font-size:11.0pt"><one:T><![CDATA[<span
3style='font-weight:bold'>Bo</span>]]></one:T></one:OE><one:OE author="Rust split author" creationTime="2026-09-08T08:51:00.000Z" lastModifiedTime="2026-09-08T08:51:00.000Z" objectID="{D7E577CC-D004-0E94-0062-712DFBBE9A11}{1}{B0}" alignment="left" quickStyleIndex="0"><one:T><![CDATA[<span
4style='font-weight:bold' lang=en-US>ld</span><span lang=en-US> </span><span
5style='font-style:italic' lang=en-US>italic</span><span lang=en-US> &#129408; é </span><span
6style='color:#123456' lang=x-none>tail</span>]]></one:T><one:OEChildren><one:OE lastModifiedBy="virtual" lastModifiedByInitials="V" creationTime="2026-09-08T08:09:33.000Z" lastModifiedTime="2026-09-08T08:09:33.000Z" objectID="{44F727E9-B96C-4C53-B20A-F9E49AD4D5AD}{48}{B0}" alignment="left" quickStyleIndex="0"><one:T><![CDATA[Preserved child]]></one:T></one:OE></one:OEChildren></one:OE><one:OE lastModifiedBy="virtual" lastModifiedByInitials="V" creationTime="2026-09-08T08:09:33.000Z" lastModifiedTime="2026-09-08T08:09:33.000Z" objectID="{44F727E9-B96C-4C53-B20A-F9E49AD4D5AD}{53}{B0}" alignment="left" quickStyleIndex="0"><one:T><![CDATA[Preserved sibling]]></one:T></one:OE></one:OEChildren></one:Outline></one:Page>
corpus/paragraph-edit/rust-split/typed/before-read/page-002.xml created+3
......@@ -0,0 +1,3 @@
1<?xml version="1.0"?>
2<one:Page xmlns:one="http://schemas.microsoft.com/office/onenote/2010/onenote" ID="{0E569C7E-F5A1-4E91-A1B9-B0AEA2AF2B2B}{1}{B0}" name="Split before hyperlink" dateTime="2026-09-08T08:09:34.000Z" lastModifiedTime="2026-09-08T08:57:31.000Z" pageLevel="1" lang="en-US"><one:QuickStyleDef index="0" name="p" fontColor="automatic" highlightColor="automatic" font="Calibri" fontSize="11.0" spaceBefore="0.0" spaceAfter="0.0"/><one:PageSettings RTL="false" color="automatic"><one:PageSize><one:Automatic/></one:PageSize><one:RuleLines visible="false"/></one:PageSettings><one:Title lang="en-US"><one:OE author="virtual" authorInitials="V" lastModifiedBy="virtual" lastModifiedByInitials="V" creationTime="2026-09-08T08:09:34.000Z" lastModifiedTime="2026-09-08T08:09:34.000Z" objectID="{28A4D41D-37EF-43BF-9736-0F9545026F0A}{33}{B0}" alignment="left" quickStyleIndex="0" style="font-family:Calibri;font-size:17.0pt"><one:T><![CDATA[Split before hyperlink]]></one:T></one:OE></one:Title><one:Outline author="virtual" authorInitials="V" lastModifiedBy="virtual" lastModifiedByInitials="V" lastModifiedTime="2026-09-08T08:09:37.000Z" objectID="{28A4D41D-37EF-43BF-9736-0F9545026F0A}{39}{B0}"><one:Position x="72.0" y="108.0" z="0"/><one:Size width="130.6343231201172" height="26.85543441772461"/><one:OEChildren><one:OE creationTime="2026-09-08T08:09:34.000Z" lastModifiedTime="2026-09-08T08:09:34.000Z" objectID="{28A4D41D-37EF-43BF-9736-0F9545026F0A}{40}{B0}" alignment="left" quickStyleIndex="0"><one:T><![CDATA[Before <a
3href="https://example.invalid/paragraph">Link label</a> tail]]></one:T></one:OE><one:OE creationTime="2026-09-08T08:09:34.000Z" lastModifiedTime="2026-09-08T08:09:34.000Z" objectID="{28A4D41D-37EF-43BF-9736-0F9545026F0A}{47}{B0}" alignment="left" quickStyleIndex="0"><one:T><![CDATA[Preserved sibling]]></one:T></one:OE></one:OEChildren></one:Outline></one:Page>
corpus/paragraph-edit/rust-split/typed/before-read/page-003.xml created+6
......@@ -0,0 +1,6 @@
1<?xml version="1.0"?>
2<one:Page xmlns:one="http://schemas.microsoft.com/office/onenote/2010/onenote" ID="{0F0A7E71-2F11-43B7-A18E-7820B16929B4}{1}{B0}" name="Split tag" dateTime="2026-09-08T08:09:34.000Z" lastModifiedTime="2026-09-08T08:57:31.000Z" pageLevel="1" lang="en-US"><one:TagDef index="0" type="0" symbol="3" fontColor="automatic" highlightColor="none" name="Fixture task"/><one:QuickStyleDef index="0" name="p" fontColor="automatic" highlightColor="automatic" font="Calibri" fontSize="11.0" spaceBefore="0.0" spaceAfter="0.0"/><one:PageSettings RTL="false" color="automatic"><one:PageSize><one:Automatic/></one:PageSize><one:RuleLines visible="false"/></one:PageSettings><one:Title lang="en-US"><one:OE author="virtual" authorInitials="V" lastModifiedBy="virtual" lastModifiedByInitials="V" creationTime="2026-09-08T08:09:34.000Z" lastModifiedTime="2026-09-08T08:09:34.000Z" objectID="{4B3D958D-44A8-4BEC-9143-BD6C62A8C6D6}{33}{B0}" alignment="left" quickStyleIndex="0" style="font-family:Calibri;font-size:17.0pt"><one:T><![CDATA[Split tag]]></one:T></one:OE></one:Title><one:Outline author="virtual" authorInitials="V" lastModifiedBy="Rust split author" lastModifiedTime="2026-09-08T08:51:01.000Z" objectID="{4B3D958D-44A8-4BEC-9143-BD6C62A8C6D6}{39}{B0}"><one:Position x="72.0" y="108.0" z="0"/><one:Size width="115.6704788208008" height="40.28315734863281"/><one:OEChildren><one:OE creationTime="2026-09-08T08:09:34.000Z" lastModifiedTime="2026-09-08T08:51:01.000Z" objectID="{4B3D958D-44A8-4BEC-9143-BD6C62A8C6D6}{40}{B0}" alignment="left" quickStyleIndex="0" style="font-family:Calibri;font-size:11.0pt"><one:Tag index="0" completed="true" disabled="false" creationDate="2020-01-02T03:04:05.000Z" completionDate="2020-01-02T04:05:06.000Z"/><one:T><![CDATA[<span
3style='font-weight:bold'>Bo</span>]]></one:T></one:OE><one:OE author="Rust split author" creationTime="2026-09-08T08:51:01.000Z" lastModifiedTime="2026-09-08T08:51:01.000Z" objectID="{31F9B7D2-9291-0CB1-07D3-38D4DAD425D7}{1}{B0}" alignment="left" quickStyleIndex="0"><one:T><![CDATA[<span
4style='font-weight:bold' lang=en-US>ld</span><span lang=en-US> </span><span
5style='font-style:italic' lang=en-US>italic</span><span lang=en-US> &#129408; é </span><span
6style='color:#123456' lang=x-none>tail</span>]]></one:T></one:OE><one:OE lastModifiedBy="virtual" lastModifiedByInitials="V" creationTime="2026-09-08T08:09:34.000Z" lastModifiedTime="2026-09-08T08:09:34.000Z" objectID="{4B3D958D-44A8-4BEC-9143-BD6C62A8C6D6}{49}{B0}" alignment="left" quickStyleIndex="0"><one:T><![CDATA[Preserved sibling]]></one:T></one:OE></one:OEChildren></one:Outline></one:Page>
corpus/paragraph-edit/rust-split/typed/before-read/page-004.xml created+20
......@@ -0,0 +1,20 @@
1<?xml version="1.0"?>
2<one:Page xmlns:one="http://schemas.microsoft.com/office/onenote/2010/onenote" ID="{188FF30E-2331-4575-BAE7-BE8DFB9D3490}{1}{B0}" name="Bold 🦀 italic é color 東京" dateTime="2026-09-05T05:06:54.000Z" lastModifiedTime="2026-09-08T08:57:31.000Z" pageLevel="1" lang="en-US"><one:QuickStyleDef index="0" name="p" fontColor="automatic" highlightColor="automatic" font="Calibri" fontSize="11.0" spaceBefore="0.0" spaceAfter="0.0"/><one:PageSettings RTL="false" color="automatic"><one:PageSize><one:Automatic/></one:PageSize><one:RuleLines visible="false"/></one:PageSettings><one:Outline author="Rich author" lastModifiedBy="Rich author" lastModifiedTime="2026-09-08T04:47:24.000Z" objectID="{7F435BB2-6844-46C3-B515-32560401D1F1}{10}{B0}"><one:Position x="36.0" y="14.40000057220459" z="0"/><one:Size width="127.5136947631836" height="42.90299224853515"/><one:OEChildren><one:OE creationTime="2026-09-08T04:47:24.000Z" lastModifiedTime="2026-09-08T04:47:24.000Z" objectID="{7826F345-9B39-0DC9-0541-F15CCF6AA307}{1}{B0}" alignment="left"><one:T><![CDATA[<span style='font-weight:bold;
3text-decoration:underline;font-family:Calibri;font-size:11.0pt'>Bold</span><span
4style='font-family:Calibri;font-size:11.0pt'> </span><span style='font-family:
5Arial;font-size:13.5pt'>&#129408;</span><span style='font-family:Calibri;
6font-size:11.0pt'> </span><span style='font-style:italic;text-decoration:line-through;
7font-family:Calibri;font-size:11.0pt'>italic</span><span style='font-family:
8Calibri;font-size:11.0pt'> </span><span style='vertical-align:super;font-family:
9Calibri;font-size:11.0pt'>é</span><span style='font-family:Calibri;font-size:
1011.0pt'> </span><span style='font-family:Calibri;font-size:11.0pt;color:#0C2238;
11background:yellow;mso-highlight:yellow'>color</span><span style='font-family:
12Calibri;font-size:11.0pt'> </span><span style='vertical-align:sub;font-family:
13Calibri;font-size:11.0pt'>東京</span><span style='font-family:Calibri;font-size:
1411.0pt'><br>
15End</span>]]></one:T></one:OE><one:OE author="snow" authorInitials="S" lastModifiedBy="snow" lastModifiedByInitials="S" creationTime="2026-09-05T05:06:55.000Z" lastModifiedTime="2026-09-05T05:06:56.000Z" objectID="{7F435BB2-6844-46C3-B515-32560401D1F1}{11}{B0}" alignment="left" quickStyleIndex="0" style="font-size:11.0pt;color:#1F4E79"><one:T><![CDATA[<span
16style='font-weight:bold;font-family:Calibri' lang=en-US>Fictitious: café, </span><span
17style='font-weight:bold;font-family:SimSun' lang=en-US>東京</span><span
18style='font-weight:bold;font-family:Calibri' lang=en-US>, </span><span
19style='font-weight:bold;font-family:Arial;direction:rtl;unicode-bidi:embed'
20lang=ar-SA>مرحبا</span>]]></one:T></one:OE></one:OEChildren></one:Outline></one:Page>
corpus/paragraph-edit/rust-split/typed/before-read/page-005.xml created+6
......@@ -0,0 +1,6 @@
1<?xml version="1.0"?>
2<one:Page xmlns:one="http://schemas.microsoft.com/office/onenote/2010/onenote" ID="{38A52E16-3377-43CF-A6D4-DFD02D336460}{1}{B0}" name="Split cell" dateTime="2026-09-08T08:09:34.000Z" lastModifiedTime="2026-09-08T08:57:31.000Z" pageLevel="1" lang="en-US"><one:QuickStyleDef index="0" name="p" fontColor="automatic" highlightColor="automatic" font="Calibri" fontSize="11.0" spaceBefore="0.0" spaceAfter="0.0"/><one:PageSettings RTL="false" color="automatic"><one:PageSize><one:Automatic/></one:PageSize><one:RuleLines visible="false"/></one:PageSettings><one:Title lang="en-US"><one:OE author="virtual" authorInitials="V" lastModifiedBy="virtual" lastModifiedByInitials="V" creationTime="2026-09-08T08:09:34.000Z" lastModifiedTime="2026-09-08T08:09:34.000Z" objectID="{8C14E633-7850-435D-8F73-AF46AA0C4034}{33}{B0}" alignment="left" quickStyleIndex="0" style="font-family:Calibri;font-size:17.0pt"><one:T><![CDATA[Split cell]]></one:T></one:OE></one:Title><one:Outline author="virtual" authorInitials="V" lastModifiedBy="virtual" lastModifiedByInitials="V" lastModifiedTime="2026-09-08T08:51:01.000Z" objectID="{8C14E633-7850-435D-8F73-AF46AA0C4034}{39}{B0}"><one:Position x="72.0" y="108.0" z="0"/><one:Size width="254.9588165283203" height="48.80315780639648"/><one:OEChildren><one:OE creationTime="2026-09-08T08:09:34.000Z" lastModifiedTime="2026-09-08T08:51:01.000Z" objectID="{8C14E633-7850-435D-8F73-AF46AA0C4034}{40}{B0}" alignment="left"><one:Table bordersVisible="true" lastModifiedTime="2026-09-08T08:51:01.000Z" objectID="{8C14E633-7850-435D-8F73-AF46AA0C4034}{41}{B0}"><one:Columns><one:Column index="0" width="180.0" isLocked="true"/><one:Column index="1" width="66.82881927490234"/></one:Columns><one:Row objectID="{8C14E633-7850-435D-8F73-AF46AA0C4034}{42}{B0}" lastModifiedTime="2026-09-08T08:51:01.000Z"><one:Cell lastModifiedTime="2026-09-08T08:51:01.000Z" objectID="{8C14E633-7850-435D-8F73-AF46AA0C4034}{43}{B0}"><one:OEChildren><one:OE creationTime="2026-09-08T08:09:34.000Z" lastModifiedTime="2026-09-08T08:51:01.000Z" objectID="{8C14E633-7850-435D-8F73-AF46AA0C4034}{46}{B0}" alignment="left" quickStyleIndex="0" style="font-family:Calibri;font-size:11.0pt"><one:T><![CDATA[<span
3style='font-weight:bold'>Bo</span>]]></one:T></one:OE><one:OE author="Rust split author" creationTime="2026-09-08T08:51:01.000Z" lastModifiedTime="2026-09-08T08:51:01.000Z" objectID="{FACE136C-CA78-0A6C-34CB-6BC2F7F0C835}{1}{B0}" alignment="left" quickStyleIndex="0"><one:T><![CDATA[<span
4style='font-weight:bold' lang=en-US>ld</span><span lang=en-US> </span><span
5style='font-style:italic' lang=en-US>italic</span><span lang=en-US> &#129408; é </span><span
6style='color:#123456' lang=x-none>tail</span>]]></one:T></one:OE></one:OEChildren></one:Cell><one:Cell lastModifiedTime="2026-09-08T08:09:37.000Z" objectID="{8C14E633-7850-435D-8F73-AF46AA0C4034}{54}{B0}" lastModifiedBy="virtual" lastModifiedByInitials="V"><one:OEChildren><one:OE creationTime="2026-09-08T08:09:34.000Z" lastModifiedTime="2026-09-08T08:09:34.000Z" objectID="{8C14E633-7850-435D-8F73-AF46AA0C4034}{57}{B0}" alignment="left" quickStyleIndex="0"><one:T><![CDATA[Preserved cell]]></one:T></one:OE></one:OEChildren></one:Cell></one:Row></one:Table></one:OE><one:OE creationTime="2026-09-08T08:09:34.000Z" lastModifiedTime="2026-09-08T08:09:34.000Z" objectID="{8C14E633-7850-435D-8F73-AF46AA0C4034}{62}{B0}" alignment="left" quickStyleIndex="0"><one:T><![CDATA[Preserved sibling]]></one:T></one:OE></one:OEChildren></one:Outline></one:Page>
corpus/paragraph-edit/rust-split/typed/before-read/page-006.xml created+6
......@@ -0,0 +1,6 @@
1<?xml version="1.0"?>
2<one:Page xmlns:one="http://schemas.microsoft.com/office/onenote/2010/onenote" ID="{40550926-0832-4E02-A8A7-012E8A2B4C46}{1}{B0}" name="Split child" dateTime="2026-09-08T08:09:33.000Z" lastModifiedTime="2026-09-08T08:57:31.000Z" pageLevel="1" lang="en-US"><one:QuickStyleDef index="0" name="p" fontColor="automatic" highlightColor="automatic" font="Calibri" fontSize="11.0" spaceBefore="0.0" spaceAfter="0.0"/><one:PageSettings RTL="false" color="automatic"><one:PageSize><one:Automatic/></one:PageSize><one:RuleLines visible="false"/></one:PageSettings><one:Title lang="en-US"><one:OE author="virtual" authorInitials="V" lastModifiedBy="virtual" lastModifiedByInitials="V" creationTime="2026-09-08T08:09:33.000Z" lastModifiedTime="2026-09-08T08:09:33.000Z" objectID="{C910063C-66E4-43E8-912A-D7C25F8D6FED}{33}{B0}" alignment="left" quickStyleIndex="0" style="font-family:Calibri;font-size:17.0pt"><one:T><![CDATA[Split child]]></one:T></one:OE></one:Title><one:Outline author="virtual" authorInitials="V" lastModifiedBy="virtual" lastModifiedByInitials="V" lastModifiedTime="2026-09-08T08:51:00.000Z" objectID="{C910063C-66E4-43E8-912A-D7C25F8D6FED}{39}{B0}"><one:Position x="72.0" y="108.0" z="0"/><one:Size width="131.8423614501953" height="53.71086883544922"/><one:OEChildren><one:OE creationTime="2026-09-08T08:09:33.000Z" lastModifiedTime="2026-09-08T08:51:00.000Z" objectID="{C910063C-66E4-43E8-912A-D7C25F8D6FED}{40}{B0}" alignment="left" quickStyleIndex="0"><one:T><![CDATA[Preserved parent]]></one:T><one:OEChildren><one:OE lastModifiedBy="Rust split author" creationTime="2026-09-08T08:09:33.000Z" lastModifiedTime="2026-09-08T08:51:00.000Z" objectID="{C910063C-66E4-43E8-912A-D7C25F8D6FED}{45}{B0}" alignment="left" quickStyleIndex="0" style="font-family:Calibri;font-size:11.0pt"><one:T><![CDATA[<span
3style='font-weight:bold'>Bo</span>]]></one:T></one:OE><one:OE author="Rust split author" lastModifiedBy="Rust split author" creationTime="2026-09-08T08:51:00.000Z" lastModifiedTime="2026-09-08T08:51:00.000Z" objectID="{E47C3A5A-0F36-046D-1A10-BB5F9EDF5E4F}{1}{B0}" alignment="left" quickStyleIndex="0"><one:T><![CDATA[<span
4style='font-weight:bold' lang=en-US>ld</span><span lang=en-US> </span><span
5style='font-style:italic' lang=en-US>italic</span><span lang=en-US> &#129408; é </span><span
6style='color:#123456' lang=x-none>tail</span>]]></one:T></one:OE></one:OEChildren></one:OE><one:OE creationTime="2026-09-08T08:09:33.000Z" lastModifiedTime="2026-09-08T08:09:33.000Z" objectID="{C910063C-66E4-43E8-912A-D7C25F8D6FED}{53}{B0}" alignment="left" quickStyleIndex="0"><one:T><![CDATA[Preserved sibling]]></one:T></one:OE></one:OEChildren></one:Outline></one:Page>
corpus/paragraph-edit/rust-split/typed/before-read/page-007.xml created+6
......@@ -0,0 +1,6 @@
1<?xml version="1.0"?>
2<one:Page xmlns:one="http://schemas.microsoft.com/office/onenote/2010/onenote" ID="{82B58899-D83F-4BF5-8AA9-AF765DDD95AA}{1}{B0}" name="Split middle" dateTime="2026-09-08T08:09:29.000Z" lastModifiedTime="2026-09-08T08:57:31.000Z" pageLevel="1" lang="en-US"><one:QuickStyleDef index="0" name="p" fontColor="automatic" highlightColor="automatic" font="Calibri" fontSize="11.0" spaceBefore="0.0" spaceAfter="0.0"/><one:PageSettings RTL="false" color="automatic"><one:PageSize><one:Automatic/></one:PageSize><one:RuleLines visible="false"/></one:PageSettings><one:Title lang="en-US"><one:OE author="virtual" authorInitials="V" lastModifiedBy="virtual" lastModifiedByInitials="V" creationTime="2026-09-08T08:09:32.000Z" lastModifiedTime="2026-09-08T08:09:32.000Z" objectID="{A37E9D15-06C3-4690-A3DF-4D061DE6EF8E}{33}{B0}" alignment="left" quickStyleIndex="0" style="font-family:Calibri;font-size:17.0pt"><one:T><![CDATA[Split middle]]></one:T></one:OE></one:Title><one:Outline author="virtual" authorInitials="V" lastModifiedBy="Rust split author" lastModifiedTime="2026-09-08T08:51:00.000Z" objectID="{A37E9D15-06C3-4690-A3DF-4D061DE6EF8E}{39}{B0}"><one:Position x="72.0" y="108.0" z="0"/><one:Size width="115.6704635620117" height="40.28315734863281"/><one:OEChildren><one:OE creationTime="2026-09-08T08:09:30.000Z" lastModifiedTime="2026-09-08T08:51:00.000Z" objectID="{A37E9D15-06C3-4690-A3DF-4D061DE6EF8E}{40}{B0}" alignment="left" quickStyleIndex="0" style="font-family:Calibri;font-size:11.0pt"><one:T><![CDATA[<span
3style='font-weight:bold'>Bo</span>]]></one:T></one:OE><one:OE author="Rust split author" creationTime="2026-09-08T08:51:00.000Z" lastModifiedTime="2026-09-08T08:51:00.000Z" objectID="{8AD6F11E-99EA-0573-2DD9-25F0CC322B7D}{1}{B0}" alignment="left" quickStyleIndex="0"><one:T><![CDATA[<span
4style='font-weight:bold' lang=en-US>ld</span><span lang=en-US> </span><span
5style='font-style:italic' lang=en-US>italic</span><span lang=en-US> &#129408; é </span><span
6style='color:#123456' lang=x-none>tail</span>]]></one:T></one:OE><one:OE lastModifiedBy="virtual" lastModifiedByInitials="V" creationTime="2026-09-08T08:09:32.000Z" lastModifiedTime="2026-09-08T08:09:32.000Z" objectID="{A37E9D15-06C3-4690-A3DF-4D061DE6EF8E}{48}{B0}" alignment="left" quickStyleIndex="0"><one:T><![CDATA[Preserved sibling]]></one:T></one:OE></one:OEChildren></one:Outline></one:Page>
corpus/paragraph-edit/rust-split/typed/before-read/page-008.xml created+2
......@@ -0,0 +1,2 @@
1<?xml version="1.0"?>
2<one:Page xmlns:one="http://schemas.microsoft.com/office/onenote/2010/onenote" ID="{984F0936-3DA3-4D19-B112-F3CA259A4148}{1}{B0}" name="Split empty" dateTime="2026-09-08T08:09:33.000Z" lastModifiedTime="2026-09-08T08:57:31.000Z" pageLevel="1" lang="en-US"><one:QuickStyleDef index="0" name="p" fontColor="automatic" highlightColor="automatic" font="Calibri" fontSize="11.0" spaceBefore="0.0" spaceAfter="0.0"/><one:PageSettings RTL="false" color="automatic"><one:PageSize><one:Automatic/></one:PageSize><one:RuleLines visible="false"/></one:PageSettings><one:Title lang="en-US"><one:OE author="virtual" authorInitials="V" lastModifiedBy="virtual" lastModifiedByInitials="V" creationTime="2026-09-08T08:09:33.000Z" lastModifiedTime="2026-09-08T08:09:33.000Z" objectID="{77D1B2CB-BFAF-4106-8E28-90895EBDFE03}{33}{B0}" alignment="left" quickStyleIndex="0" style="font-family:Calibri;font-size:17.0pt"><one:T><![CDATA[Split empty]]></one:T></one:OE></one:Title><one:Outline author="virtual" authorInitials="V" lastModifiedBy="Rust split author" lastModifiedTime="2026-09-08T08:51:00.000Z" objectID="{77D1B2CB-BFAF-4106-8E28-90895EBDFE03}{39}{B0}"><one:Position x="72.0" y="108.0" z="0"/><one:Size width="115.6704635620117" height="40.28315734863281"/><one:OEChildren><one:OE creationTime="2026-09-08T08:09:33.000Z" lastModifiedTime="2026-09-08T08:51:00.000Z" objectID="{77D1B2CB-BFAF-4106-8E28-90895EBDFE03}{40}{B0}" alignment="left" quickStyleIndex="0"><one:T><![CDATA[]]></one:T></one:OE><one:OE author="Rust split author" creationTime="2026-09-08T08:51:00.000Z" lastModifiedTime="2026-09-08T08:51:00.000Z" objectID="{F8CC0112-769C-0624-19AF-E3D7C46B02D1}{1}{B0}" alignment="left" quickStyleIndex="0"><one:T><![CDATA[]]></one:T></one:OE><one:OE lastModifiedBy="virtual" lastModifiedByInitials="V" creationTime="2026-09-08T08:09:33.000Z" lastModifiedTime="2026-09-08T08:09:33.000Z" objectID="{77D1B2CB-BFAF-4106-8E28-90895EBDFE03}{46}{B0}" alignment="left" quickStyleIndex="0"><one:T><![CDATA[Preserved sibling]]></one:T></one:OE></one:OEChildren></one:Outline></one:Page>
corpus/paragraph-edit/rust-split/typed/before-read/page-009.xml created+5
......@@ -0,0 +1,5 @@
1<?xml version="1.0"?>
2<one:Page xmlns:one="http://schemas.microsoft.com/office/onenote/2010/onenote" ID="{A24347FF-6099-4ED9-8FB1-3F5190D09CCD}{1}{B0}" name="Split style boundary" dateTime="2026-09-08T08:09:32.000Z" lastModifiedTime="2026-09-08T08:57:31.000Z" pageLevel="1" lang="en-US"><one:QuickStyleDef index="0" name="p" fontColor="automatic" highlightColor="automatic" font="Calibri" fontSize="11.0" spaceBefore="0.0" spaceAfter="0.0"/><one:PageSettings RTL="false" color="automatic"><one:PageSize><one:Automatic/></one:PageSize><one:RuleLines visible="false"/></one:PageSettings><one:Title lang="en-US"><one:OE author="virtual" authorInitials="V" lastModifiedBy="virtual" lastModifiedByInitials="V" creationTime="2026-09-08T08:09:32.000Z" lastModifiedTime="2026-09-08T08:09:32.000Z" objectID="{23234918-7316-4356-9E55-1168D2F353CE}{33}{B0}" alignment="left" quickStyleIndex="0" style="font-family:Calibri;font-size:17.0pt"><one:T><![CDATA[Split style boundary]]></one:T></one:OE></one:Title><one:Outline author="virtual" authorInitials="V" lastModifiedBy="Rust split author" lastModifiedTime="2026-09-08T08:51:00.000Z" objectID="{23234918-7316-4356-9E55-1168D2F353CE}{39}{B0}"><one:Position x="72.0" y="108.0" z="0"/><one:Size width="115.6704635620117" height="40.28315734863281"/><one:OEChildren><one:OE creationTime="2026-09-08T08:09:32.000Z" lastModifiedTime="2026-09-08T08:51:00.000Z" objectID="{23234918-7316-4356-9E55-1168D2F353CE}{40}{B0}" alignment="left" quickStyleIndex="0" style="font-family:Calibri;font-size:11.0pt"><one:T><![CDATA[<span
3style='font-weight:bold'>Bold</span>]]></one:T></one:OE><one:OE author="Rust split author" creationTime="2026-09-08T08:51:00.000Z" lastModifiedTime="2026-09-08T08:51:00.000Z" objectID="{35529659-8CEB-0DFE-0B44-65DA40345D59}{1}{B0}" alignment="left" quickStyleIndex="0"><one:T><![CDATA[<span
4lang=en-US> </span><span style='font-style:italic' lang=en-US>italic</span><span
5lang=en-US> &#129408; é </span><span style='color:#123456' lang=x-none>tail</span>]]></one:T></one:OE><one:OE lastModifiedBy="virtual" lastModifiedByInitials="V" creationTime="2026-09-08T08:09:32.000Z" lastModifiedTime="2026-09-08T08:09:32.000Z" objectID="{23234918-7316-4356-9E55-1168D2F353CE}{48}{B0}" alignment="left" quickStyleIndex="0"><one:T><![CDATA[Preserved sibling]]></one:T></one:OE></one:OEChildren></one:Outline></one:Page>
corpus/paragraph-edit/rust-split/typed/before-read/page-010.xml created+3
......@@ -0,0 +1,3 @@
1<?xml version="1.0"?>
2<one:Page xmlns:one="http://schemas.microsoft.com/office/onenote/2010/onenote" ID="{A4769B89-C976-40DF-AEC6-41152F6A9095}{1}{B0}" name="Split soft break" dateTime="2026-09-08T08:09:34.000Z" lastModifiedTime="2026-09-08T08:57:31.000Z" pageLevel="1" lang="en-US"><one:QuickStyleDef index="0" name="p" fontColor="automatic" highlightColor="automatic" font="Calibri" fontSize="11.0" spaceBefore="0.0" spaceAfter="0.0"/><one:PageSettings RTL="false" color="automatic"><one:PageSize><one:Automatic/></one:PageSize><one:RuleLines visible="false"/></one:PageSettings><one:Title lang="en-US"><one:OE author="virtual" authorInitials="V" lastModifiedBy="virtual" lastModifiedByInitials="V" creationTime="2026-09-08T08:09:34.000Z" lastModifiedTime="2026-09-08T08:09:34.000Z" objectID="{F48F565B-4231-4B49-8231-96CADD1B4ECF}{33}{B0}" alignment="left" quickStyleIndex="0" style="font-family:Calibri;font-size:17.0pt"><one:T><![CDATA[Split soft break]]></one:T></one:OE></one:Title><one:Outline author="virtual" authorInitials="V" lastModifiedBy="Rust split author" lastModifiedTime="2026-09-08T08:51:01.000Z" objectID="{F48F565B-4231-4B49-8231-96CADD1B4ECF}{39}{B0}"><one:Position x="72.0" y="108.0" z="0"/><one:Size width="468.0" height="53.71086883544922"/><one:OEChildren><one:OE creationTime="2026-09-08T08:09:34.000Z" lastModifiedTime="2026-09-08T08:51:01.000Z" objectID="{F48F565B-4231-4B49-8231-96CADD1B4ECF}{40}{B0}" alignment="left" quickStyleIndex="0"><one:T><![CDATA[Bo]]></one:T></one:OE><one:OE author="Rust split author" creationTime="2026-09-08T08:51:01.000Z" lastModifiedTime="2026-09-08T08:51:01.000Z" objectID="{2DC9F33D-F035-0427-18FE-20FB4F7168C3}{1}{B0}" alignment="left" quickStyleIndex="0"><one:T><![CDATA[ld<br>
3soft break]]></one:T></one:OE><one:OE lastModifiedBy="virtual" lastModifiedByInitials="V" creationTime="2026-09-08T08:09:34.000Z" lastModifiedTime="2026-09-08T08:09:34.000Z" objectID="{F48F565B-4231-4B49-8231-96CADD1B4ECF}{45}{B0}" alignment="left" quickStyleIndex="0"><one:T><![CDATA[Preserved sibling]]></one:T></one:OE></one:OEChildren></one:Outline></one:Page>
corpus/paragraph-edit/rust-split/typed/before-read/page-011.xml created+6
......@@ -0,0 +1,6 @@
1<?xml version="1.0"?>
2<one:Page xmlns:one="http://schemas.microsoft.com/office/onenote/2010/onenote" ID="{D8398D05-B0A8-49C8-AF8A-21AAC514A41D}{1}{B0}" name="Split number" dateTime="2026-09-08T08:09:34.000Z" lastModifiedTime="2026-09-08T08:57:31.000Z" pageLevel="1" lang="en-US"><one:QuickStyleDef index="0" name="p" fontColor="automatic" highlightColor="automatic" font="Calibri" fontSize="11.0" spaceBefore="0.0" spaceAfter="0.0"/><one:PageSettings RTL="false" color="automatic"><one:PageSize><one:Automatic/></one:PageSize><one:RuleLines visible="false"/></one:PageSettings><one:Title lang="en-US"><one:OE author="virtual" authorInitials="V" lastModifiedBy="virtual" lastModifiedByInitials="V" creationTime="2026-09-08T08:09:34.000Z" lastModifiedTime="2026-09-08T08:09:34.000Z" objectID="{A83C73B5-4C4D-48E9-9843-9A9112DA788F}{33}{B0}" alignment="left" quickStyleIndex="0" style="font-family:Calibri;font-size:17.0pt"><one:T><![CDATA[Split number]]></one:T></one:OE></one:Title><one:Outline author="virtual" authorInitials="V" lastModifiedBy="Rust split author" lastModifiedTime="2026-09-08T08:51:01.000Z" objectID="{A83C73B5-4C4D-48E9-9843-9A9112DA788F}{39}{B0}"><one:Position x="72.0" y="108.0" z="0"/><one:Size width="115.6704635620117" height="40.28315734863281"/><one:OEChildren><one:OE creationTime="2026-09-08T08:09:34.000Z" lastModifiedTime="2026-09-08T08:51:01.000Z" objectID="{A83C73B5-4C4D-48E9-9843-9A9112DA788F}{40}{B0}" alignment="left" quickStyleIndex="0" style="font-family:Calibri;font-size:11.0pt"><one:List><one:Number numberSequence="1" numberFormat="##." restartNumberingAt="3" fontSize="11.0" font="Calibri" text="III."/></one:List><one:T><![CDATA[<span
3style='font-weight:bold'>Bo</span>]]></one:T></one:OE><one:OE author="Rust split author" creationTime="2026-09-08T08:51:01.000Z" lastModifiedTime="2026-09-08T08:51:01.000Z" objectID="{876C483E-C2E9-08C3-2868-4862F3F152CE}{1}{B0}" alignment="left" quickStyleIndex="0"><one:List><one:Number numberSequence="1" numberFormat="##." fontSize="11.0" font="Calibri" text="IV."/></one:List><one:T><![CDATA[<span
4style='font-weight:bold' lang=en-US>ld</span><span lang=en-US> </span><span
5style='font-style:italic' lang=en-US>italic</span><span lang=en-US> &#129408; é </span><span
6style='color:#123456' lang=x-none>tail</span>]]></one:T></one:OE><one:OE lastModifiedBy="virtual" lastModifiedByInitials="V" creationTime="2026-09-08T08:09:34.000Z" lastModifiedTime="2026-09-08T08:09:34.000Z" objectID="{A83C73B5-4C4D-48E9-9843-9A9112DA788F}{49}{B0}" alignment="left" quickStyleIndex="0"><one:T><![CDATA[Preserved sibling]]></one:T></one:OE></one:OEChildren></one:Outline></one:Page>
corpus/paragraph-edit/rust-split/typed/before-read/page-012.xml created+6
......@@ -0,0 +1,6 @@
1<?xml version="1.0"?>
2<one:Page xmlns:one="http://schemas.microsoft.com/office/onenote/2010/onenote" ID="{E8B9381E-92F9-462F-A40E-425B65DDC831}{1}{B0}" name="Split bullet" dateTime="2026-09-08T08:09:33.000Z" lastModifiedTime="2026-09-08T08:57:31.000Z" pageLevel="1" lang="en-US"><one:QuickStyleDef index="0" name="p" fontColor="automatic" highlightColor="automatic" font="Calibri" fontSize="11.0" spaceBefore="0.0" spaceAfter="0.0"/><one:PageSettings RTL="false" color="automatic"><one:PageSize><one:Automatic/></one:PageSize><one:RuleLines visible="false"/></one:PageSettings><one:Title lang="en-US"><one:OE author="virtual" authorInitials="V" lastModifiedBy="virtual" lastModifiedByInitials="V" creationTime="2026-09-08T08:09:33.000Z" lastModifiedTime="2026-09-08T08:09:33.000Z" objectID="{F0F229DD-2A54-4B26-9FDB-19620E3FBE11}{33}{B0}" alignment="left" quickStyleIndex="0" style="font-family:Calibri;font-size:17.0pt"><one:T><![CDATA[Split bullet]]></one:T></one:OE></one:Title><one:Outline author="virtual" authorInitials="V" lastModifiedBy="Rust split author" lastModifiedTime="2026-09-08T08:51:00.000Z" objectID="{F0F229DD-2A54-4B26-9FDB-19620E3FBE11}{39}{B0}"><one:Position x="72.0" y="108.0" z="0"/><one:Size width="135.3173980712891" height="53.71086883544922"/><one:OEChildren><one:OE creationTime="2026-09-08T08:09:33.000Z" lastModifiedTime="2026-09-08T08:51:00.000Z" objectID="{F0F229DD-2A54-4B26-9FDB-19620E3FBE11}{40}{B0}" alignment="left" quickStyleIndex="0" style="font-family:Calibri;font-size:11.0pt"><one:List><one:Bullet bullet="3" fontSize="11.0"/></one:List><one:T><![CDATA[<span
3style='font-weight:bold'>Bo</span>]]></one:T></one:OE><one:OE author="Rust split author" creationTime="2026-09-08T08:51:00.000Z" lastModifiedTime="2026-09-08T08:51:00.000Z" objectID="{304138CF-55B7-054D-3586-B5C4A63AA094}{1}{B0}" alignment="left" quickStyleIndex="0"><one:List><one:Bullet bullet="3" fontSize="11.0"/></one:List><one:T><![CDATA[<span
4style='font-weight:bold' lang=en-US>ld</span><span lang=en-US> </span><span
5style='font-style:italic' lang=en-US>italic</span><span lang=en-US> &#129408; é </span><span
6style='color:#123456' lang=x-none>tail</span>]]></one:T><one:OEChildren><one:OE lastModifiedBy="virtual" lastModifiedByInitials="V" creationTime="2026-09-08T08:09:33.000Z" lastModifiedTime="2026-09-08T08:09:33.000Z" objectID="{F0F229DD-2A54-4B26-9FDB-19620E3FBE11}{48}{B0}" alignment="left" quickStyleIndex="0"><one:T><![CDATA[Preserved child]]></one:T></one:OE></one:OEChildren></one:OE><one:OE lastModifiedBy="virtual" lastModifiedByInitials="V" creationTime="2026-09-08T08:09:33.000Z" lastModifiedTime="2026-09-08T08:09:33.000Z" objectID="{F0F229DD-2A54-4B26-9FDB-19620E3FBE11}{54}{B0}" alignment="left" quickStyleIndex="0"><one:T><![CDATA[Preserved sibling]]></one:T></one:OE></one:OEChildren></one:Outline></one:Page>
corpus/paragraph-edit/rust-split/typed/before-read/page-013.xml created+5
......@@ -0,0 +1,5 @@
1<?xml version="1.0"?>
2<one:Page xmlns:one="http://schemas.microsoft.com/office/onenote/2010/onenote" ID="{EEE8E5F3-7A14-4AA5-B06A-56D4BAC7C8AF}{1}{B0}" name="Split end" dateTime="2026-09-08T08:09:32.000Z" lastModifiedTime="2026-09-08T08:57:31.000Z" pageLevel="1" lang="en-US"><one:QuickStyleDef index="0" name="p" fontColor="automatic" highlightColor="automatic" font="Calibri" fontSize="11.0" spaceBefore="0.0" spaceAfter="0.0"/><one:PageSettings RTL="false" color="automatic"><one:PageSize><one:Automatic/></one:PageSize><one:RuleLines visible="false"/></one:PageSettings><one:Title lang="en-US"><one:OE author="virtual" authorInitials="V" lastModifiedBy="virtual" lastModifiedByInitials="V" creationTime="2026-09-08T08:09:33.000Z" lastModifiedTime="2026-09-08T08:09:33.000Z" objectID="{A660EE59-AF8B-4E53-A977-0213DD2E1818}{33}{B0}" alignment="left" quickStyleIndex="0" style="font-family:Calibri;font-size:17.0pt"><one:T><![CDATA[Split end]]></one:T></one:OE></one:Title><one:Outline author="virtual" authorInitials="V" lastModifiedBy="Rust split author" lastModifiedTime="2026-09-08T08:51:00.000Z" objectID="{A660EE59-AF8B-4E53-A977-0213DD2E1818}{39}{B0}"><one:Position x="72.0" y="108.0" z="0"/><one:Size width="116.921875" height="40.28315734863281"/><one:OEChildren><one:OE creationTime="2026-09-08T08:09:33.000Z" lastModifiedTime="2026-09-08T08:51:00.000Z" objectID="{A660EE59-AF8B-4E53-A977-0213DD2E1818}{40}{B0}" alignment="left" quickStyleIndex="0"><one:T><![CDATA[<span
3style='font-weight:bold' lang=en-US>Bold</span><span lang=en-US> </span><span
4style='font-style:italic' lang=en-US>italic</span><span lang=en-US> &#129408; é </span><span
5style='color:#123456' lang=x-none>tail</span>]]></one:T></one:OE><one:OE author="Rust split author" creationTime="2026-09-08T08:51:00.000Z" lastModifiedTime="2026-09-08T08:51:00.000Z" objectID="{F60211DF-6E7D-0CA1-2F70-07201B2B1F07}{1}{B0}" alignment="left" quickStyleIndex="0" style="font-family:Calibri;font-size:11.0pt;color:#123456"><one:T><![CDATA[]]></one:T></one:OE><one:OE lastModifiedBy="virtual" lastModifiedByInitials="V" creationTime="2026-09-08T08:09:33.000Z" lastModifiedTime="2026-09-08T08:09:33.000Z" objectID="{A660EE59-AF8B-4E53-A977-0213DD2E1818}{48}{B0}" alignment="left" quickStyleIndex="0"><one:T><![CDATA[Preserved sibling]]></one:T></one:OE></one:OEChildren></one:Outline></one:Page>
corpus/paragraph-edit/rust-split/typed/before-read/payloads.json created+1
......@@ -0,0 +1 @@
1../../../before/read/payloads.json
\ No newline at end of file
corpus/paragraph-edit/rust-split/typed/notebook/Open Notebook.onetoc2 created+1
......@@ -0,0 +1 @@
1../../native/notebook/Open Notebook.onetoc2
\ No newline at end of file
corpus/paragraph-edit/rust-split/typed/notebook/synthetic.one created
Binary files /dev/null and b/corpus/paragraph-edit/rust-split/typed/notebook/synthetic.one differ
corpus/paragraph-edit/rust-split/typed/read/environment.json created+7
......@@ -0,0 +1,7 @@
1{
2 "powershell": "5.1.14409.1005",
3 "schema": "xs2010",
4 "hostname": "ONE-M6-02D586B5",
5 "cold": false,
6 "onenote": "14.0.4763.1000"
7}
corpus/paragraph-edit/rust-split/typed/read/hierarchy.xml created+2
......@@ -0,0 +1,2 @@
1<?xml version="1.0"?>
2<one:Notebook xmlns:one="http://schemas.microsoft.com/office/onenote/2010/onenote" name="notebook" nickname="notebook" ID="{5F2547AA-6079-422C-929F-ACD159424C5F}{1}{B0}" path="C:\one-tests\runs\capture\notebook" lastModifiedTime="2026-09-08T08:59:47.000Z" color="#B49EDE" isCurrentlyViewed="true"><one:Section name="synthetic" ID="{34C60088-AAFA-0664-3D80-161C07A5288F}{1}{B0}" path="C:\one-tests\runs\capture\notebook\synthetic.one" lastModifiedTime="2026-09-08T08:59:47.000Z" color="#8AA8E4" isCurrentlyViewed="true"><one:Page ID="{188FF30E-2331-4575-BAE7-BE8DFB9D3490}{1}{B0}" name="Bold 🦀 italic é color 東京" dateTime="2026-09-05T05:06:54.000Z" lastModifiedTime="2026-09-08T08:57:31.000Z" pageLevel="1"/><one:Page ID="{82B58899-D83F-4BF5-8AA9-AF765DDD95AA}{1}{B0}" name="Split middle" dateTime="2026-09-08T08:09:29.000Z" lastModifiedTime="2026-09-08T08:57:31.000Z" pageLevel="1"/><one:Page ID="{A24347FF-6099-4ED9-8FB1-3F5190D09CCD}{1}{B0}" name="Split style boundary" dateTime="2026-09-08T08:09:32.000Z" lastModifiedTime="2026-09-08T08:57:31.000Z" pageLevel="1"/><one:Page ID="{058E24C9-6521-4913-9088-94646869E7EC}{1}{B0}" name="Split start" dateTime="2026-09-08T08:09:32.000Z" lastModifiedTime="2026-09-08T08:59:40.000Z" pageLevel="1"/><one:Page ID="{EEE8E5F3-7A14-4AA5-B06A-56D4BAC7C8AF}{1}{B0}" name="Split end" dateTime="2026-09-08T08:09:32.000Z" lastModifiedTime="2026-09-08T08:59:43.000Z" pageLevel="1"/><one:Page ID="{984F0936-3DA3-4D19-B112-F3CA259A4148}{1}{B0}" name="Split empty" dateTime="2026-09-08T08:09:33.000Z" lastModifiedTime="2026-09-08T08:59:47.000Z" pageLevel="1" isCurrentlyViewed="true"/><one:Page ID="{06A1F0B6-1EEA-4375-8EED-D084C6D806D2}{1}{B0}" name="Split parent" dateTime="2026-09-08T08:09:33.000Z" lastModifiedTime="2026-09-08T08:57:31.000Z" pageLevel="1"/><one:Page ID="{40550926-0832-4E02-A8A7-012E8A2B4C46}{1}{B0}" name="Split child" dateTime="2026-09-08T08:09:33.000Z" lastModifiedTime="2026-09-08T08:57:31.000Z" pageLevel="1"/><one:Page ID="{E8B9381E-92F9-462F-A40E-425B65DDC831}{1}{B0}" name="Split bullet" dateTime="2026-09-08T08:09:33.000Z" lastModifiedTime="2026-09-08T08:57:31.000Z" pageLevel="1"/><one:Page ID="{D8398D05-B0A8-49C8-AF8A-21AAC514A41D}{1}{B0}" name="Split number" dateTime="2026-09-08T08:09:34.000Z" lastModifiedTime="2026-09-08T08:57:31.000Z" pageLevel="1"/><one:Page ID="{0F0A7E71-2F11-43B7-A18E-7820B16929B4}{1}{B0}" name="Split tag" dateTime="2026-09-08T08:09:34.000Z" lastModifiedTime="2026-09-08T08:57:31.000Z" pageLevel="1"/><one:Page ID="{38A52E16-3377-43CF-A6D4-DFD02D336460}{1}{B0}" name="Split cell" dateTime="2026-09-08T08:09:34.000Z" lastModifiedTime="2026-09-08T08:57:31.000Z" pageLevel="1"/><one:Page ID="{A4769B89-C976-40DF-AEC6-41152F6A9095}{1}{B0}" name="Split soft break" dateTime="2026-09-08T08:09:34.000Z" lastModifiedTime="2026-09-08T08:57:31.000Z" pageLevel="1"/><one:Page ID="{0E569C7E-F5A1-4E91-A1B9-B0AEA2AF2B2B}{1}{B0}" name="Split before hyperlink" dateTime="2026-09-08T08:09:34.000Z" lastModifiedTime="2026-09-08T08:57:31.000Z" pageLevel="1"/></one:Section></one:Notebook>
corpus/paragraph-edit/rust-split/typed/read/page-000.xml created+5
......@@ -0,0 +1,5 @@
1<?xml version="1.0"?>
2<one:Page xmlns:one="http://schemas.microsoft.com/office/onenote/2010/onenote" ID="{058E24C9-6521-4913-9088-94646869E7EC}{1}{B0}" name="Split start" dateTime="2026-09-08T08:09:32.000Z" lastModifiedTime="2026-09-08T08:59:41.000Z" pageLevel="1" lang="en-US"><one:QuickStyleDef index="0" name="p" fontColor="automatic" highlightColor="automatic" font="Calibri" fontSize="11.0" spaceBefore="0.0" spaceAfter="0.0"/><one:PageSettings RTL="false" color="automatic"><one:PageSize><one:Automatic/></one:PageSize><one:RuleLines visible="false"/></one:PageSettings><one:Title lang="en-US"><one:OE author="virtual" authorInitials="V" lastModifiedBy="virtual" lastModifiedByInitials="V" creationTime="2026-09-08T08:09:32.000Z" lastModifiedTime="2026-09-08T08:59:40.000Z" objectID="{7DB914B1-2E9B-4E51-B78C-87B90E14A385}{33}{B0}" alignment="left" quickStyleIndex="0" style="font-family:Calibri;font-size:17.0pt"><one:T><![CDATA[Split start]]></one:T></one:OE></one:Title><one:Outline author="virtual" authorInitials="V" lastModifiedBy="virtual" lastModifiedByInitials="V" lastModifiedTime="2026-09-08T08:59:40.000Z" objectID="{7DB914B1-2E9B-4E51-B78C-87B90E14A385}{39}{B0}"><one:Position x="72.0" y="108.0" z="0"/><one:Size width="116.921875" height="40.28315734863281"/><one:OEChildren><one:OE creationTime="2026-09-08T08:09:32.000Z" lastModifiedTime="2026-09-08T08:59:40.000Z" objectID="{7DB914B1-2E9B-4E51-B78C-87B90E14A385}{40}{B0}" alignment="left" quickStyleIndex="0"><one:T><![CDATA[Typed ]]></one:T></one:OE><one:OE author="Rust split author" lastModifiedBy="Rust split author" creationTime="2026-09-08T08:51:00.000Z" lastModifiedTime="2026-09-08T08:59:40.000Z" objectID="{8441DD7D-4E61-0CC9-1309-4B6EC734EEAF}{1}{B0}" alignment="left" quickStyleIndex="0"><one:T><![CDATA[<span
3style='font-weight:bold' lang=en-US>Bold</span><span lang=en-US> </span><span
4style='font-style:italic' lang=en-US>italic</span><span lang=en-US> &#129408; é </span><span
5style='color:#123456' lang=x-none>tail</span>]]></one:T></one:OE><one:OE creationTime="2026-09-08T08:09:32.000Z" lastModifiedTime="2026-09-08T08:59:40.000Z" objectID="{7DB914B1-2E9B-4E51-B78C-87B90E14A385}{48}{B0}" alignment="left" quickStyleIndex="0"><one:T><![CDATA[Preserved sibling]]></one:T></one:OE></one:OEChildren></one:Outline></one:Page>
corpus/paragraph-edit/rust-split/typed/read/page-001.xml created+1
......@@ -0,0 +1 @@
1../before-read/page-001.xml
\ No newline at end of file
corpus/paragraph-edit/rust-split/typed/read/page-002.xml created+1
......@@ -0,0 +1 @@
1../before-read/page-002.xml
\ No newline at end of file
corpus/paragraph-edit/rust-split/typed/read/page-003.xml created+1
......@@ -0,0 +1 @@
1../before-read/page-003.xml
\ No newline at end of file
corpus/paragraph-edit/rust-split/typed/read/page-004.xml created+20
......@@ -0,0 +1,20 @@
1<?xml version="1.0"?>
2<one:Page xmlns:one="http://schemas.microsoft.com/office/onenote/2010/onenote" ID="{188FF30E-2331-4575-BAE7-BE8DFB9D3490}{1}{B0}" name="Bold 🦀 italic é color 東京" dateTime="2026-09-05T05:06:54.000Z" lastModifiedTime="2026-09-08T08:59:37.000Z" pageLevel="1" lang="en-US"><one:QuickStyleDef index="0" name="p" fontColor="automatic" highlightColor="automatic" font="Calibri" fontSize="11.0" spaceBefore="0.0" spaceAfter="0.0"/><one:PageSettings RTL="false" color="automatic"><one:PageSize><one:Automatic/></one:PageSize><one:RuleLines visible="false"/></one:PageSettings><one:Outline author="Rich author" lastModifiedBy="Rich author" lastModifiedTime="2026-09-08T04:47:24.000Z" objectID="{7F435BB2-6844-46C3-B515-32560401D1F1}{10}{B0}"><one:Position x="36.0" y="14.40000057220459" z="0"/><one:Size width="523.125" height="42.90299224853515"/><one:OEChildren><one:OE creationTime="2026-09-08T04:47:24.000Z" lastModifiedTime="2026-09-08T04:47:24.000Z" objectID="{7826F345-9B39-0DC9-0541-F15CCF6AA307}{1}{B0}" alignment="left"><one:T><![CDATA[<span style='font-weight:bold;
3text-decoration:underline;font-family:Calibri;font-size:11.0pt'>Bold</span><span
4style='font-family:Calibri;font-size:11.0pt'> </span><span style='font-family:
5Arial;font-size:13.5pt'>&#129408;</span><span style='font-family:Calibri;
6font-size:11.0pt'> </span><span style='font-style:italic;text-decoration:line-through;
7font-family:Calibri;font-size:11.0pt'>italic</span><span style='font-family:
8Calibri;font-size:11.0pt'> </span><span style='vertical-align:super;font-family:
9Calibri;font-size:11.0pt'>é</span><span style='font-family:Calibri;font-size:
1011.0pt'> </span><span style='font-family:Calibri;font-size:11.0pt;color:#0C2238;
11background:yellow;mso-highlight:yellow'>color</span><span style='font-family:
12Calibri;font-size:11.0pt'> </span><span style='vertical-align:sub;font-family:
13Calibri;font-size:11.0pt'>東京</span><span style='font-family:Calibri;font-size:
1411.0pt'><br>
15End</span>]]></one:T></one:OE><one:OE author="snow" authorInitials="S" lastModifiedBy="snow" lastModifiedByInitials="S" creationTime="2026-09-05T05:06:55.000Z" lastModifiedTime="2026-09-05T05:06:56.000Z" objectID="{7F435BB2-6844-46C3-B515-32560401D1F1}{11}{B0}" alignment="left" quickStyleIndex="0" style="font-size:11.0pt;color:#1F4E79"><one:T><![CDATA[<span
16style='font-weight:bold;font-family:Calibri' lang=en-US>Fictitious: café, </span><span
17style='font-weight:bold;font-family:SimSun' lang=en-US>東京</span><span
18style='font-weight:bold;font-family:Calibri' lang=en-US>, </span><span
19style='font-weight:bold;font-family:Arial;direction:rtl;unicode-bidi:embed'
20lang=ar-SA>مرحبا</span>]]></one:T></one:OE></one:OEChildren></one:Outline></one:Page>
corpus/paragraph-edit/rust-split/typed/read/page-005.xml created+1
......@@ -0,0 +1 @@
1../before-read/page-005.xml
\ No newline at end of file
corpus/paragraph-edit/rust-split/typed/read/page-006.xml created+1
......@@ -0,0 +1 @@
1../before-read/page-006.xml
\ No newline at end of file
corpus/paragraph-edit/rust-split/typed/read/page-007.xml created+1
......@@ -0,0 +1 @@
1../before-read/page-007.xml
\ No newline at end of file
corpus/paragraph-edit/rust-split/typed/read/page-008.xml created+2
......@@ -0,0 +1,2 @@
1<?xml version="1.0"?>
2<one:Page xmlns:one="http://schemas.microsoft.com/office/onenote/2010/onenote" ID="{984F0936-3DA3-4D19-B112-F3CA259A4148}{1}{B0}" name="Split empty" dateTime="2026-09-08T08:09:33.000Z" lastModifiedTime="2026-09-08T08:59:47.000Z" pageLevel="1" isCurrentlyViewed="true" lang="en-US"><one:QuickStyleDef index="0" name="p" fontColor="automatic" highlightColor="automatic" font="Calibri" fontSize="11.0" spaceBefore="0.0" spaceAfter="0.0"/><one:PageSettings RTL="false" color="automatic"><one:PageSize><one:Automatic/></one:PageSize><one:RuleLines visible="false"/></one:PageSettings><one:Title lang="en-US"><one:OE author="virtual" authorInitials="V" lastModifiedBy="virtual" lastModifiedByInitials="V" creationTime="2026-09-08T08:09:33.000Z" lastModifiedTime="2026-09-08T08:59:43.000Z" objectID="{77D1B2CB-BFAF-4106-8E28-90895EBDFE03}{33}{B0}" alignment="left" quickStyleIndex="0" style="font-family:Calibri;font-size:17.0pt"><one:T><![CDATA[Split empty]]></one:T></one:OE></one:Title><one:Outline author="virtual" authorInitials="V" lastModifiedBy="virtual" lastModifiedByInitials="V" lastModifiedTime="2026-09-08T08:59:46.000Z" objectID="{77D1B2CB-BFAF-4106-8E28-90895EBDFE03}{39}{B0}"><one:Position x="72.0" y="108.0" z="0"/><one:Size width="115.6704635620117" height="40.28315734863281"/><one:OEChildren><one:OE creationTime="2026-09-08T08:09:33.000Z" lastModifiedTime="2026-09-08T08:59:44.000Z" objectID="{77D1B2CB-BFAF-4106-8E28-90895EBDFE03}{40}{B0}" alignment="left" quickStyleIndex="0"><one:T><![CDATA[Typed ]]></one:T></one:OE><one:OE author="Rust split author" creationTime="2026-09-08T08:51:00.000Z" lastModifiedTime="2026-09-08T08:59:46.000Z" objectID="{F8CC0112-769C-0624-19AF-E3D7C46B02D1}{1}{B0}" alignment="left" quickStyleIndex="0"><one:T><![CDATA[Typed ]]></one:T></one:OE><one:OE creationTime="2026-09-08T08:09:33.000Z" lastModifiedTime="2026-09-08T08:59:43.000Z" objectID="{77D1B2CB-BFAF-4106-8E28-90895EBDFE03}{46}{B0}" alignment="left" quickStyleIndex="0"><one:T><![CDATA[Preserved sibling]]></one:T></one:OE></one:OEChildren></one:Outline></one:Page>
corpus/paragraph-edit/rust-split/typed/read/page-009.xml created+1
......@@ -0,0 +1 @@
1../before-read/page-009.xml
\ No newline at end of file
corpus/paragraph-edit/rust-split/typed/read/page-010.xml created+1
......@@ -0,0 +1 @@
1../before-read/page-010.xml
\ No newline at end of file
corpus/paragraph-edit/rust-split/typed/read/page-011.xml created+1
......@@ -0,0 +1 @@
1../before-read/page-011.xml
\ No newline at end of file
corpus/paragraph-edit/rust-split/typed/read/page-012.xml created+1
......@@ -0,0 +1 @@
1../before-read/page-012.xml
\ No newline at end of file
corpus/paragraph-edit/rust-split/typed/read/page-013.xml created+5
......@@ -0,0 +1,5 @@
1<?xml version="1.0"?>
2<one:Page xmlns:one="http://schemas.microsoft.com/office/onenote/2010/onenote" ID="{EEE8E5F3-7A14-4AA5-B06A-56D4BAC7C8AF}{1}{B0}" name="Split end" dateTime="2026-09-08T08:09:32.000Z" lastModifiedTime="2026-09-08T08:59:43.000Z" pageLevel="1" lang="en-US"><one:QuickStyleDef index="0" name="p" fontColor="automatic" highlightColor="automatic" font="Calibri" fontSize="11.0" spaceBefore="0.0" spaceAfter="0.0"/><one:PageSettings RTL="false" color="automatic"><one:PageSize><one:Automatic/></one:PageSize><one:RuleLines visible="false"/></one:PageSettings><one:Title lang="en-US"><one:OE author="virtual" authorInitials="V" lastModifiedBy="virtual" lastModifiedByInitials="V" creationTime="2026-09-08T08:09:33.000Z" lastModifiedTime="2026-09-08T08:59:42.000Z" objectID="{A660EE59-AF8B-4E53-A977-0213DD2E1818}{33}{B0}" alignment="left" quickStyleIndex="0" style="font-family:Calibri;font-size:17.0pt"><one:T><![CDATA[Split end]]></one:T></one:OE></one:Title><one:Outline author="virtual" authorInitials="V" lastModifiedBy="Rust split author" lastModifiedTime="2026-09-08T08:59:42.000Z" objectID="{A660EE59-AF8B-4E53-A977-0213DD2E1818}{39}{B0}"><one:Position x="72.0" y="108.0" z="0"/><one:Size width="116.921875" height="40.28315734863281"/><one:OEChildren><one:OE creationTime="2026-09-08T08:09:33.000Z" lastModifiedTime="2026-09-08T08:59:42.000Z" objectID="{A660EE59-AF8B-4E53-A977-0213DD2E1818}{40}{B0}" alignment="left" quickStyleIndex="0"><one:T><![CDATA[<span
3style='font-weight:bold' lang=en-US>Bold</span><span lang=en-US> </span><span
4style='font-style:italic' lang=en-US>italic</span><span lang=en-US> &#129408; é </span><span
5style='color:#123456' lang=x-none>tail</span>]]></one:T></one:OE><one:OE author="Rust split author" lastModifiedBy="virtual" lastModifiedByInitials="V" creationTime="2026-09-08T08:51:00.000Z" lastModifiedTime="2026-09-08T08:59:42.000Z" objectID="{F60211DF-6E7D-0CA1-2F70-07201B2B1F07}{1}{B0}" alignment="left" quickStyleIndex="0" style="font-family:Calibri;font-size:11.0pt;color:#123456"><one:T><![CDATA[Typed ]]></one:T></one:OE><one:OE lastModifiedBy="virtual" lastModifiedByInitials="V" creationTime="2026-09-08T08:09:33.000Z" lastModifiedTime="2026-09-08T08:59:42.000Z" objectID="{A660EE59-AF8B-4E53-A977-0213DD2E1818}{48}{B0}" alignment="left" quickStyleIndex="0"><one:T><![CDATA[Preserved sibling]]></one:T></one:OE></one:OEChildren></one:Outline></one:Page>
corpus/paragraph-edit/rust-split/typed/read/payloads.json created+1
......@@ -0,0 +1 @@
1../../../before/read/payloads.json
\ No newline at end of file
corpus/paragraph-edit/rust-split/typed/run.json created+18
......@@ -0,0 +1,18 @@
1{
2 "notebook": "/Users/clo/dev/one/evidence/m10/paragraph-rust-split-01/native/notebook",
3 "expected_pages": 14,
4 "author": null,
5 "author_timeout_seconds": 600,
6 "inspect": true,
7 "collect_notebook": true,
8 "base": {
9 "file": "win7-office-base.qcow2",
10 "format": "qcow2",
11 "sha256": "a1a4f8fab782ee14885ff801ca2f6347c208fdcfc3513637096f314315c89346",
12 "virtual_size": 68719476736
13 },
14 "scripts": {
15 "cold.ps1": "c177fc72ae6c2634d186f5671a880de20b09f9716532c37c69cb13aa15c7e331",
16 "read.ps1": "04013bfcccee40a17e2a225f9b9e96f40a3a8daad9e350609654f8eda3ccbb41"
17 }
18}
corpus/paragraph-edit/rust-split/typed/source.json created+14
......@@ -0,0 +1,14 @@
1[
2 {
3 "path": "Open Notebook.onetoc2",
4 "bytes": 4800,
5 "sha256": "7c258d318aaa6089989a7beb427a820beb99ebd7833f2a76ecbbb3713df07dbb",
6 "mtime_ns": 1788857651415033964
7 },
8 {
9 "path": "synthetic.one",
10 "bytes": 110224,
11 "sha256": "29a64584c4d7ac72958595769854a3df199156cb89541df354d9e9f484450712",
12 "mtime_ns": 1788857651415524756
13 }
14]
corpus/paragraph-edit/rust-split/typed/teardown.json created+1
......@@ -0,0 +1 @@
1../../joined/teardown.json
\ No newline at end of file
corpus/paragraph-edit/rust-split/typed/ui/selections.json created+30
......@@ -0,0 +1,30 @@
1[
2 {
3 "case": "Split start",
4 "index": 0,
5 "page": "{058E24C9-6521-4913-9088-94646869E7EC}{1}{B0}",
6 "object": "{7DB914B1-2E9B-4E51-B78C-87B90E14A385}{40}{B0}",
7 "text": "Typed "
8 },
9 {
10 "case": "Split end",
11 "index": 1,
12 "page": "{EEE8E5F3-7A14-4AA5-B06A-56D4BAC7C8AF}{1}{B0}",
13 "object": "{F60211DF-6E7D-0CA1-2F70-07201B2B1F07}{1}{B0}",
14 "text": "Typed "
15 },
16 {
17 "case": "Split empty",
18 "index": 0,
19 "page": "{984F0936-3DA3-4D19-B112-F3CA259A4148}{1}{B0}",
20 "object": "{77D1B2CB-BFAF-4106-8E28-90895EBDFE03}{40}{B0}",
21 "text": "Typed "
22 },
23 {
24 "case": "Split empty",
25 "index": 1,
26 "page": "{984F0936-3DA3-4D19-B112-F3CA259A4148}{1}{B0}",
27 "object": "{F8CC0112-769C-0624-19AF-E3D7C46B02D1}{1}{B0}",
28 "text": "Typed "
29 }
30]
\ No newline at end of file
corpus/paragraph-edit/rust-split/typed/ui/split-empty-0.ahk created+23
......@@ -0,0 +1,23 @@
1#Requires AutoHotkey v2.0
2OnError((exception, mode) => (FileAppend(exception.Message, "**"), ExitApp(1)))
3dm := Buffer(220, 0)
4NumPut("UShort", 220, dm, 68)
5if !DllCall("EnumDisplaySettingsW", "Ptr", 0, "UInt", 0xFFFFFFFF, "Ptr", dm)
6 throw Error("Cannot inspect display mode")
7NumPut("UInt", NumGet(dm, 72, "UInt") | 0x180000, dm, 72)
8NumPut("UInt", 1280, dm, 172)
9NumPut("UInt", 720, dm, 176)
10if DllCall("ChangeDisplaySettingsW", "Ptr", dm, "UInt", 0, "Int") != 0
11 throw Error("Display mode rejected")
12app := ComObject("OneNote.Application")
13app.NavigateTo("{984F0936-3DA3-4D19-B112-F3CA259A4148}{1}{B0}", "{77D1B2CB-BFAF-4106-8E28-90895EBDFE03}{40}{B0}", false)
14hwnd := WinWait("ahk_class Framework::CFrame ahk_exe ONENOTE.EXE",, 10)
15if !hwnd
16 throw Error("OneNote window did not appear")
17WinMaximize(hwnd)
18WinActivate(hwnd)
19if !WinWaitActive(hwnd,, 10)
20 throw Error("OneNote window did not become active")
21Sleep 300
22Send "{Left}"
23SendText "Typed "
corpus/paragraph-edit/rust-split/typed/ui/split-empty-0.json created+1
......@@ -0,0 +1 @@
1../../../joined/ui/split-empty.json
\ No newline at end of file
corpus/paragraph-edit/rust-split/typed/ui/split-empty-0.png created
Binary files /dev/null and b/corpus/paragraph-edit/rust-split/typed/ui/split-empty-0.png differ
corpus/paragraph-edit/rust-split/typed/ui/split-empty-1.ahk created+23
......@@ -0,0 +1,23 @@
1#Requires AutoHotkey v2.0
2OnError((exception, mode) => (FileAppend(exception.Message, "**"), ExitApp(1)))
3dm := Buffer(220, 0)
4NumPut("UShort", 220, dm, 68)
5if !DllCall("EnumDisplaySettingsW", "Ptr", 0, "UInt", 0xFFFFFFFF, "Ptr", dm)
6 throw Error("Cannot inspect display mode")
7NumPut("UInt", NumGet(dm, 72, "UInt") | 0x180000, dm, 72)
8NumPut("UInt", 1280, dm, 172)
9NumPut("UInt", 720, dm, 176)
10if DllCall("ChangeDisplaySettingsW", "Ptr", dm, "UInt", 0, "Int") != 0
11 throw Error("Display mode rejected")
12app := ComObject("OneNote.Application")
13app.NavigateTo("{984F0936-3DA3-4D19-B112-F3CA259A4148}{1}{B0}", "{F8CC0112-769C-0624-19AF-E3D7C46B02D1}{1}{B0}", false)
14hwnd := WinWait("ahk_class Framework::CFrame ahk_exe ONENOTE.EXE",, 10)
15if !hwnd
16 throw Error("OneNote window did not appear")
17WinMaximize(hwnd)
18WinActivate(hwnd)
19if !WinWaitActive(hwnd,, 10)
20 throw Error("OneNote window did not become active")
21Sleep 300
22Send "{Left}"
23SendText "Typed "
corpus/paragraph-edit/rust-split/typed/ui/split-empty-1.json created+1
......@@ -0,0 +1 @@
1../../../joined/ui/split-empty.json
\ No newline at end of file
corpus/paragraph-edit/rust-split/typed/ui/split-empty-1.png created
Binary files /dev/null and b/corpus/paragraph-edit/rust-split/typed/ui/split-empty-1.png differ
corpus/paragraph-edit/rust-split/typed/ui/split-end-1.ahk created+23
......@@ -0,0 +1,23 @@
1#Requires AutoHotkey v2.0
2OnError((exception, mode) => (FileAppend(exception.Message, "**"), ExitApp(1)))
3dm := Buffer(220, 0)
4NumPut("UShort", 220, dm, 68)
5if !DllCall("EnumDisplaySettingsW", "Ptr", 0, "UInt", 0xFFFFFFFF, "Ptr", dm)
6 throw Error("Cannot inspect display mode")
7NumPut("UInt", NumGet(dm, 72, "UInt") | 0x180000, dm, 72)
8NumPut("UInt", 1280, dm, 172)
9NumPut("UInt", 720, dm, 176)
10if DllCall("ChangeDisplaySettingsW", "Ptr", dm, "UInt", 0, "Int") != 0
11 throw Error("Display mode rejected")
12app := ComObject("OneNote.Application")
13app.NavigateTo("{EEE8E5F3-7A14-4AA5-B06A-56D4BAC7C8AF}{1}{B0}", "{F60211DF-6E7D-0CA1-2F70-07201B2B1F07}{1}{B0}", false)
14hwnd := WinWait("ahk_class Framework::CFrame ahk_exe ONENOTE.EXE",, 10)
15if !hwnd
16 throw Error("OneNote window did not appear")
17WinMaximize(hwnd)
18WinActivate(hwnd)
19if !WinWaitActive(hwnd,, 10)
20 throw Error("OneNote window did not become active")
21Sleep 300
22Send "{Left}"
23SendText "Typed "
corpus/paragraph-edit/rust-split/typed/ui/split-end-1.json created+1
......@@ -0,0 +1 @@
1../../../joined/ui/split-end.json
\ No newline at end of file
corpus/paragraph-edit/rust-split/typed/ui/split-end-1.png created
Binary files /dev/null and b/corpus/paragraph-edit/rust-split/typed/ui/split-end-1.png differ
corpus/paragraph-edit/rust-split/typed/ui/split-start-0.ahk created+23
......@@ -0,0 +1,23 @@
1#Requires AutoHotkey v2.0
2OnError((exception, mode) => (FileAppend(exception.Message, "**"), ExitApp(1)))
3dm := Buffer(220, 0)
4NumPut("UShort", 220, dm, 68)
5if !DllCall("EnumDisplaySettingsW", "Ptr", 0, "UInt", 0xFFFFFFFF, "Ptr", dm)
6 throw Error("Cannot inspect display mode")
7NumPut("UInt", NumGet(dm, 72, "UInt") | 0x180000, dm, 72)
8NumPut("UInt", 1280, dm, 172)
9NumPut("UInt", 720, dm, 176)
10if DllCall("ChangeDisplaySettingsW", "Ptr", dm, "UInt", 0, "Int") != 0
11 throw Error("Display mode rejected")
12app := ComObject("OneNote.Application")
13app.NavigateTo("{058E24C9-6521-4913-9088-94646869E7EC}{1}{B0}", "{7DB914B1-2E9B-4E51-B78C-87B90E14A385}{40}{B0}", false)
14hwnd := WinWait("ahk_class Framework::CFrame ahk_exe ONENOTE.EXE",, 10)
15if !hwnd
16 throw Error("OneNote window did not appear")
17WinMaximize(hwnd)
18WinActivate(hwnd)
19if !WinWaitActive(hwnd,, 10)
20 throw Error("OneNote window did not become active")
21Sleep 300
22Send "{Left}"
23SendText "Typed "
corpus/paragraph-edit/rust-split/typed/ui/split-start-0.json created+1
......@@ -0,0 +1 @@
1../../../joined/ui/split-start.json
\ No newline at end of file
corpus/paragraph-edit/rust-split/typed/ui/split-start-0.png created
Binary files /dev/null and b/corpus/paragraph-edit/rust-split/typed/ui/split-start-0.png differ
crates/onestore/README.md+9
......@@ -49,6 +49,7 @@ harness also accepts `--client-profile release`.
4949| `replace_property_bytes` | Append one scalar-property revision; preserve prior revisions and unrelated property values and references |
5050| `replace_text`, `commit_text`, `commit_file_text` | Replace a UTF-16 range across ordinary text runs; publish text, run boundaries and modification time together |
5151| `Insertion`, `PreparedEdit::insert` | Insert paragraphs into editable containers or positioned outlines into a page, retaining intent identities across rebases |
52| `ParagraphSplit`, `PreparedEdit::split` | Split ordinary text at a UTF-16 scalar boundary, retaining the original left identities and moving children to the right |
5253| `TextAttribute`, `PreparedEdit::format` | Change character formatting over a UTF-16 range while sharing immutable styles; preserve unselected runs |
5354| `PreparedEdit::commit`, `PreparedEdit::commit_file` | Publish the exact prepared image under caller-held exclusion or the conservative filesystem adapter |
5455| `read_file` | Read a snapshot under whole-file exclusion |
......@@ -77,6 +78,13 @@ accepts one `0..0` span for subsequent typing. Retain the `Insertion` value for
7778value creates different object identities. Duplicate insertion identities require
7879reconciliation. Formatting accepts explicit attributes, preserves inherited values,
7980and gives retired immutable styles zero current references while retaining history.
81Paragraph splits preserve character formatting, retain tags on the left, and clone
82mutable list objects without restarting numbering. The new right paragraph/text
83identities belong to the retained `ParagraphSplit` intent. Its publication includes
84the complete child graph and title metadata; repeating an existing identity requires
85reconciliation. Title containers, generated fields, recording-linked text and
86associated run metadata are rejected before I/O. Native split controls and subsequent
87typing checks reside in [the paragraph corpus](../../corpus/paragraph-edit/README.md).
8088Generated fields, protected targets and unsupported run-data boundary changes are
8189rejected before publication. Local caches expose text, insertion and formatting edits;
8290the [document-writer acceptance](../../evidence/MILESTONE9.md#document-writer-and-offline-acceptance)
......@@ -215,6 +223,7 @@ subsets of unflushed bytes and is shared with the stateful commit fuzzer.
215223```sh
216224cargo +nightly fuzz run revisions -- -max_total_time=120 -max_len=262144 -rss_limit_mb=2048
217225cargo +nightly fuzz run commit -- -max_total_time=300 -max_len=4096 -rss_limit_mb=2048
226cargo +nightly fuzz run paragraph -- -max_total_time=120 -max_len=160 -rss_limit_mb=2048
218227```
219228
220229Fuzz targets cover storage, properties, revisions, scalar edits, creation, and
crates/onestore/src/commit.rs+13
......@@ -183,6 +183,19 @@ pub struct PreparedEdit<'a> {
183183}
184184
185185impl<'a> PreparedEdit<'a> {
186 /// Splits a paragraph and updates its children, lists, tags and title metadata atomically.
187 /// Fields and associated run metadata are rejected before I/O.
188 pub fn split(
189 source: &'a [u8],
190 space: ExGuid,
191 split: &crate::ParagraphSplit,
192 ) -> Result<Self, crate::Error> {
193 Ok(Self {
194 source,
195 written: split.apply(source, space)?,
196 })
197 }
198
186199 /// Prepares an insertion and its dependent metadata in one revision, without I/O.
187200 pub fn insert(
188201 source: &'a [u8],
crates/onestore/src/lib.rs+2
......@@ -11,6 +11,7 @@ mod flush;
1111mod formatting;
1212mod insertion;
1313mod objects;
14mod paragraph;
1415mod properties;
1516#[cfg(feature = "protected")]
1617pub mod protected;
......@@ -31,6 +32,7 @@ pub use files::FileDataReference;
3132pub use formatting::TextAttribute;
3233pub use insertion::Insertion;
3334pub use objects::{Object, ObjectData, ObjectReferences, ResolvedRevision};
35pub use paragraph::ParagraphSplit;
3436pub use properties::{IdStream, Property, PropertySets, Value};
3537pub use revisions::{ExGuid, ObjectSpace, Revision, RevisionIndex};
3638pub use snapshot::{read_snapshot, read_storage_snapshot};
crates/onestore/src/paragraph.rs created+383
......@@ -0,0 +1,383 @@
1use crate::{
2 Error, ExGuid, Object, ObjectData, PropertySets, RevisionIndex, Store,
3 create::{current_timestamps, properties, string},
4 document::{Document, Element, Kind},
5 edit::{editable_parents, page_title},
6 write::{PropertyObject, fresh_guid, write_revision},
7};
8use serde::{Deserialize, Serialize};
9use std::{
10 collections::{BTreeMap, BTreeSet},
11 ops::Range,
12 sync::Arc,
13};
14
15fn invalid(message: &'static str) -> Error {
16 Error { offset: 0, message }
17}
18
19/// Splits ordinary paragraph text while retaining the new objects' identities across retries.
20/// The original paragraph/text remain on the left; nested children move to the right.
21#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
22#[serde(deny_unknown_fields)]
23pub struct ParagraphSplit {
24 guid: [u8; 16],
25 text: ExGuid,
26 offset: u32,
27 author: String,
28 created: u32,
29}
30
31impl ParagraphSplit {
32 /// The offset is measured in UTF-16 code units and must lie between Unicode scalars.
33 pub fn new(text: ExGuid, offset: u32, author: &str) -> Result<Self, Error> {
34 if text.guid == [0; 16] || author.contains('\0') {
35 return Err(invalid(
36 "Choose paragraph text and an author name without NUL",
37 ));
38 }
39 Ok(Self {
40 guid: fresh_guid()?,
41 text,
42 offset,
43 author: author.to_owned(),
44 created: current_timestamps()?.0,
45 })
46 }
47
48 /// Identity of the new right paragraph.
49 pub fn object(&self) -> ExGuid {
50 ExGuid {
51 guid: self.guid,
52 n: 1,
53 }
54 }
55
56 /// Identity of the new right paragraph's text.
57 pub fn text_object(&self) -> ExGuid {
58 ExGuid {
59 guid: self.guid,
60 n: 2,
61 }
62 }
63
64 pub(crate) fn apply(&self, source: &[u8], space: ExGuid) -> Result<Vec<u8>, Error> {
65 if self.guid == [0; 16] || self.text.guid == [0; 16] || self.author.contains('\0') {
66 return Err(invalid(
67 "Choose paragraph text and an author name without NUL",
68 ));
69 }
70 let store = Store::parse(source)?;
71 let index = RevisionIndex::parse(&store)?;
72 index.validate_current()?;
73 let mut document = Document::parse(&index)?;
74 let pages: Vec<_> = document
75 .pages()?
76 .into_iter()
77 .filter_map(|(sid, page)| (sid == space).then_some(page))
78 .collect();
79 let [page] = pages.as_slice() else {
80 return Err(invalid("Splitting requires a single active page"));
81 };
82 let semantic = document
83 .spaces
84 .remove(&space)
85 .ok_or_else(|| invalid("The active page is unavailable"))?;
86 let rid = semantic.contexts[&ExGuid::default()];
87 let mut view = semantic
88 .revisions
89 .into_iter()
90 .find_map(|(id, view)| (id == rid).then_some(view))
91 .unwrap();
92 let parents = editable_parents(&view, &pages, self.text)?;
93 let [paragraph] = parents
94 .get(&self.text)
95 .map(Vec::as_slice)
96 .unwrap_or_default()
97 else {
98 return Err(invalid("Select text belonging to one paragraph"));
99 };
100 let [parent] = parents
101 .get(paragraph)
102 .map(Vec::as_slice)
103 .unwrap_or_default()
104 else {
105 return Err(invalid("Select a paragraph with one parent"));
106 };
107 let left = &view.nodes[paragraph];
108 let Kind::Paragraph { lists, .. } = &left.kind else {
109 return Err(invalid("Select ordinary paragraph text"));
110 };
111 if left.content != [self.text]
112 || !matches!(
113 view.nodes[parent].kind,
114 Kind::Outline { .. }
115 | Kind::OutlineGroup
116 | Kind::Paragraph { .. }
117 | Kind::Cell { .. }
118 )
119 {
120 return Err(invalid(
121 "Select ordinary paragraph text inside an outline or table cell",
122 ));
123 }
124 let mut ancestors = BTreeSet::new();
125 let mut pending = vec![*paragraph];
126 while let Some(id) = pending.pop() {
127 if !ancestors.insert(id) {
128 continue;
129 }
130 if matches!(view.nodes[&id].kind, Kind::Title) {
131 return Err(invalid(
132 "Title containers cannot be split into ordinary paragraphs",
133 ));
134 }
135 pending.extend(parents.get(&id).into_iter().flatten().copied());
136 }
137 let node = &view.nodes[&self.text];
138 let Kind::RichText {
139 text,
140 runs,
141 boilerplate,
142 ..
143 } = &node.kind
144 else {
145 return Err(invalid("Select ordinary paragraph text"));
146 };
147 if *boilerplate || !node.media_ids.is_empty() || node.media_time_ms.is_some() {
148 return Err(invalid(
149 "Generated or recording-linked text cannot be split",
150 ));
151 }
152 for run in view.text_runs(self.text)? {
153 if [
154 run.format.hidden,
155 run.format.hyperlink,
156 run.format.math,
157 run.format.embedded_object,
158 ]
159 .contains(&Some(true))
160 || run.text.contains(['\u{fffc}', '\u{fddf}'])
161 {
162 return Err(invalid(
163 "This paragraph contains a field or embedded object that cannot be split",
164 ));
165 }
166 }
167 let raw = index.resolve(space, rid)?;
168 let ObjectData::Properties(blob) = raw.objects[&self.text].data else {
169 unreachable!()
170 };
171 if PropertySets::parse(blob)?.sets[0]
172 .iter()
173 .any(|p| matches!(p.id, 0x40003499 | 0x24003458))
174 {
175 return Err(invalid(
176 "This paragraph contains run metadata that cannot be split",
177 ));
178 }
179 let length = u32::try_from(text.encode_utf16().count())
180 .map_err(|_| invalid("Paragraph exceeds the UTF-16 offset range"))?;
181 if self.offset > length || lists.len() > 251 {
182 return Err(invalid(
183 "Choose a position within the paragraph and at most 251 list levels",
184 ));
185 }
186 let author_id = ExGuid {
187 guid: self.guid,
188 n: 3,
189 };
190 let normal_id = ExGuid {
191 guid: self.guid,
192 n: 4,
193 };
194 let typing = runs.last().and_then(|run| run.format).unwrap_or(normal_id);
195 let modified = current_timestamps()?.0.to_le_bytes();
196 let mut changed = BTreeMap::new();
197 if (self.offset == 0 && !text.is_empty()) || runs.iter().any(|run| run.format.is_none()) {
198 changed.insert(
199 normal_id,
200 PropertyObject {
201 jcid: 0x12004d,
202 bytes: properties(&[])?,
203 global_ids: Arc::new(BTreeMap::from([(0, self.guid)])),
204 },
205 );
206 }
207 let mut prefix = fragment(
208 &raw.objects[&self.text],
209 node,
210 0..self.offset,
211 if text.is_empty() { typing } else { normal_id },
212 )?;
213 let mut suffix = fragment(&raw.objects[&self.text], node, self.offset..length, typing)?;
214 prefix.set(&[(0x14001d7a, &modified)])?;
215 suffix.remove(&[0x40003489])?;
216 suffix.set(&[(0x14001d7a, &modified)])?;
217 suffix.reference(self.text_object())?;
218 changed.insert(self.text, prefix);
219 changed.insert(self.text_object(), suffix);
220 changed.insert(
221 author_id,
222 PropertyObject {
223 jcid: 0x120001,
224 bytes: properties(&[(0x1c001d75, string(&self.author))])?,
225 global_ids: Arc::new(BTreeMap::from([(0, self.guid)])),
226 },
227 );
228 let mut right = PropertyObject::from_object(&raw.objects[paragraph])?;
229 let content = right.reference(self.text_object())?;
230 let author = right.reference(author_id)?;
231 right.set(&[
232 (0x24001c1f, &content),
233 (0x14001d09, &self.created.to_le_bytes()),
234 (0x20001d78, &author),
235 (0x20001d79, &author),
236 (0x14001d7a, &modified),
237 ])?;
238 if !lists.is_empty() {
239 let mut references = Vec::new();
240 for (i, old) in lists.iter().enumerate() {
241 if !matches!(view.nodes[old].kind, Kind::List { .. }) {
242 return Err(invalid("The paragraph list is unavailable"));
243 }
244 let id = ExGuid {
245 guid: self.guid,
246 n: 5 + u32::try_from(i).unwrap(),
247 };
248 let mut list = PropertyObject::from_object(&raw.objects[old])?;
249 list.remove(&[0x14001cb7])?;
250 list.reference(id)?;
251 references.extend_from_slice(&right.reference(id)?);
252 changed.insert(id, list);
253 }
254 right.set(&[(0x24001c26, &references)])?;
255 }
256 changed.insert(self.object(), right);
257 let mut original = PropertyObject::from_object(&raw.objects[paragraph])?;
258 original.remove(&[0x24001c20])?;
259 let author = original.reference(author_id)?;
260 original.set(&[(0x20001d79, &author), (0x14001d7a, &modified)])?;
261 changed.insert(*paragraph, original);
262 let mut parent_object = PropertyObject::from_object(&raw.objects[parent])?;
263 let mut children = Vec::new();
264 for child in &view.nodes[parent].children {
265 children.extend_from_slice(&parent_object.reference(*child)?);
266 if child == paragraph {
267 children.extend_from_slice(&parent_object.reference(self.object())?);
268 }
269 }
270 parent_object.set(&[(0x24001c20, &children)])?;
271 changed.insert(*parent, parent_object);
272 if changed
273 .keys()
274 .any(|id| id.guid == self.guid && raw.objects.contains_key(id))
275 {
276 return Err(invalid(
277 "A split identity already exists; reconcile the existing edit",
278 ));
279 }
280 for id in ancestors {
281 let object = match changed.entry(id) {
282 std::collections::btree_map::Entry::Occupied(entry) => entry.into_mut(),
283 std::collections::btree_map::Entry::Vacant(entry) => {
284 entry.insert(PropertyObject::from_object(&raw.objects[&id])?)
285 }
286 };
287 object.set(&[(0x14001d7a, &modified)])?;
288 }
289 for (id, object) in &changed {
290 view.nodes.insert(
291 *id,
292 Element::parse(
293 &Object {
294 jcid: object.jcid,
295 reference_count: 0,
296 data: ObjectData::Properties(&object.bytes),
297 global_ids: Arc::clone(&object.global_ids),
298 },
299 &store,
300 )?,
301 );
302 }
303 let title = page_title(&view, &pages, None)?;
304 drop(view);
305 if let Some((_, automatic, title)) = title {
306 let metadata = raw
307 .roots
308 .get(&2)
309 .ok_or_else(|| invalid("Page title metadata is unavailable"))?;
310 if raw.objects[metadata].jcid != 0x20030 {
311 return Err(invalid("Page title metadata is unavailable"));
312 }
313 let title = string(&title);
314 let mut object = PropertyObject::from_object(&raw.objects[metadata])?;
315 object.set(&[(0x1c001cf3, &title)])?;
316 changed.insert(*metadata, object);
317 changed
318 .get_mut(page)
319 .unwrap()
320 .set(&[(0x1c001d3c, if automatic { &title } else { &[0, 0] })])?;
321 }
322 write_revision(source, space, |_| Ok(changed))
323 }
324}
325
326fn fragment(
327 raw: &Object<'_>,
328 node: &Element<'_>,
329 range: Range<u32>,
330 empty: ExGuid,
331) -> Result<PropertyObject, Error> {
332 let Kind::RichText { text, runs, .. } = &node.kind else {
333 return Err(invalid("Select ordinary paragraph text"));
334 };
335 let units: Vec<_> = text.encode_utf16().collect();
336 let start = usize::try_from(range.start)
337 .map_err(|_| invalid("Choose a position within the paragraph"))?;
338 let end = usize::try_from(range.end)
339 .map_err(|_| invalid("Choose a position within the paragraph"))?;
340 let slice = units
341 .get(start..end)
342 .ok_or_else(|| invalid("Choose a position within the paragraph"))?;
343 let text = String::from_utf16(slice)
344 .map_err(|_| invalid("Choose a position between Unicode scalars"))?;
345 let mut segments = Vec::new();
346 for run in runs {
347 if run.start < range.end && range.start < run.end {
348 segments.push((
349 run.end.min(range.end) - range.start,
350 run.format.unwrap_or(empty),
351 ));
352 }
353 }
354 if segments.is_empty() {
355 segments.push((0, empty));
356 }
357 if !range.is_empty() && end == units.len() {
358 let last = runs.last().unwrap();
359 if last.start == last.end {
360 segments.push((range.end - range.start, last.format.unwrap_or(empty)));
361 }
362 }
363 if segments[..segments.len() - 1]
364 .windows(2)
365 .any(|pair| pair[0].0 >= pair[1].0)
366 {
367 return Err(invalid("Text-run boundaries must be strictly increasing"));
368 }
369 let mut object = PropertyObject::from_object(raw)?;
370 let mut ends = Vec::new();
371 let mut references = Vec::new();
372 for (end, id) in segments {
373 ends.extend_from_slice(&end.to_le_bytes());
374 references.extend_from_slice(&object.reference(id)?);
375 }
376 ends.truncate(ends.len() - 4);
377 object.set(&[
378 (0x1c001c22, &string(&text)),
379 (0x1c001e12, &ends),
380 (0x24001e13, &references),
381 ])?;
382 Ok(object)
383}
crates/onestore/src/write.rs+83-9
......@@ -120,6 +120,15 @@ fn field_length(property: &crate::Property<'_>, set_lengths: &[usize]) -> usize
120120 }
121121}
122122
123fn property_set_lengths(properties: &PropertySets<'_>) -> Vec<usize> {
124 let mut lengths = vec![0; properties.sets.len()];
125 for (i, set) in properties.sets.iter().enumerate().rev() {
126 lengths[i] =
127 2 + set.len() * 4 + set.iter().map(|p| field_length(p, &lengths)).sum::<usize>();
128 }
129 lengths
130}
131
123132fn patch_properties(
124133 blob: &[u8],
125134 updates: &[(u32, &[u8])],
......@@ -130,15 +139,7 @@ fn patch_properties(
130139 let ids = properties.root_ids.as_ptr().addr() - blob.as_ptr().addr();
131140 let ids_end = ids + properties.root_ids.len();
132141 let body_end = blob.len() - properties.padding.len();
133 let mut set_lengths = vec![0; properties.sets.len()];
134 for (i, set) in properties.sets.iter().enumerate().rev() {
135 set_lengths[i] = 2
136 + set.len() * 4
137 + set
138 .iter()
139 .map(|p| field_length(p, &set_lengths))
140 .sum::<usize>();
141 }
142 let set_lengths = property_set_lengths(&properties);
142143 let mut offsets = Vec::with_capacity(root.len());
143144 let mut offset = ids_end;
144145 for property in root {
......@@ -379,6 +380,79 @@ impl PropertyObject {
379380 Ok(())
380381 }
381382
383 pub fn remove(&mut self, ids: &[u32]) -> Result<()> {
384 let properties = PropertySets::parse(&self.bytes)?;
385 let removed = |id: u32| {
386 ids.iter()
387 .any(|wanted| id & 0x7fffffff == wanted & 0x7fffffff)
388 };
389 if !properties.sets[0].iter().any(|p| removed(p.id)) {
390 return Ok(());
391 }
392 let lengths = property_set_lengths(&properties);
393 let mut offset = properties.root_ids.as_ptr().addr() - self.bytes.as_ptr().addr()
394 + properties.root_ids.len();
395 let mut retained_ids = Vec::new();
396 let mut fields = Vec::new();
397 let mut references: [Vec<u8>; 3] = std::array::from_fn(|_| Vec::new());
398 for property in &properties.sets[0] {
399 let end = offset + field_length(property, &lengths);
400 if !removed(property.id) {
401 retained_ids.extend_from_slice(&property.id.to_le_bytes());
402 fields.extend_from_slice(&self.bytes[offset..end]);
403 let mut pending = vec![property];
404 while let Some(field) = pending.pop() {
405 match &field.value {
406 Value::References {
407 stream,
408 compact_ids,
409 } => {
410 let index = match stream {
411 crate::IdStream::Objects => 0,
412 crate::IdStream::ObjectSpaces => 1,
413 crate::IdStream::Contexts => 2,
414 };
415 references[index].extend_from_slice(compact_ids);
416 }
417 Value::Sets(children) => {
418 for child in children.clone().rev() {
419 pending.extend(properties.sets[child].iter().rev());
420 }
421 }
422 _ => {}
423 }
424 }
425 }
426 offset = end;
427 }
428 let mut cursor = crate::bytes::Cursor {
429 bytes: &self.bytes,
430 offset: 0,
431 };
432 let streams = crate::properties::reference_streams(&mut cursor)?;
433 let mut bytes = Vec::new();
434 for (stream, retained) in streams.iter().zip(&references) {
435 if stream.offset == 0 {
436 continue;
437 }
438 let header = u32::from_le_bytes(
439 self.bytes[stream.offset - 4..stream.offset]
440 .try_into()
441 .unwrap(),
442 );
443 let count = u32::try_from(retained.len() / 4).unwrap();
444 bytes.extend_from_slice(&((header & 0xff000000) | count).to_le_bytes());
445 bytes.extend_from_slice(retained);
446 }
447 bytes.extend_from_slice(&u16::try_from(retained_ids.len() / 4).unwrap().to_le_bytes());
448 bytes.extend_from_slice(&retained_ids);
449 bytes.extend_from_slice(&fields);
450 bytes.resize(bytes.len().next_multiple_of(8), 0);
451 PropertySets::parse(&bytes)?;
452 self.bytes = bytes;
453 Ok(())
454 }
455
382456 pub fn reference(&mut self, id: ExGuid) -> Result<[u8; 4]> {
383457 if !self.global_ids.values().any(|guid| *guid == id.guid) {
384458 let mut index = 0;
crates/onestore/src/write/tests.rs+54
......@@ -46,6 +46,8 @@ fn document_insertions_and_formatting_respect_readonly_ancestors() {
4646 .iter()
4747 .find_map(|(id, object)| (object.jcid == 0x6000e).then_some(*id))
4848 .unwrap();
49 let split = crate::ParagraphSplit::new(text, 1, "Author").unwrap();
50 assert!(PreparedEdit::split(&protected, sid, &split).is_err());
4951 assert!(
5052 PreparedEdit::format(
5153 &protected,
......@@ -531,6 +533,45 @@ fn nested_fields_and_other_reference_streams_remain_byte_exact() {
531533 );
532534 assert_eq!(&changed[20..36], &original[16..32]);
533535 assert_eq!(parsed.sets[0][3].value, Value::Bytes(&[96, 97, 98, 99]));
536
537 for removed in 0..16 {
538 let ids: Vec<_> = previous.sets[0]
539 .iter()
540 .enumerate()
541 .filter_map(|(i, property)| (removed & (1 << i) != 0).then_some(property.id))
542 .collect();
543 let mut object = super::PropertyObject {
544 jcid: 0x6000e,
545 bytes: original.clone(),
546 global_ids: Default::default(),
547 };
548 object.remove(&ids).unwrap();
549 let parsed = PropertySets::parse(&object.bytes).unwrap();
550 assert!(
551 parsed.sets[0]
552 .iter()
553 .eq(previous.sets[0].iter().filter(|p| !ids.contains(&p.id)))
554 );
555 if removed & 2 == 0 {
556 assert_eq!(parsed.sets[1], previous.sets[1]);
557 assert_eq!(
558 object
559 .bytes
560 .windows(nested.len())
561 .filter(|bytes| *bytes == nested)
562 .count(),
563 1
564 );
565 } else {
566 assert_eq!(parsed.sets.len(), 1);
567 }
568 if removed == 0 {
569 assert_eq!(object.bytes, original);
570 }
571 let before = object.bytes.clone();
572 object.remove(&ids).unwrap();
573 assert_eq!(object.bytes, before);
574 }
534575}
535576
536577#[test]
......@@ -549,6 +590,19 @@ fn deep_property_splices_do_not_use_the_call_stack() {
549590 &changed[14..changed.len() - parsed.padding.len()],
550591 &bytes[10..]
551592 );
593 let mut object = super::PropertyObject {
594 jcid: 0x6000e,
595 bytes: changed,
596 global_ids: Default::default(),
597 };
598 object.remove(&[0x08000002]).unwrap();
599 let parsed = PropertySets::parse(&object.bytes).unwrap();
600 assert_eq!(parsed.sets.len(), 100_001);
601 assert_eq!(&object.bytes[..bytes.len()], &bytes);
602 object.remove(&[0x44000001]).unwrap();
603 let parsed = PropertySets::parse(&object.bytes).unwrap();
604 assert_eq!(parsed.sets.len(), 1);
605 assert!(parsed.sets[0].is_empty());
552606}
553607
554608#[test]
crates/onestore/tests/paragraph.rs created+343
......@@ -0,0 +1,343 @@
1use onestore::{
2 ExGuid, ParagraphSplit, PreparedEdit, RevisionIndex, Store,
3 document::{Document, Kind, Revision},
4};
5use serde_json::Value;
6
7#[path = "support/checkpoint.rs"]
8mod checkpoint;
9#[path = "support/current.rs"]
10mod current;
11#[path = "support/disk.rs"]
12mod disk;
13
14const SOURCE: &[u8] =
15 include_bytes!("../../../corpus/paragraph-edit/before/notebook/synthetic.one");
16
17fn characters(view: &Revision<'_>, id: ExGuid) -> Vec<(char, Value)> {
18 view.text_runs(id)
19 .unwrap()
20 .into_iter()
21 .flat_map(|run| {
22 let format = serde_json::to_value(run.format).unwrap();
23 run.text.chars().map(move |c| (c, format.clone()))
24 })
25 .collect()
26}
27
28#[test]
29fn splits_partition_native_paragraphs_at_every_scalar_boundary() {
30 let manifest: Value =
31 serde_json::from_str(include_str!("../../../corpus/paragraph-edit/manifest.json")).unwrap();
32 let store = Store::parse(SOURCE).unwrap();
33 let index = RevisionIndex::parse(&store).unwrap();
34 let document = Document::parse(&index).unwrap();
35 for case in manifest["cases"].as_array().unwrap() {
36 let text: ExGuid = serde_json::from_value(case["original_text"].clone()).unwrap();
37 let paragraph: ExGuid = serde_json::from_value(case["original_paragraph"].clone()).unwrap();
38 let (sid, space) = document
39 .spaces
40 .iter()
41 .find(|(_, space)| {
42 space.revisions[&space.contexts[&ExGuid::default()]]
43 .nodes
44 .contains_key(&text)
45 })
46 .unwrap();
47 let before = &space.revisions[&space.contexts[&ExGuid::default()]];
48 let (parent, parent_node) = before
49 .nodes
50 .iter()
51 .find(|(_, node)| node.children.contains(&paragraph))
52 .unwrap();
53 let expected = characters(before, text);
54 let offsets: Vec<u32> = std::iter::once(0)
55 .chain(expected.iter().scan(0, |offset, (c, _)| {
56 *offset += u32::try_from(c.len_utf16()).unwrap();
57 Some(*offset)
58 }))
59 .collect();
60 for (position, offset) in offsets.iter().enumerate() {
61 let intent = ParagraphSplit::new(text, *offset, "Split author").unwrap();
62 let restored = serde_json::from_value(serde_json::to_value(&intent).unwrap()).unwrap();
63 assert_eq!(intent, restored);
64 let edited = PreparedEdit::split(SOURCE, *sid, &restored);
65 if case["case"] == "Split before hyperlink" {
66 assert!(edited.is_err());
67 continue;
68 }
69 let edited =
70 edited.unwrap_or_else(|error| panic!("{} at {offset}: {error}", case["case"]));
71 let current_store = Store::parse(edited.as_bytes()).unwrap();
72 assert_eq!(
73 current_store.header.transaction_count,
74 store.header.transaction_count + 1
75 );
76 let current_index = RevisionIndex::parse(&current_store).unwrap();
77 current_index.validate_current().unwrap();
78 let current_document = Document::parse(&current_index).unwrap();
79 let current_space = &current_document.spaces[sid];
80 let after = &current_space.revisions[&current_space.contexts[&ExGuid::default()]];
81 let mut changed = std::collections::BTreeSet::from([text, before.roots[&2]]);
82 let mut pending = vec![paragraph];
83 while let Some(id) = pending.pop() {
84 if !changed.insert(id) {
85 continue;
86 }
87 pending.extend(before.nodes.iter().filter_map(|(parent, node)| {
88 node.children
89 .iter()
90 .chain(&node.content)
91 .chain(&node.structure)
92 .any(|child| *child == id)
93 .then_some(*parent)
94 }));
95 }
96 let old_raw = index
97 .resolve(*sid, space.contexts[&ExGuid::default()])
98 .unwrap();
99 let new_raw = current_index
100 .resolve(*sid, current_space.contexts[&ExGuid::default()])
101 .unwrap();
102 for (id, object) in old_raw.objects {
103 if !changed.contains(&id) {
104 assert_eq!(object.data, new_raw.objects[&id].data, "untouched {id}");
105 }
106 }
107 assert_eq!(
108 characters(after, text),
109 expected[..position],
110 "{} prefix at {offset}",
111 case["case"]
112 );
113 assert_eq!(
114 characters(after, intent.text_object()),
115 expected[position..],
116 "{} suffix at {offset}",
117 case["case"]
118 );
119 let mut children = parent_node.children.clone();
120 children.insert(
121 children.iter().position(|id| *id == paragraph).unwrap() + 1,
122 intent.object(),
123 );
124 assert_eq!(after.nodes[parent].children, children);
125 assert_eq!(after.nodes[&paragraph].content, [text]);
126 assert!(after.nodes[&paragraph].children.is_empty());
127 assert_eq!(
128 after.nodes[&intent.object()].content,
129 [intent.text_object()]
130 );
131 assert_eq!(
132 after.nodes[&intent.object()].children,
133 before.nodes[&paragraph].children
134 );
135 assert_eq!(
136 serde_json::to_value(&after.nodes[&text].tags).unwrap(),
137 serde_json::to_value(&before.nodes[&text].tags).unwrap()
138 );
139 assert!(after.nodes[&intent.text_object()].tags.is_empty());
140 let Kind::Paragraph {
141 lists: old_lists, ..
142 } = &before.nodes[&paragraph].kind
143 else {
144 panic!()
145 };
146 let Kind::Paragraph { lists, .. } = &after.nodes[&intent.object()].kind else {
147 panic!()
148 };
149 assert_eq!(old_lists.len(), lists.len());
150 for (old, new) in old_lists.iter().zip(lists) {
151 assert_ne!(old, new);
152 let mut old = serde_json::to_value(&before.nodes[old]).unwrap();
153 old["kind"]["restart"] = Value::Null;
154 assert_eq!(serde_json::to_value(&after.nodes[new]).unwrap(), old);
155 }
156 for (space_id, old_space) in &index.spaces {
157 for revision in old_space.revisions.keys() {
158 let old = index.resolve(*space_id, *revision).unwrap();
159 let retained = current_index.resolve(*space_id, *revision).unwrap();
160 assert_eq!(old.roots, retained.roots);
161 for (id, object) in old.objects {
162 assert_eq!(object.data, retained.objects[&id].data);
163 }
164 }
165 }
166 assert!(PreparedEdit::split(edited.as_bytes(), *sid, &intent).is_err());
167 }
168 for offset in 0..=*offsets.last().unwrap() + 1 {
169 if offsets.contains(&offset) {
170 continue;
171 }
172 let intent = ParagraphSplit::new(text, offset, "Author").unwrap();
173 assert!(PreparedEdit::split(SOURCE, *sid, &intent).is_err());
174 }
175 }
176}
177
178#[test]
179fn invalid_split_identities_and_title_targets_are_rejected() {
180 assert!(ParagraphSplit::new(ExGuid::default(), 0, "Author").is_err());
181 let manifest: Value =
182 serde_json::from_str(include_str!("../../../corpus/paragraph-edit/manifest.json")).unwrap();
183 let text: ExGuid =
184 serde_json::from_value(manifest["cases"][0]["original_text"].clone()).unwrap();
185 assert!(ParagraphSplit::new(text, 0, "a\0b").is_err());
186 let store = Store::parse(SOURCE).unwrap();
187 let index = RevisionIndex::parse(&store).unwrap();
188 let document = Document::parse(&index).unwrap();
189 let sid = *document
190 .spaces
191 .iter()
192 .find(|(_, space)| {
193 space.revisions[&space.contexts[&ExGuid::default()]]
194 .nodes
195 .contains_key(&text)
196 })
197 .unwrap()
198 .0;
199 let intent = ParagraphSplit::new(text, 1, "Author").unwrap();
200 for (field, value) in [
201 ("guid", serde_json::to_value([0_u8; 16]).unwrap()),
202 ("guid", serde_json::to_value(text.guid).unwrap()),
203 ("text", serde_json::to_value(ExGuid::default()).unwrap()),
204 ("author", serde_json::json!("a\0b")),
205 ("offset", serde_json::json!(u32::MAX)),
206 ] {
207 let mut encoded = serde_json::to_value(&intent).unwrap();
208 encoded[field] = value;
209 let forged = serde_json::from_value(encoded).unwrap();
210 assert!(PreparedEdit::split(SOURCE, sid, &forged).is_err());
211 }
212 let mut titles = 0;
213 for (sid, _) in document.pages().unwrap() {
214 let space = &document.spaces[&sid];
215 let view = &space.revisions[&space.contexts[&ExGuid::default()]];
216 let mut pending: Vec<_> = view
217 .nodes
218 .iter()
219 .filter_map(|(id, n)| matches!(n.kind, Kind::Title).then_some(*id))
220 .collect();
221 let mut seen = std::collections::BTreeSet::new();
222 while let Some(id) = pending.pop() {
223 if !seen.insert(id) {
224 continue;
225 }
226 let node = &view.nodes[&id];
227 pending.extend(node.children.iter().chain(&node.content).copied());
228 if matches!(node.kind, Kind::RichText { .. }) {
229 let intent = ParagraphSplit::new(id, 0, "Author").unwrap();
230 assert!(PreparedEdit::split(SOURCE, sid, &intent).is_err());
231 titles += 1;
232 }
233 }
234 }
235 assert!(titles >= 14);
236}
237
238#[test]
239#[ignore = "exports paragraph splits for independent native validation"]
240fn export_native_paragraph_splits() {
241 use std::{fs, path::PathBuf};
242 let output = PathBuf::from(std::env::var_os("ONESTORE_PARAGRAPH_OUTPUT").unwrap());
243 assert!(output.is_absolute());
244 fs::create_dir(&output).unwrap();
245 let manifest: Value =
246 serde_json::from_str(include_str!("../../../corpus/paragraph-edit/manifest.json")).unwrap();
247 let mut source = SOURCE.to_vec();
248 let mut written = Vec::new();
249 for case in manifest["cases"].as_array().unwrap() {
250 if case["case"] == "Split before hyperlink" {
251 continue;
252 }
253 let text: ExGuid = serde_json::from_value(case["original_text"].clone()).unwrap();
254 let store = Store::parse(&source).unwrap();
255 let index = RevisionIndex::parse(&store).unwrap();
256 let document = Document::parse(&index).unwrap();
257 let sid = *document
258 .spaces
259 .iter()
260 .find(|(_, space)| {
261 space.revisions[&space.contexts[&ExGuid::default()]]
262 .nodes
263 .contains_key(&text)
264 })
265 .unwrap()
266 .0;
267 let intent = ParagraphSplit::new(
268 text,
269 serde_json::from_value(case["offset_utf16"].clone()).unwrap(),
270 "Rust split author",
271 )
272 .unwrap();
273 let edited = PreparedEdit::split(&source, sid, &intent).unwrap();
274 written.push(serde_json::json!({"case": case["case"], "intent": intent,
275 "new_paragraph": intent.object(), "new_text": intent.text_object()}));
276 source = edited.as_bytes().to_vec();
277 }
278 let candidate = output.join("candidate");
279 fs::create_dir(&candidate).unwrap();
280 fs::write(candidate.join("synthetic.one"), source).unwrap();
281 fs::write(
282 output.join("manifest.json"),
283 serde_json::to_vec_pretty(&serde_json::json!({"cases": written})).unwrap(),
284 )
285 .unwrap();
286}
287
288#[test]
289fn interrupted_splits_publish_a_complete_graph_or_retain_the_original() {
290 let original = onestore::create_section("split.one", "Original", "Author").unwrap();
291 let store = Store::parse(&original).unwrap();
292 let index = RevisionIndex::parse(&store).unwrap();
293 let document = Document::parse(&index).unwrap();
294 let (sid, page) = document.pages().unwrap()[0];
295 let space = &document.spaces[&sid];
296 let view = &space.revisions[&space.contexts[&ExGuid::default()]];
297 let outline = view.nodes[&page]
298 .children
299 .iter()
300 .find(|id| matches!(view.nodes[id].kind, Kind::Outline { .. }))
301 .unwrap();
302 let paragraph = view.nodes[outline].children[0];
303 let insertion = onestore::Insertion::paragraph(paragraph, None, "a🦀b", "Author")
304 .unwrap()
305 .with_formatting(1..3, &[onestore::TextAttribute::Bold(true)])
306 .unwrap();
307 let inserted = PreparedEdit::insert(&original, sid, &insertion).unwrap();
308 let source = inserted.as_bytes();
309 let checkpoint = checkpoint::pending(source, sid, insertion.text_object(), 0x14001d7a);
310 for source in [source, &checkpoint] {
311 let intent = ParagraphSplit::new(insertion.text_object(), 1, "Author").unwrap();
312 let edit = PreparedEdit::split(source, sid, &intent).unwrap();
313 let before = current::current(source);
314 let after = current::current(edit.as_bytes());
315 for write_limit in [17, 4096] {
316 let disk = |fail_at| disk::Disk {
317 visible: source.to_vec(),
318 durable: source.to_vec(),
319 operation: 0,
320 fail_at,
321 write_limit,
322 random: 347,
323 };
324 let mut successful = disk(None);
325 edit.commit(&mut successful).unwrap();
326 assert_eq!(successful.durable, edit.as_bytes());
327 for at in 1..=successful.operation {
328 let mut interrupted = disk(Some(at));
329 let error = edit.commit(&mut interrupted).unwrap_err();
330 let recovered = current::current(&interrupted.durable);
331 assert!(
332 recovered == before || recovered == after,
333 "interruption {at}"
334 );
335 match error.state {
336 onestore::CommitState::NotCommitted => assert_eq!(recovered, before),
337 onestore::CommitState::Committed => assert_eq!(recovered, after),
338 onestore::CommitState::Unknown => {}
339 }
340 }
341 }
342 }
343}
fuzz/Cargo.toml+7
......@@ -84,3 +84,10 @@ path = "fuzz_targets/insert.rs"
8484test = false
8585doc = false
8686bench = false
87
88[[bin]]
89name = "paragraph"
90path = "fuzz_targets/paragraph.rs"
91test = false
92doc = false
93bench = false
fuzz/fuzz_targets/paragraph.rs created+144
......@@ -0,0 +1,144 @@
1#![no_main]
2use libfuzzer_sys::fuzz_target;
3use onestore::{
4 CommitState, ExGuid, Insertion, ParagraphSplit, PreparedEdit, RevisionIndex, Store,
5 TextAttribute as A,
6 document::{Document, Kind},
7};
8use std::sync::LazyLock;
9
10#[path = "../../crates/onestore/tests/support/current.rs"]
11mod current;
12#[path = "../../crates/onestore/tests/support/disk.rs"]
13mod disk;
14
15static SOURCE: LazyLock<(Vec<u8>, ExGuid, ExGuid)> = LazyLock::new(|| {
16 let source = onestore::create_section("paragraph.one", "Original", "Author").unwrap();
17 let store = Store::parse(&source).unwrap();
18 let index = RevisionIndex::parse(&store).unwrap();
19 let document = Document::parse(&index).unwrap();
20 let (sid, page) = document.pages().unwrap()[0];
21 let space = &document.spaces[&sid];
22 let view = &space.revisions[&space.contexts[&ExGuid::default()]];
23 let outline = *view.nodes[&page]
24 .children
25 .iter()
26 .find(|id| matches!(view.nodes[id].kind, Kind::Outline { .. }))
27 .unwrap();
28 let parent = view.nodes[&outline].children[0];
29 let intent = Insertion::paragraph(parent, None, "a🦀 e\u{301} 東京\rEnd", "Author")
30 .unwrap()
31 .with_formatting(0..4, &[A::Bold(true)])
32 .unwrap()
33 .with_formatting(4..7, &[A::Italic(true), A::Color(Some([12, 34, 56]))])
34 .unwrap();
35 let edited = PreparedEdit::insert(&source, sid, &intent).unwrap();
36 (edited.as_bytes().to_vec(), sid, outline)
37});
38
39fuzz_target!(|input: &[u8]| {
40 let (source, sid, outline) = &*SOURCE;
41 if let Ok(intent) = serde_json::from_slice::<ParagraphSplit>(input)
42 && let Ok(edit) = PreparedEdit::split(source, *sid, &intent)
43 {
44 current::current(edit.as_bytes());
45 }
46 let mut persisted = source.clone();
47 let mut caches = std::array::from_fn::<_, 12, _>(|_| source.clone());
48 for step in input.chunks_exact(8).take(20) {
49 let actor = usize::from(step[0]) % caches.len();
50 if step[1] % 3 == 0 {
51 caches[actor].clone_from(&persisted);
52 }
53 let source = &caches[actor];
54 let store = Store::parse(source).unwrap();
55 let index = RevisionIndex::parse(&store).unwrap();
56 let document = Document::parse(&index).unwrap();
57 let space = &document.spaces[sid];
58 let view = &space.revisions[&space.contexts[&ExGuid::default()]];
59 let mut pending = vec![*outline];
60 let mut paragraphs = Vec::new();
61 while let Some(id) = pending.pop() {
62 let node = &view.nodes[&id];
63 pending.extend(node.children.iter().copied());
64 if matches!(node.kind, Kind::Paragraph { .. }) {
65 paragraphs.push(id);
66 }
67 }
68 let paragraph = paragraphs[usize::from(step[2]) % paragraphs.len()];
69 let text = view.nodes[&paragraph].content[0];
70 let characters: Vec<_> = view
71 .text_runs(text)
72 .unwrap()
73 .into_iter()
74 .flat_map(|run| {
75 let style = serde_json::to_value(run.format).unwrap();
76 run.text.chars().map(move |c| (c, style.clone()))
77 })
78 .collect();
79 let offsets: Vec<u32> = std::iter::once(0)
80 .chain(characters.iter().scan(0, |n, (c, _)| {
81 *n += u32::try_from(c.len_utf16()).unwrap();
82 Some(*n)
83 }))
84 .collect();
85 let offset = u32::from(step[3]) % (offsets.last().unwrap() + 2);
86 let intent = ParagraphSplit::new(text, offset, "Paragraph fuzz").unwrap();
87 let intent = serde_json::from_value(serde_json::to_value(intent).unwrap()).unwrap();
88 let edit = PreparedEdit::split(source, *sid, &intent);
89 let Some(position) = offsets.iter().position(|n| *n == offset) else {
90 assert!(edit.is_err());
91 continue;
92 };
93 let edit = edit.unwrap();
94 let after_store = Store::parse(edit.as_bytes()).unwrap();
95 let after_index = RevisionIndex::parse(&after_store).unwrap();
96 let after_document = Document::parse(&after_index).unwrap();
97 let space = &after_document.spaces[sid];
98 let after_view = &space.revisions[&space.contexts[&ExGuid::default()]];
99 for (id, expected) in [
100 (text, &characters[..position]),
101 (intent.text_object(), &characters[position..]),
102 ] {
103 let actual: Vec<_> = after_view
104 .text_runs(id)
105 .unwrap()
106 .into_iter()
107 .flat_map(|run| {
108 let style = serde_json::to_value(run.format).unwrap();
109 run.text.chars().map(move |c| (c, style.clone()))
110 })
111 .collect();
112 assert_eq!(actual, expected);
113 }
114 assert!(after_view.nodes[&paragraph].children.is_empty());
115 assert_eq!(
116 after_view.nodes[&intent.object()].children,
117 view.nodes[&paragraph].children
118 );
119 let before = current::current(&persisted);
120 let after = current::current(edit.as_bytes());
121 let mut disk = disk::Disk {
122 visible: persisted.clone(),
123 durable: persisted.clone(),
124 operation: 0,
125 fail_at: (step[4] != 0).then_some(usize::from(u16::from_le_bytes([step[4], step[5]]))),
126 write_limit: if step[6] & 1 == 0 { 17 } else { 4096 },
127 random: u64::from(step[7]) + 1,
128 };
129 let result = edit.commit(&mut disk);
130 let observed = current::current(&disk.durable);
131 match result {
132 Ok(()) => assert_eq!(observed, after),
133 Err(error) => {
134 assert!(observed == before || observed == after);
135 match error.state {
136 CommitState::NotCommitted => assert_eq!(observed, before),
137 CommitState::Committed => assert_eq!(observed, after),
138 CommitState::Unknown => {}
139 }
140 }
141 }
142 persisted = disk.durable;
143 }
144});
tools/test_paragraph_edit.py+60-1
......@@ -8,7 +8,7 @@ import unittest
88import xml.etree.ElementTree as ET
99
1010from document_model import EXPORTER, ordered_pages, walk
11from native_format import native_characters
11from native_format import compare_formats, native_characters
1212from native_xml import ns
1313
1414ROOT = Path(__file__).resolve().parent.parent
......@@ -17,6 +17,65 @@ compare = runpy.run_path(str(ROOT / 'tools/verify-document.py'))['compare']
1717
1818
1919class ParagraphEditTest(unittest.TestCase):
20 def test_rust_splits_match_native_controls_and_preserve_empty_typing_styles(self):
21 fixture = FIXTURE / 'rust-split'
22 manifest = json.loads((fixture / 'manifest.json').read_text())
23 with TemporaryDirectory() as temporary:
24 for source, capture in [('candidate', 'native'), ('native/notebook', 'native'),
25 ('typed/notebook', 'typed')]:
26 native = Path(temporary) / source.replace('/', '-') / 'read'
27 shutil.copytree(fixture / capture / 'read', native)
28 compare(fixture / source, native)
29 subprocess.run([EXPORTER, fixture / 'candidate/synthetic.one', Path(temporary) / 'model'], check=True)
30 model = json.loads((Path(temporary) / 'model/document.json').read_text())
31 subprocess.run([EXPORTER, fixture / 'native/notebook/synthetic.one', Path(temporary) / 'saved'], check=True)
32 saved = json.loads((Path(temporary) / 'saved/document.json').read_text())
33 views = {r['nodes'][r['roots']['2']]['kind']['title']: (r, page)
34 for _, _, r, page in ordered_pages(model)}
35 saved_views = {r['nodes'][r['roots']['2']]['kind']['title']: (r, page)
36 for _, _, r, page in ordered_pages(saved)}
37 text_nodes = {}
38 for name, (revision, page) in views.items():
39 current, current_page = saved_views[name]
40 self.assertEqual(page, current_page)
41 text_nodes[name] = []
42 for outline in revision['nodes'][page]['children']:
43 if revision['nodes'][outline]['kind']['type'] != 'Outline': continue
44 for oid, node in walk(revision, outline):
45 self.assertEqual(current['nodes'][oid]['children'], node['children'])
46 self.assertEqual(current['nodes'][oid]['content'], node['content'])
47 if node['kind']['type'] == 'RichText': text_nodes[name].append(node)
48 captures = {}
49 for phase, folder in [('native', fixture / 'native/read'), ('typed', fixture / 'typed/read'),
50 ('control', FIXTURE / 'cold-split/read')]:
51 captures[phase] = {}
52 for path in folder.glob('page-*.xml'):
53 page = ET.parse(path).getroot()
54 captures[phase][page.get('name')] = native_characters(page, page.findall('one:Outline', ns))
55 self.assertEqual(len(captures[phase]), 14)
56 cases = [c for c in manifest['cases'] if 'intent' in c]
57 self.assertEqual(len(cases), 12)
58 for case in cases:
59 name = case['case']
60 with self.subTest(case=name):
61 for a, b in zip(captures['native'][name], captures['control'][name], strict=True):
62 for (c, left), (d, right) in zip(a, b, strict=True):
63 self.assertEqual(c, d)
64 for key in left.keys() | right.keys():
65 default = 'automatic' if key in ('color', 'highlight') else False
66 self.assertEqual(left.get(key, default), right.get(key, default))
67 selections = json.loads((fixture / 'typed/ui/selections.json').read_text())
68 self.assertEqual(len(selections), 4)
69 for selection in selections:
70 node = text_nodes[selection['case']][selection['index']]
71 self.assertEqual(node['kind']['text'], '')
72 self.assertEqual(len(node['kind']['runs']), 1)
73 node['kind']['text'] = selection['text']
74 node['kind']['runs'][0]['end'] = len(selection['text'].encode('utf-16-le')) // 2
75 for name, (revision, page) in views.items():
76 _, differences = compare_formats(revision, text_nodes[name], captures['typed'][name])
77 self.assertEqual(differences, [], name)
78
2079 def test_native_split_join_graphs_styles_and_identity_boundaries(self):
2180 manifest = json.loads((FIXTURE / 'manifest.json').read_text())
2281 models, native = {}, {}