| author | |
| committer | |
| log | 94b162d4813c318a27b96cc9f1923bd80c21c1d6 |
| tree | 99056cb9a0b9ca3d42b80f18a50740a5c699dbd5 |
| parent | 3d72c72fcc4bf5ea8b86377b6117843fea073b61 |
| signature | Signed by SSH key SHA256:52mNGHRsVFBDED9IAX5pe+LRWUefqTbxEReunq21QvU |
`Notebook` now runs over a `Storage` trait: a mounted directory or an SMB share
(`Notebook::open_smb`), so sections and groups are created, renamed, coloured, ordered
and deleted on the share too. The native-compatible SMB client gained file creation,
directory creation, rename (`FileRenameInformation`), delete-on-close and header placement
(`onestore::place` on any `CommitIo`); `smb::tests::live_structure` runs against the Samba
lab VM through `tools/test_smb_structure.py`.
Page copies cover nested tables and paragraph subtrees inside new cells: the place pass
builds tables round by round as their holders appear, and a run's language id is a text
attribute the formatting writer sets. Pages whose indent levels only an outline group can
carry refuse to copy, since the model holds no outline groups. `corpus/page-copy` grows to
seventeen copied pages.
Assisted-by: claude-fable-5.177 files changed, 865 insertions(+), 191 deletions(-)
corpus/page-copy/README.md+4-1| ... | ... | @@ -6,7 +6,10 @@ |
| 6 | 6 | `Section::import_page` copied one page from each of eight earlier rows (text |
| 7 | 7 | with an attachment and its icon, a table, an inserted picture, a page-level |
| 8 | 8 | ink drawing, note tags, bullets and numbering, equations, paragraph |
| 9 | formatting), each as a page creation and a save queued through the replica | |
| 9 | formatting) and the `table-edit/nested` pages whose indent levels the model | |
| 10 | can express (nested tables, cell subtrees, mixed languages; four outdent | |
| 11 | pages need outline groups and refuse), each as a page creation and a save | |
| 12 | queued through the replica | |
| 10 | 13 | and published to the file; the last copy (paragraph formatting) was then deleted permanently |
| 11 | 14 | through `Section::delete_pages` (`expected-count.txt` is the page count |
| 12 | 15 | left). Every object carries a fresh identity (`Page::copy`), paragraph |
corpus/page-copy/candidate/Open Notebook.onetoc2| Binary files a/corpus/page-copy/candidate/Open Notebook.onetoc2 and b/corpus/page-copy/candidate/Open Notebook.onetoc2 differ |
corpus/page-copy/candidate/copies.one| Binary files a/corpus/page-copy/candidate/copies.one and b/corpus/page-copy/candidate/copies.one differ |
corpus/page-copy/candidate/expected-count.txt+1-1| ... | ... | @@ -1 +1 @@ |
| 1 | 9 | |
| \ No newline at end of file | ||
| 1 | 17 | |
| \ No newline at end of file |
corpus/page-copy/cold/commands.jsonl+1-1| ... | ... | @@ -1,3 +1,3 @@ |
| 1 | 1 | {"command": "powershell -NoProfile -Command \"Expand-Archive -LiteralPath C:\\one-tests\\transfer.zip -DestinationPath C:\\one-tests\\runs\\capture\\notebook\"", "exit": 0, "stdout": "", "stderr": "", "error": null} |
| 2 | {"command": "powershell -NoProfile -NonInteractive -ExecutionPolicy Bypass -File C:\\one-tests\\read-current.ps1 -Root C:\\one-tests\\runs\\capture -CloneHost ONE-M6-1C0F2CDE -ExpectedPages 9 -KeepOpen", "exit": 0, "stdout": "Read 1 sections and 9 pages.\r\n", "stderr": "", "error": null} | |
| 2 | {"command": "powershell -NoProfile -NonInteractive -ExecutionPolicy Bypass -File C:\\one-tests\\read-current.ps1 -Root C:\\one-tests\\runs\\capture -CloneHost ONE-M6-33218F72 -ExpectedPages 17 -KeepOpen", "exit": 0, "stdout": "Read 1 sections and 17 pages.\r\n", "stderr": "", "error": null} | |
| 3 | 3 | {"command": "powershell -NoProfile -Command \"Compress-Archive -Force -Path C:\\one-tests\\runs\\capture\\* -DestinationPath C:\\one-tests\\captured.zip\"", "exit": 0, "stdout": "", "stderr": "", "error": null} |
corpus/page-copy/cold/machine.json+1-1| ... | ... | @@ -1 +1 @@ |
| 1 | {"name": "m6-1c0f2cde", "hostname": "ONE-M6-1C0F2CDE"} | |
| 1 | {"name": "m6-33218f72", "hostname": "ONE-M6-33218F72"} |
corpus/page-copy/cold/notebook/Open Notebook.onetoc2| Binary files a/corpus/page-copy/cold/notebook/Open Notebook.onetoc2 and b/corpus/page-copy/cold/notebook/Open Notebook.onetoc2 differ |
corpus/page-copy/cold/notebook/copies.one| Binary files a/corpus/page-copy/cold/notebook/copies.one and b/corpus/page-copy/cold/notebook/copies.one differ |
corpus/page-copy/cold/notebook/expected-count.txt+1-1| ... | ... | @@ -1 +1 @@ |
| 1 | 9 | |
| \ No newline at end of file | ||
| 1 | 17 | |
| \ No newline at end of file |
corpus/page-copy/cold/read/environment.json+1-1| ... | ... | @@ -1,7 +1,7 @@ |
| 1 | 1 | { |
| 2 | 2 | "powershell": "5.1.14409.1005", |
| 3 | 3 | "schema": "xs2010", |
| 4 | "hostname": "ONE-M6-1C0F2CDE", | |
| 4 | "hostname": "ONE-M6-33218F72", | |
| 5 | 5 | "cold": true, |
| 6 | 6 | "onenote": "14.0.4763.1000" |
| 7 | 7 | } |
corpus/page-copy/cold/read/hierarchy.xml+1-1| ... | ... | @@ -1,2 +1,2 @@ |
| 1 | 1 | <?xml version="1.0"?> |
| 2 | <one:Notebook xmlns:one="http://schemas.microsoft.com/office/onenote/2010/onenote" name="notebook" nickname="notebook" ID="{CA49439A-5FEF-43A6-AB60-E8C051A59087}{1}{B0}" path="C:\one-tests\runs\capture\notebook" lastModifiedTime="2026-09-13T07:34:46.000Z" color="#B49EDE"><one:Section name="copies" ID="{6D7B6C59-2E45-0D8F-286E-4FD72999E63A}{1}{B0}" path="C:\one-tests\runs\capture\notebook\copies.one" lastModifiedTime="2026-09-13T07:34:46.000Z" color="#8AA8E4"><one:Page ID="{8BB0D046-3BC7-0CE9-33B2-04F7D5E9C6FD}{1}{B0}" name="Destination" dateTime="2026-09-13T07:33:14.000Z" lastModifiedTime="2026-09-13T07:34:35.000Z" pageLevel="1"/><one:Page ID="{C12C0ECF-DDF8-0A21-11BE-3074429542E0}{1}{B0}" name="Before the file" dateTime="2026-09-13T07:33:14.000Z" lastModifiedTime="2026-09-13T07:34:35.000Z" pageLevel="1"/><one:Page ID="{91EAB23E-CBE0-0D18-1A25-23B9CBC39112}{1}{B0}" name="Before the table" dateTime="2026-09-13T07:33:14.000Z" lastModifiedTime="2026-09-13T07:34:35.000Z" pageLevel="1"/><one:Page ID="{B5A45771-4A39-05F8-1953-4F2F9B2B33A5}{1}{B0}" name="Before the picture" dateTime="2026-09-13T07:33:14.000Z" lastModifiedTime="2026-09-13T07:34:36.000Z" pageLevel="1"/><one:Page ID="{B28A26BE-5DF2-0214-1827-B1747FE95ECC}{1}{B0}" name="Beside the drawing" dateTime="2026-09-13T07:33:14.000Z" lastModifiedTime="2026-09-13T07:34:36.000Z" pageLevel="1"/><one:Page ID="{5C003E48-8717-05C2-096E-6762316BC0A0}{1}{B0}" name="Open task" dateTime="2026-09-13T07:33:14.000Z" lastModifiedTime="2026-09-13T07:34:36.000Z" pageLevel="1"/><one:Page ID="{C5E005CB-753E-07E2-0C53-CD40FBB64A63}{1}{B0}" name="Bullet item" dateTime="2026-09-13T07:33:14.000Z" lastModifiedTime="2026-09-13T07:34:36.000Z" pageLevel="1"/><one:Page ID="{5A5E0FDA-1644-0F00-0C45-8D72178B2031}{1}{B0}" name="Equations below" dateTime="2026-09-13T07:33:15.000Z" lastModifiedTime="2026-09-13T07:34:36.000Z" pageLevel="1"/><one:Page ID="{D4C06049-3C91-0190-0C2E-1BB1EBA49EBA}{1}{B0}" name="A notebook created in Rust." dateTime="2026-09-13T07:33:15.000Z" lastModifiedTime="2026-09-13T07:34:36.000Z" pageLevel="1"/></one:Section></one:Notebook> | |
| 2 | <one:Notebook xmlns:one="http://schemas.microsoft.com/office/onenote/2010/onenote" name="notebook" nickname="notebook" ID="{3D7C62EC-5CB3-485B-BB1F-23FA56C52E8D}{1}{B0}" path="C:\one-tests\runs\capture\notebook" lastModifiedTime="2026-09-13T08:14:37.000Z" color="#B49EDE"><one:Section name="copies" ID="{8631621B-321A-0F71-03FE-3BCA53E86583}{1}{B0}" path="C:\one-tests\runs\capture\notebook\copies.one" lastModifiedTime="2026-09-13T08:14:37.000Z" color="#8AA8E4"><one:Page ID="{0A5A2909-7069-0DA0-2457-FE8F9CA25885}{1}{B0}" name="Destination" dateTime="2026-09-13T08:12:55.000Z" lastModifiedTime="2026-09-13T08:14:26.000Z" pageLevel="1"/><one:Page ID="{62E12C49-D5FE-0850-17D5-B4DC95B736E9}{1}{B0}" name="Before the file" dateTime="2026-09-13T08:12:55.000Z" lastModifiedTime="2026-09-13T08:14:26.000Z" pageLevel="1"/><one:Page ID="{FBBA4589-4114-0DBB-1DDE-9AEBE04435E8}{1}{B0}" name="Before the table" dateTime="2026-09-13T08:12:55.000Z" lastModifiedTime="2026-09-13T08:14:26.000Z" pageLevel="1"/><one:Page ID="{5E04C302-1E83-0CCD-1715-B0A2566E0191}{1}{B0}" name="Bold 🦀 italic é color 東京" dateTime="2026-09-13T08:12:55.000Z" lastModifiedTime="2026-09-13T08:14:26.000Z" pageLevel="1"/><one:Page ID="{55B596AA-4540-085D-142D-9F788431ACE5}{1}{B0}" name="Indent first subtree" dateTime="2026-09-13T08:12:55.000Z" lastModifiedTime="2026-09-13T08:14:27.000Z" pageLevel="1"/><one:Page ID="{BA810F75-DBC0-0827-0990-F9FBFC84B7D7}{1}{B0}" name="Delete cell subtree" dateTime="2026-09-13T08:12:56.000Z" lastModifiedTime="2026-09-13T08:14:27.000Z" pageLevel="1"/><one:Page ID="{493E9D0C-5976-0886-2ADB-636A30B81D20}{1}{B0}" name="Delete sole cell paragraph" dateTime="2026-09-13T08:12:56.000Z" lastModifiedTime="2026-09-13T08:14:27.000Z" pageLevel="1"/><one:Page ID="{79EFBB50-C028-09DE-005B-75E21D0ED54C}{1}{B0}" name="Move numbered subtree down" dateTime="2026-09-13T08:12:56.000Z" lastModifiedTime="2026-09-13T08:14:27.000Z" pageLevel="1"/><one:Page ID="{6EC9E652-85BD-0524-17E7-232F5951B731}{1}{B0}" name="Delete numbered subtree" dateTime="2026-09-13T08:12:57.000Z" lastModifiedTime="2026-09-13T08:14:27.000Z" pageLevel="1"/><one:Page ID="{25E90FFA-6C7E-0A8D-3F8B-FC658F7AAF3B}{1}{B0}" name="Indent bullet subtree" dateTime="2026-09-13T08:12:57.000Z" lastModifiedTime="2026-09-13T08:14:27.000Z" pageLevel="1"/><one:Page ID="{AA29BE5C-9249-0610-1036-E2735CEC0BB9}{1}{B0}" name="Move cell subtree down" dateTime="2026-09-13T08:12:58.000Z" lastModifiedTime="2026-09-13T08:14:27.000Z" pageLevel="1"/><one:Page ID="{1E9DFA9B-2BEB-0C4E-3FEA-12F1C294A76E}{1}{B0}" name="Before the picture" dateTime="2026-09-13T08:12:58.000Z" lastModifiedTime="2026-09-13T08:14:27.000Z" pageLevel="1"/><one:Page ID="{D28E7576-C55F-0047-2C51-4C855C536D13}{1}{B0}" name="Beside the drawing" dateTime="2026-09-13T08:12:58.000Z" lastModifiedTime="2026-09-13T08:14:27.000Z" pageLevel="1"/><one:Page ID="{8E5634C2-26CB-0458-2810-125D129037C8}{1}{B0}" name="Open task" dateTime="2026-09-13T08:12:59.000Z" lastModifiedTime="2026-09-13T08:14:27.000Z" pageLevel="1"/><one:Page ID="{35E45165-B253-07BF-1324-6FC7DCE3552B}{1}{B0}" name="Bullet item" dateTime="2026-09-13T08:12:59.000Z" lastModifiedTime="2026-09-13T08:14:27.000Z" pageLevel="1"/><one:Page ID="{78595C91-C5E1-0D03-3A98-A98CA31DE5A8}{1}{B0}" name="Equations below" dateTime="2026-09-13T08:12:59.000Z" lastModifiedTime="2026-09-13T08:14:27.000Z" pageLevel="1"/><one:Page ID="{EF547C09-87EA-0A35-039B-F5512549E931}{1}{B0}" name="A notebook created in Rust." dateTime="2026-09-13T08:13:00.000Z" lastModifiedTime="2026-09-13T08:14:27.000Z" pageLevel="1"/></one:Section></one:Notebook> |
corpus/page-copy/cold/read/page-000.navigation.json+1-1| ... | ... | @@ -6,7 +6,7 @@ |
| 6 | 6 | "h": 600, |
| 7 | 7 | "error": null, |
| 8 | 8 | "win": { |
| 9 | "title": "Equations below - Microsoft OneNote", | |
| 9 | "title": "Destination - Microsoft OneNote", | |
| 10 | 10 | "class": "Framework::CFrame", |
| 11 | 11 | "dialog": false |
| 12 | 12 | } |
corpus/page-copy/cold/read/page-000.png| Binary files a/corpus/page-copy/cold/read/page-000.png and b/corpus/page-copy/cold/read/page-000.png differ |
corpus/page-copy/cold/read/page-000.xml+1-2| ... | ... | @@ -1,3 +1,2 @@ |
| 1 | 1 | <?xml version="1.0"?> |
| 2 | <one:Page xmlns:one="http://schemas.microsoft.com/office/onenote/2010/onenote" ID="{5A5E0FDA-1644-0F00-0C45-8D72178B2031}{1}{B0}" name="Equations below" dateTime="2026-09-13T07:33:15.000Z" lastModifiedTime="2026-09-13T07:34:36.000Z" pageLevel="1" style="font-family:Calibri;font-size:11.0pt" lang="en-US"><one:QuickStyleDef index="0" name="PageTitle" font="Calibri" fontSize="17.0"/><one:PageSettings RTL="false" color="automatic"><one:PageSize><one:Automatic/></one:PageSize><one:RuleLines visible="false"/></one:PageSettings><one:Title showDate="false" showTime="false" lang="en-US"><one:OE author="Copier" lastModifiedBy="Copier" creationTime="2026-09-13T07:33:15.000Z" lastModifiedTime="2026-09-13T07:33:15.000Z" objectID="{5A5E0FDA-1644-0F00-0C45-8D72178B2031}{15}{B0}" alignment="left" quickStyleIndex="0" style="font-family:Calibri;font-size:17.0pt"><one:T><![CDATA[Equations below]]></one:T></one:OE></one:Title><one:Outline author="Copier" lastModifiedBy="Copier" lastModifiedTime="2026-09-13T07:33:15.000Z" objectID="{75AB7537-48D1-0C4C-297D-B4D4CFA87CA2}{1}{B0}"><one:Position x="36.0" y="36.0" z="0"/><one:Size width="140.9678649902344" height="208.9916534423828"/><one:Indents><one:Indent level="0" indent="0.0"/></one:Indents><one:OEChildren><one:OE creationTime="2026-09-13T07:33:15.000Z" lastModifiedTime="2026-09-13T07:33:15.000Z" objectID="{D6CEF286-AFD3-0A03-0655-BA825F09BE5C}{1}{B0}" alignment="left"><one:T><![CDATA[Equations below]]></one:T></one:OE><one:OE creationTime="2026-09-13T07:33:15.000Z" lastModifiedTime="2026-09-13T07:33:15.000Z" objectID="{111AB493-1B15-0171-1BEC-C517BF808F15}{1}{B0}" alignment="left" style="font-family:'Cambria Math';font-size:11.0pt"><one:T><![CDATA[<!--[if mathML]><mml:math xmlns:mml="http://www.w3.org/1998/Math/MathML" display="block"><mml:msup><mml:mi>x</mml:mi><mml:mn>2</mml:mn></mml:msup><mml:mo>+</mml:mo><mml:msup><mml:mi>y</mml:mi><mml:mn>2</mml:mn></mml:msup><mml:mo>=</mml:mo><mml:msup><mml:mi>z</mml:mi><mml:mn>2</mml:mn></mml:msup></mml:math><![endif]-->]]></one:T></one:OE><one:OE creationTime="2026-09-13T07:33:15.000Z" lastModifiedTime="2026-09-13T07:33:15.000Z" objectID="{E963BDE9-C0E4-02BE-2D54-23989FC58846}{1}{B0}" alignment="left" style="font-family:'Cambria Math';font-size:11.0pt"><one:T><![CDATA[<!--[if mathML]><mml:math xmlns:mml="http://www.w3.org/1998/Math/MathML" display="block"><mml:mfrac><mml:mrow><mml:mi>a</mml:mi><mml:mo>+</mml:mo><mml:mi>b</mml:mi></mml:mrow><mml:mrow><mml:mi>c</mml:mi><mml:mo>+</mml:mo><mml:mi>d</mml:mi></mml:mrow></mml:mfrac></mml:math><![endif]-->]]></one:T></one:OE><one:OE creationTime="2026-09-13T07:33:15.000Z" lastModifiedTime="2026-09-13T07:33:15.000Z" objectID="{869A34E1-759D-03DC-1F28-DE83A586BDD6}{1}{B0}" alignment="left" style="font-size:11.0pt"><one:T><![CDATA[<span | |
| 3 | style='font-family:Calibri' lang=en-US>Inline </span><!--[if mathML]><mml:math xmlns:mml="http://www.w3.org/1998/Math/MathML"><mml:mi>&#120572;</mml:mi><mml:mo>+</mml:mo><mml:mi>&#120573;</mml:mi></mml:math><![endif]-->]]></one:T></one:OE><one:OE creationTime="2026-09-13T07:33:15.000Z" lastModifiedTime="2026-09-13T07:33:15.000Z" objectID="{877DD34D-81AC-038C-0477-B3E0645DD63E}{1}{B0}" alignment="left" style="font-family:'Cambria Math';font-size:11.0pt"><one:T><![CDATA[<!--[if mathML]><mml:math xmlns:mml="http://www.w3.org/1998/Math/MathML" display="block"><mml:msub><mml:mi>a</mml:mi><mml:mn>1</mml:mn></mml:msub><mml:mo>+</mml:mo><mml:msub><mml:mi>b</mml:mi><mml:mn>2</mml:mn></mml:msub></mml:math><![endif]-->]]></one:T></one:OE><one:OE creationTime="2026-09-13T07:33:15.000Z" lastModifiedTime="2026-09-13T07:33:15.000Z" objectID="{CD4EC150-40D1-074B-1157-F388604EEBE0}{1}{B0}" alignment="left" style="font-family:'Cambria Math';font-size:11.0pt"><one:T><![CDATA[<!--[if mathML]><mml:math xmlns:mml="http://www.w3.org/1998/Math/MathML" display="block"><mml:msubsup><mml:mi>x</mml:mi><mml:mi>i</mml:mi><mml:mn>2</mml:mn></mml:msubsup></mml:math><![endif]-->]]></one:T></one:OE><one:OE creationTime="2026-09-13T07:33:15.000Z" lastModifiedTime="2026-09-13T07:33:15.000Z" objectID="{1B908B9B-F5DF-0E47-3861-D55838C5AB28}{1}{B0}" alignment="left" style="font-family:'Cambria Math';font-size:11.0pt"><one:T><![CDATA[<!--[if mathML]><mml:math xmlns:mml="http://www.w3.org/1998/Math/MathML" display="block"><mml:mfenced><mml:mrow><mml:mi>a</mml:mi><mml:mo>+</mml:mo><mml:mi>b</mml:mi></mml:mrow></mml:mfenced></mml:math><![endif]-->]]></one:T></one:OE><one:OE creationTime="2026-09-13T07:33:15.000Z" lastModifiedTime="2026-09-13T07:33:15.000Z" objectID="{2A2E6B30-0040-052F-26F1-91BABCAE46B2}{1}{B0}" alignment="left" style="font-family:'Cambria Math';font-size:11.0pt"><one:T><![CDATA[<!--[if mathML]><mml:math xmlns:mml="http://www.w3.org/1998/Math/MathML" display="block"><mml:msubsup><mml:mo stretchy="false">∫</mml:mo><mml:mn>0</mml:mn><mml:mn>1</mml:mn></mml:msubsup><mml:mrow><mml:mi>x</mml:mi><mml:mo>&nbsp;</mml:mo><mml:mi>d</mml:mi><mml:mi>x</mml:mi><mml:mo>&nbsp;</mml:mo></mml:mrow></mml:math><![endif]-->]]></one:T></one:OE><one:OE creationTime="2026-09-13T07:33:15.000Z" lastModifiedTime="2026-09-13T07:33:15.000Z" objectID="{3110679E-A6C8-08CA-14E7-D38AABF07619}{1}{B0}" alignment="left" style="font-family:'Cambria Math';font-size:11.0pt"><one:T><![CDATA[<!--[if mathML]><mml:math xmlns:mml="http://www.w3.org/1998/Math/MathML" display="block"><mml:munderover><mml:mo stretchy="false">∑</mml:mo><mml:mrow><mml:mi>i</mml:mi><mml:mo>=</mml:mo><mml:mn>1</mml:mn></mml:mrow><mml:mi>n</mml:mi></mml:munderover><mml:mrow><mml:mi>i</mml:mi><mml:mo>&nbsp;</mml:mo></mml:mrow></mml:math><![endif]-->]]></one:T></one:OE><one:OE creationTime="2026-09-13T07:33:15.000Z" lastModifiedTime="2026-09-13T07:33:15.000Z" objectID="{58A7316B-7529-03F0-2F54-20F513A79572}{1}{B0}" alignment="left" style="font-family:'Cambria Math';font-size:11.0pt"><one:T><![CDATA[<!--[if mathML]><mml:math xmlns:mml="http://www.w3.org/1998/Math/MathML" display="block"><mml:msup><mml:mi>x</mml:mi><mml:mn>2</mml:mn></mml:msup><mml:mo>+</mml:mo><mml:mn>1</mml:mn></mml:math><![endif]-->]]></one:T></one:OE><one:OE creationTime="2026-09-13T07:33:15.000Z" lastModifiedTime="2026-09-13T07:33:15.000Z" objectID="{BFE82679-7A72-09C5-266D-FBEC819E237D}{1}{B0}" alignment="left" style="font-family:'Cambria Math';font-size:11.0pt"><one:T><![CDATA[<!--[if mathML]><mml:math xmlns:mml="http://www.w3.org/1998/Math/MathML" display="block"><mml:mfrac><mml:mrow><mml:mi>a</mml:mi><mml:mo>+</mml:mo><mml:mi>b</mml:mi></mml:mrow><mml:mrow><mml:msup><mml:mi>c</mml:mi><mml:mn>2</mml:mn></mml:msup></mml:mrow></mml:mfrac></mml:math><![endif]-->]]></one:T></one:OE></one:OEChildren></one:Outline></one:Page> | |
| 2 | <one:Page xmlns:one="http://schemas.microsoft.com/office/onenote/2010/onenote" ID="{0A5A2909-7069-0DA0-2457-FE8F9CA25885}{1}{B0}" name="Destination" dateTime="2026-09-13T08:12:55.000Z" lastModifiedTime="2026-09-13T08:14:26.000Z" pageLevel="1" style="font-family:Calibri;font-size:11.0pt" lang="en-US"><one:PageSettings RTL="false" color="automatic"><one:PageSize><one:Automatic/></one:PageSize><one:RuleLines visible="false"/></one:PageSettings><one:Outline author="Author" lastModifiedBy="Author" lastModifiedTime="2026-09-13T08:12:55.000Z" objectID="{8631621B-321A-0F71-03FE-3BCA53E86583}{23}{B0}"><one:Position x="36.0" y="36.0" z="0"/><one:Size width="118.3393707275391" height="13.4277172088623"/><one:Indents><one:Indent level="0" indent="0.0"/></one:Indents><one:OEChildren><one:OE creationTime="2026-09-13T08:12:55.000Z" lastModifiedTime="2026-09-13T08:12:55.000Z" objectID="{8631621B-321A-0F71-03FE-3BCA53E86583}{24}{B0}" alignment="left"><one:T><![CDATA[Destination]]></one:T></one:OE></one:OEChildren></one:Outline></one:Page> |
corpus/page-copy/cold/read/page-001.navigation.json+1-1| ... | ... | @@ -6,7 +6,7 @@ |
| 6 | 6 | "h": 600, |
| 7 | 7 | "error": null, |
| 8 | 8 | "win": { |
| 9 | "title": "Open task - Microsoft OneNote", | |
| 9 | "title": "Before the picture - Microsoft OneNote", | |
| 10 | 10 | "class": "Framework::CFrame", |
| 11 | 11 | "dialog": false |
| 12 | 12 | } |
corpus/page-copy/cold/read/page-001.png| Binary files a/corpus/page-copy/cold/read/page-001.png and b/corpus/page-copy/cold/read/page-001.png differ |
corpus/page-copy/cold/read/page-001.xml+3-1| ... | ... | @@ -1,2 +1,4 @@ |
| 1 | 1 | <?xml version="1.0"?> |
| 2 | <one:Page xmlns:one="http://schemas.microsoft.com/office/onenote/2010/onenote" ID="{5C003E48-8717-05C2-096E-6762316BC0A0}{1}{B0}" name="Open task" dateTime="2026-09-13T07:33:14.000Z" lastModifiedTime="2026-09-13T07:34:36.000Z" pageLevel="1" style="font-family:Calibri;font-size:11.0pt" lang="en-US"><one:TagDef index="0" type="0" symbol="3" fontColor="automatic" highlightColor="none" name="Rust task"/><one:TagDef index="1" type="1" symbol="13" fontColor="#FF0000" highlightColor="#FFFF00" name="Important"/><one:QuickStyleDef index="0" name="PageTitle" font="Calibri" fontSize="17.0"/><one:PageSettings RTL="false" color="automatic"><one:PageSize><one:Automatic/></one:PageSize><one:RuleLines visible="false"/></one:PageSettings><one:Title showDate="false" showTime="false" lang="en-US"><one:OE author="Copier" lastModifiedBy="Copier" creationTime="2026-09-13T07:33:14.000Z" lastModifiedTime="2026-09-13T07:33:14.000Z" objectID="{5C003E48-8717-05C2-096E-6762316BC0A0}{15}{B0}" alignment="left" quickStyleIndex="0" style="font-family:Calibri;font-size:17.0pt"><one:T><![CDATA[Open task]]></one:T></one:OE></one:Title><one:Outline author="Copier" lastModifiedBy="Copier" lastModifiedTime="2026-09-13T07:33:15.000Z" objectID="{EA96F1EA-D912-043B-3585-EF6DB73F7D60}{1}{B0}"><one:Position x="36.0" y="36.0" z="0"/><one:Size width="158.2036895751953" height="53.71086883544922"/><one:Indents><one:Indent level="0" indent="0.0"/></one:Indents><one:OEChildren><one:OE creationTime="2026-09-13T07:33:15.000Z" lastModifiedTime="2026-09-13T07:33:15.000Z" objectID="{2B4A358D-B65A-0B30-167C-A3C772956F2F}{1}{B0}" alignment="left"><one:Tag index="0" completed="false" disabled="false" creationDate="2020-01-02T03:04:05.000Z"/><one:T><![CDATA[Open task]]></one:T></one:OE><one:OE creationTime="2026-09-13T07:33:15.000Z" lastModifiedTime="2026-09-13T07:33:15.000Z" objectID="{30380DA0-EF03-0A04-03AD-6F50C3F095CB}{1}{B0}" alignment="left"><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[Completed task]]></one:T></one:OE><one:OE creationTime="2026-09-13T07:33:15.000Z" lastModifiedTime="2026-09-13T07:33:15.000Z" objectID="{26502F9C-1811-0C5C-23BE-395D96FFF797}{1}{B0}" alignment="left"><one:Tag index="0" completed="false" disabled="false" creationDate="2020-01-02T03:04:05.000Z"/><one:Tag index="1" completed="false" disabled="false" creationDate="2020-01-02T03:04:05.000Z"/><one:T><![CDATA[Important open task]]></one:T></one:OE><one:OE creationTime="2026-09-13T07:33:15.000Z" lastModifiedTime="2026-09-13T07:33:15.000Z" objectID="{B17CBFD9-E3D1-0CC8-0837-B615ED83C6E5}{1}{B0}" alignment="left"><one:T><![CDATA[Untagged]]></one:T></one:OE></one:OEChildren></one:Outline></one:Page> | |
| 2 | <one:Page xmlns:one="http://schemas.microsoft.com/office/onenote/2010/onenote" ID="{1E9DFA9B-2BEB-0C4E-3FEA-12F1C294A76E}{1}{B0}" name="Before the picture" dateTime="2026-09-13T08:12:58.000Z" lastModifiedTime="2026-09-13T08:14:27.000Z" pageLevel="1" lang="en-US"><one:QuickStyleDef index="0" name="PageTitle" font="Calibri" fontSize="17.0"/><one:PageSettings RTL="false" color="automatic"><one:PageSize><one:Automatic/></one:PageSize><one:RuleLines visible="false"/></one:PageSettings><one:Title showDate="false" showTime="false" lang="en-US"><one:OE author="Copier" lastModifiedBy="Copier" creationTime="2026-09-13T08:12:58.000Z" lastModifiedTime="2026-09-13T08:12:58.000Z" objectID="{1E9DFA9B-2BEB-0C4E-3FEA-12F1C294A76E}{15}{B0}" alignment="left" quickStyleIndex="0" style="font-family:Calibri;font-size:17.0pt"><one:T><![CDATA[Before the picture]]></one:T></one:OE></one:Title><one:Outline author="Copier" lastModifiedBy="Copier" lastModifiedTime="2026-09-13T08:12:59.000Z" objectID="{4DA80AD4-95E4-0563-13A1-48595B5FF4B8}{1}{B0}"><one:Position x="36.0" y="36.0" z="0"/><one:Size width="148.3100738525391" height="27.60543251037598"/><one:Indents><one:Indent level="0" indent="0.0"/></one:Indents><one:OEChildren><one:OE creationTime="2026-09-13T08:12:59.000Z" lastModifiedTime="2026-09-13T08:12:59.000Z" objectID="{AFD96465-6096-07A5-2297-9F5092B2C4D0}{1}{B0}" alignment="left" style="font-family:Calibri;font-size:11.0pt"><one:T><![CDATA[Before the picture]]></one:T></one:OE><one:OE creationTime="2026-09-13T08:12:59.000Z" lastModifiedTime="2026-09-13T08:12:59.000Z" objectID="{EAFF9A35-4964-0B98-232B-BE4FC1E5AC7A}{1}{B0}" alignment="left"><one:Image format="png"><one:Data>iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAIAAACQd1PeAAAADElEQVQI12P4z8AAAAMBAQAY3Y2w | |
| 3 | AAAAAElFTkSuQmCC | |
| 4 | </one:Data></one:Image></one:OE><one:OE creationTime="2026-09-13T08:12:59.000Z" lastModifiedTime="2026-09-13T08:12:59.000Z" objectID="{30FDBCD9-EBE5-0C42-3241-15D4E7312FCD}{1}{B0}" alignment="left" style="font-family:Calibri;font-size:11.0pt"><one:T><![CDATA[After the picture]]></one:T></one:OE></one:OEChildren></one:Outline></one:Page> |
corpus/page-copy/cold/read/page-002.navigation.json+1-1| ... | ... | @@ -6,7 +6,7 @@ |
| 6 | 6 | "h": 600, |
| 7 | 7 | "error": null, |
| 8 | 8 | "win": { |
| 9 | "title": "Destination - Microsoft OneNote", | |
| 9 | "title": "Indent bullet subtree - Microsoft OneNote", | |
| 10 | 10 | "class": "Framework::CFrame", |
| 11 | 11 | "dialog": false |
| 12 | 12 | } |
corpus/page-copy/cold/read/page-002.png| Binary files a/corpus/page-copy/cold/read/page-002.png and b/corpus/page-copy/cold/read/page-002.png differ |
corpus/page-copy/cold/read/page-002.xml+4-1| ... | ... | @@ -1,2 +1,5 @@ |
| 1 | 1 | <?xml version="1.0"?> |
| 2 | <one:Page xmlns:one="http://schemas.microsoft.com/office/onenote/2010/onenote" ID="{8BB0D046-3BC7-0CE9-33B2-04F7D5E9C6FD}{1}{B0}" name="Destination" dateTime="2026-09-13T07:33:14.000Z" lastModifiedTime="2026-09-13T07:34:35.000Z" pageLevel="1" style="font-family:Calibri;font-size:11.0pt" lang="en-US"><one:PageSettings RTL="false" color="automatic"><one:PageSize><one:Automatic/></one:PageSize><one:RuleLines visible="false"/></one:PageSettings><one:Outline author="Author" lastModifiedBy="Author" lastModifiedTime="2026-09-13T07:33:14.000Z" objectID="{6D7B6C59-2E45-0D8F-286E-4FD72999E63A}{23}{B0}"><one:Position x="36.0" y="36.0" z="0"/><one:Size width="118.3393707275391" height="13.4277172088623"/><one:Indents><one:Indent level="0" indent="0.0"/></one:Indents><one:OEChildren><one:OE creationTime="2026-09-13T07:33:14.000Z" lastModifiedTime="2026-09-13T07:33:14.000Z" objectID="{6D7B6C59-2E45-0D8F-286E-4FD72999E63A}{24}{B0}" alignment="left"><one:T><![CDATA[Destination]]></one:T></one:OE></one:OEChildren></one:Outline></one:Page> | |
| 2 | <one:Page xmlns:one="http://schemas.microsoft.com/office/onenote/2010/onenote" ID="{25E90FFA-6C7E-0A8D-3F8B-FC658F7AAF3B}{1}{B0}" name="Indent bullet subtree" dateTime="2026-09-13T08:12:57.000Z" lastModifiedTime="2026-09-13T08:14:27.000Z" pageLevel="1" lang="en-US"><one:TagDef index="0" type="0" symbol="3" fontColor="automatic" highlightColor="none" name="Preserved task"/><one:QuickStyleDef index="0" name="PageTitle" font="Calibri" fontSize="17.0"/><one:QuickStyleDef index="1" 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 showDate="false" showTime="false" lang="en-US"><one:OE author="Copier" lastModifiedBy="Copier" creationTime="2026-09-13T08:12:57.000Z" lastModifiedTime="2026-09-13T08:12:57.000Z" objectID="{25E90FFA-6C7E-0A8D-3F8B-FC658F7AAF3B}{15}{B0}" alignment="left" quickStyleIndex="0" style="font-family:Calibri;font-size:17.0pt"><one:T><![CDATA[Indent bullet subtree]]></one:T></one:OE></one:Title><one:Outline author="Copier" lastModifiedBy="Copier" lastModifiedTime="2026-09-13T08:12:58.000Z" objectID="{E70D26B4-5E53-0439-14D6-AB435B274370}{1}{B0}"><one:Position x="72.0" y="108.0" z="0"/><one:Size width="142.6107788085937" height="67.13858032226562"/><one:OEChildren><one:OE creationTime="2026-09-13T08:12:58.000Z" lastModifiedTime="2026-09-13T08:12:58.000Z" objectID="{C20780E2-91FA-0C79-3266-C1E8843F8C27}{1}{B0}" alignment="left" quickStyleIndex="1"><one:List><one:Bullet bullet="3" fontSize="11.0"/></one:List><one:T><![CDATA[Anchor]]></one:T></one:OE><one:OE creationTime="2026-09-13T08:12:58.000Z" lastModifiedTime="2026-09-13T08:12:58.000Z" objectID="{B9F245E8-A24F-019A-3F3E-540901F3F3F1}{1}{B0}" alignment="left" quickStyleIndex="1"><one:Tag index="0" completed="true" disabled="false" creationDate="2020-01-02T03:04:05.000Z" completionDate="2020-01-02T04:05:06.000Z"/><one:List><one:Bullet bullet="3" fontSize="11.0"/></one:List><one:T><![CDATA[<span | |
| 3 | style='font-weight:bold'>Target &#129408; é</span> <a | |
| 4 | href="https://example.invalid/tree">Link label</a>]]></one:T><one:OEChildren><one:OE creationTime="2026-09-13T08:12:58.000Z" lastModifiedTime="2026-09-13T08:12:58.000Z" objectID="{F762F81C-0C7D-0D7E-318B-18934A658911}{1}{B0}" alignment="left" quickStyleIndex="1"><one:T style="font-family:Calibri;font-size:11.0pt"><![CDATA[<span | |
| 5 | style='font-style:italic'>Child</span>]]></one:T><one:OEChildren><one:OE creationTime="2026-09-13T08:12:58.000Z" lastModifiedTime="2026-09-13T08:12:58.000Z" objectID="{25F7C65A-45FD-03F5-31CF-DCA9A335FC64}{1}{B0}" alignment="left" quickStyleIndex="1"><one:T><![CDATA[Grandchild]]></one:T></one:OE></one:OEChildren></one:OE></one:OEChildren></one:OE><one:OE creationTime="2026-09-13T08:12:58.000Z" lastModifiedTime="2026-09-13T08:12:58.000Z" objectID="{91205826-B132-0A1C-0828-370A55059BE9}{1}{B0}" alignment="left" quickStyleIndex="1"><one:List><one:Bullet bullet="3" fontSize="11.0"/></one:List><one:T><![CDATA[Trailing sibling]]></one:T></one:OE></one:OEChildren></one:Outline><one:Outline author="Copier" lastModifiedBy="Copier" lastModifiedTime="2026-09-13T08:12:58.000Z" objectID="{7E8151C3-CE0D-083C-29FA-66EB4C60734C}{1}{B0}"><one:Position x="540.0" y="108.0" z="1"/><one:Size width="99.85796356201171" height="13.42771339416504"/><one:OEChildren><one:OE creationTime="2026-09-13T08:12:58.000Z" lastModifiedTime="2026-09-13T08:12:58.000Z" objectID="{A50B7E04-F685-06D4-3602-48EC3C9D5381}{1}{B0}" alignment="left" quickStyleIndex="1"><one:T><![CDATA[Other outline]]></one:T></one:OE></one:OEChildren></one:Outline></one:Page> |
corpus/page-copy/cold/read/page-003.navigation.json+1-1| ... | ... | @@ -6,7 +6,7 @@ |
| 6 | 6 | "h": 600, |
| 7 | 7 | "error": null, |
| 8 | 8 | "win": { |
| 9 | "title": "Before the table - Microsoft OneNote", | |
| 9 | "title": "Bullet item - Microsoft OneNote", | |
| 10 | 10 | "class": "Framework::CFrame", |
| 11 | 11 | "dialog": false |
| 12 | 12 | } |
corpus/page-copy/cold/read/page-003.png| Binary files a/corpus/page-copy/cold/read/page-003.png and b/corpus/page-copy/cold/read/page-003.png differ |
corpus/page-copy/cold/read/page-003.xml+1-1| ... | ... | @@ -1,2 +1,2 @@ |
| 1 | 1 | <?xml version="1.0"?> |
| 2 | <one:Page xmlns:one="http://schemas.microsoft.com/office/onenote/2010/onenote" ID="{91EAB23E-CBE0-0D18-1A25-23B9CBC39112}{1}{B0}" name="Before the table" dateTime="2026-09-13T07:33:14.000Z" lastModifiedTime="2026-09-13T07:34:35.000Z" pageLevel="1" style="font-family:Calibri;font-size:11.0pt" lang="en-US"><one:QuickStyleDef index="0" name="PageTitle" font="Calibri" fontSize="17.0"/><one:PageSettings RTL="false" color="automatic"><one:PageSize><one:Automatic/></one:PageSize><one:RuleLines visible="false"/></one:PageSettings><one:Title showDate="false" showTime="false" lang="en-US"><one:OE author="Copier" lastModifiedBy="Copier" creationTime="2026-09-13T07:33:14.000Z" lastModifiedTime="2026-09-13T07:33:14.000Z" objectID="{91EAB23E-CBE0-0D18-1A25-23B9CBC39112}{15}{B0}" alignment="left" quickStyleIndex="0" style="font-family:Calibri;font-size:17.0pt"><one:T><![CDATA[Before the table]]></one:T></one:OE></one:Title><one:Outline author="Copier" lastModifiedBy="Copier" lastModifiedTime="2026-09-13T07:33:14.000Z" objectID="{899FA9AA-6E30-05C6-0039-C1174852FBAA}{1}{B0}"><one:Position x="36.0" y="36.0" z="0"/><one:Size width="395.1299438476562" height="67.21086883544922"/><one:Indents><one:Indent level="0" indent="0.0"/></one:Indents><one:OEChildren><one:OE creationTime="2026-09-13T07:33:14.000Z" lastModifiedTime="2026-09-13T07:33:14.000Z" objectID="{03DB4753-6DD9-0476-0A44-807F1E239611}{1}{B0}" alignment="left"><one:T><![CDATA[Before the table]]></one:T></one:OE><one:OE creationTime="2026-09-13T07:33:14.000Z" lastModifiedTime="2026-09-13T07:33:14.000Z" objectID="{CC36F460-50AA-0CAC-185C-B2DD3405EC23}{1}{B0}" alignment="left"><one:Table bordersVisible="true" lastModifiedTime="2026-09-13T07:33:14.000Z" objectID="{F406EA96-EABF-0750-358B-13B077B8877C}{1}{B0}"><one:Columns><one:Column index="0" width="144.0" isLocked="true"/><one:Column index="1" width="216.0" isLocked="true"/></one:Columns><one:Row objectID="{B57E3F32-D364-012F-129A-7A8AFA0A8DE1}{1}{B0}" lastModifiedTime="2026-09-13T07:33:14.000Z"><one:Cell lastModifiedTime="2026-09-13T07:33:14.000Z" objectID="{8B99B904-69FB-0ABF-25D8-6EDED1F41EED}{1}{B0}"><one:OEChildren><one:OE creationTime="2026-09-13T07:33:14.000Z" lastModifiedTime="2026-09-13T07:33:14.000Z" objectID="{2F0315A5-D396-09FD-0772-968EDD6113D6}{1}{B0}" alignment="left"><one:T><![CDATA[Name]]></one:T></one:OE></one:OEChildren></one:Cell><one:Cell lastModifiedTime="2026-09-13T07:33:14.000Z" objectID="{58E45041-62CE-0EFA-3F22-C4509482E3BF}{1}{B0}"><one:OEChildren><one:OE creationTime="2026-09-13T07:33:14.000Z" lastModifiedTime="2026-09-13T07:33:14.000Z" objectID="{0F92F8F0-F5F6-0CCA-3E1C-10A217EA11EF}{1}{B0}" alignment="left"><one:T><![CDATA[Value]]></one:T></one:OE></one:OEChildren></one:Cell></one:Row><one:Row objectID="{6D9AA72E-D225-0D46-3D00-5B12D99343C3}{1}{B0}" lastModifiedTime="2026-09-13T07:33:14.000Z"><one:Cell lastModifiedTime="2026-09-13T07:33:14.000Z" objectID="{2555B7CF-F12A-013D-0652-4CA9AEF5284C}{1}{B0}"><one:OEChildren><one:OE creationTime="2026-09-13T07:33:14.000Z" lastModifiedTime="2026-09-13T07:33:14.000Z" objectID="{A0E15DEA-0A8D-0F42-12FA-36CC54EA289A}{1}{B0}" alignment="left"><one:T><![CDATA[Rust &#129408;]]></one:T></one:OE></one:OEChildren></one:Cell><one:Cell lastModifiedTime="2026-09-13T07:33:14.000Z" objectID="{7ED49F5B-8C93-0208-16B6-8816DB6B4151}{1}{B0}"><one:OEChildren><one:OE creationTime="2026-09-13T07:33:14.000Z" lastModifiedTime="2026-09-13T07:33:14.000Z" objectID="{D60ED3D2-2081-02A2-1EC5-A3D1190448EB}{1}{B0}" alignment="left"><one:T><![CDATA[Written natively]]></one:T></one:OE></one:OEChildren></one:Cell></one:Row></one:Table></one:OE><one:OE creationTime="2026-09-13T07:33:14.000Z" lastModifiedTime="2026-09-13T07:33:14.000Z" objectID="{F18DD402-3CA3-01AB-32DC-D1D5A8545B7F}{1}{B0}" alignment="left"><one:T><![CDATA[After the table]]></one:T></one:OE></one:OEChildren></one:Outline></one:Page> | |
| 2 | <one:Page xmlns:one="http://schemas.microsoft.com/office/onenote/2010/onenote" ID="{35E45165-B253-07BF-1324-6FC7DCE3552B}{1}{B0}" name="Bullet item" dateTime="2026-09-13T08:12:59.000Z" lastModifiedTime="2026-09-13T08:14:27.000Z" pageLevel="1" style="font-family:Calibri;font-size:11.0pt" lang="en-US"><one:QuickStyleDef index="0" name="PageTitle" font="Calibri" fontSize="17.0"/><one:PageSettings RTL="false" color="automatic"><one:PageSize><one:Automatic/></one:PageSize><one:RuleLines visible="false"/></one:PageSettings><one:Title showDate="false" showTime="false" lang="en-US"><one:OE author="Copier" lastModifiedBy="Copier" creationTime="2026-09-13T08:12:59.000Z" lastModifiedTime="2026-09-13T08:12:59.000Z" objectID="{35E45165-B253-07BF-1324-6FC7DCE3552B}{15}{B0}" alignment="left" quickStyleIndex="0" style="font-family:Calibri;font-size:17.0pt"><one:T><![CDATA[Bullet item]]></one:T></one:OE></one:Title><one:Outline author="Copier" lastModifiedBy="Copier" lastModifiedTime="2026-09-13T08:13:00.000Z" objectID="{1030C98D-AF8F-01AF-0FE4-4821037C552D}{1}{B0}"><one:Position x="36.0" y="36.0" z="0"/><one:Size width="174.7353515625" height="93.99401092529296"/><one:Indents><one:Indent level="0" indent="0.0"/></one:Indents><one:OEChildren><one:OE creationTime="2026-09-13T08:13:00.000Z" lastModifiedTime="2026-09-13T08:13:00.000Z" objectID="{41E8A28A-ADD0-072D-0780-D5A47F095985}{1}{B0}" alignment="left"><one:List><one:Bullet bullet="3" fontSize="11.0"/></one:List><one:T><![CDATA[Bullet item]]></one:T></one:OE><one:OE creationTime="2026-09-13T08:13:00.000Z" lastModifiedTime="2026-09-13T08:13:00.000Z" objectID="{45462BD4-B2B9-0403-1A75-2A2CFE1C6368}{1}{B0}" alignment="left"><one:List><one:Number numberSequence="1" numberFormat="##." fontSize="11.0" font="Calibri" text="I."/></one:List><one:T><![CDATA[First numbered]]></one:T></one:OE><one:OE creationTime="2026-09-13T08:13:00.000Z" lastModifiedTime="2026-09-13T08:13:00.000Z" objectID="{0547114E-6093-0FBB-0257-A78B4D838BFB}{1}{B0}" alignment="left"><one:List><one:Number numberSequence="1" numberFormat="##." fontSize="11.0" font="Calibri" text="II."/></one:List><one:T><![CDATA[Second numbered]]></one:T><one:OEChildren><one:OE creationTime="2026-09-13T08:13:00.000Z" lastModifiedTime="2026-09-13T08:13:00.000Z" objectID="{BBD74A7A-615E-04F9-0758-5D319A106A96}{1}{B0}" alignment="left"><one:List><one:Number numberSequence="1" numberFormat="##." fontSize="11.0" font="Calibri" text="I."/></one:List><one:T><![CDATA[Nested numbered]]></one:T></one:OE></one:OEChildren></one:OE><one:OE creationTime="2026-09-13T08:13:00.000Z" lastModifiedTime="2026-09-13T08:13:00.000Z" objectID="{73CB0260-61B9-026E-068D-9106DD4C284F}{1}{B0}" alignment="left"><one:List><one:Number numberSequence="1" numberFormat="##." fontSize="11.0" font="Calibri" text="III."/></one:List><one:T><![CDATA[Restarted at three]]></one:T><one:OEChildren><one:OE creationTime="2026-09-13T08:13:00.000Z" lastModifiedTime="2026-09-13T08:13:00.000Z" objectID="{D4851817-9021-0C2E-1FB9-78CACB7483E5}{1}{B0}" alignment="left"><one:T><![CDATA[Nested plain]]></one:T></one:OE></one:OEChildren></one:OE><one:OE creationTime="2026-09-13T08:13:00.000Z" lastModifiedTime="2026-09-13T08:13:00.000Z" objectID="{7F1ACAD9-03E3-0D2C-0854-83C7B46AA88A}{1}{B0}" alignment="left"><one:T><![CDATA[Plain again]]></one:T></one:OE></one:OEChildren></one:Outline></one:Page> |
corpus/page-copy/cold/read/page-004.navigation.json+1-1| ... | ... | @@ -6,7 +6,7 @@ |
| 6 | 6 | "h": 600, |
| 7 | 7 | "error": null, |
| 8 | 8 | "win": { |
| 9 | "title": "Beside the drawing - Microsoft OneNote", | |
| 9 | "title": "Delete sole cell paragraph - Microsoft OneNote", | |
| 10 | 10 | "class": "Framework::CFrame", |
| 11 | 11 | "dialog": false |
| 12 | 12 | } |
corpus/page-copy/cold/read/page-004.png| Binary files a/corpus/page-copy/cold/read/page-004.png and b/corpus/page-copy/cold/read/page-004.png differ |
corpus/page-copy/cold/read/page-004.xml+3-6| ... | ... | @@ -1,7 +1,4 @@ |
| 1 | 1 | <?xml version="1.0"?> |
| 2 | <one:Page xmlns:one="http://schemas.microsoft.com/office/onenote/2010/onenote" ID="{B28A26BE-5DF2-0214-1827-B1747FE95ECC}{1}{B0}" name="Beside the drawing" dateTime="2026-09-13T07:33:14.000Z" lastModifiedTime="2026-09-13T07:34:36.000Z" pageLevel="1" style="font-family:Calibri;font-size:11.0pt" lang="en-US"><one:QuickStyleDef index="0" name="PageTitle" font="Calibri" fontSize="17.0"/><one:PageSettings RTL="false" color="automatic"><one:PageSize><one:Automatic/></one:PageSize><one:RuleLines visible="false"/></one:PageSettings><one:Title showDate="false" showTime="false" lang="en-US"><one:OE author="Copier" lastModifiedBy="Copier" creationTime="2026-09-13T07:33:14.000Z" lastModifiedTime="2026-09-13T07:33:14.000Z" objectID="{B28A26BE-5DF2-0214-1827-B1747FE95ECC}{15}{B0}" alignment="left" quickStyleIndex="0" style="font-family:Calibri;font-size:17.0pt"><one:T><![CDATA[Beside the drawing]]></one:T></one:OE></one:Title><one:Outline author="Copier" lastModifiedBy="Copier" lastModifiedTime="2026-09-13T07:33:14.000Z" objectID="{BA59696B-EAE1-0771-0BCB-5878F45A65F8}{1}{B0}"><one:Position x="36.0" y="36.0" z="0"/><one:Size width="152.4244079589843" height="13.4277172088623"/><one:Indents><one:Indent level="0" indent="0.0"/></one:Indents><one:OEChildren><one:OE creationTime="2026-09-13T07:33:14.000Z" lastModifiedTime="2026-09-13T07:33:14.000Z" objectID="{38FEF76B-56AE-0456-1B54-A2C668C24685}{1}{B0}" alignment="left"><one:T><![CDATA[Beside the drawing]]></one:T></one:OE></one:OEChildren></one:Outline><one:InkDrawing lastModifiedTime="2026-09-13T07:33:14.000Z" objectID="{501D4164-CA81-04D3-1BDC-D2CA0006F088}{1}{B0}"><one:Position x="299.9905395507812" y="119.9905471801758" z="1"/><one:Size width="60.03781127929687" height="60.03779220581055"/><one:Data>AM8CHQSiAaIBAWAqABofi0JwRYR1gL7QRdkE+oeVMvLsF0G4wBa/8yv0et67E4vlXrNInJuhJVq3 | |
| 3 | URK/7HHMzCKxQYkOuxMs7nqhWM9UiuaXxU+PBvi60uGbIsRmbacNslhJmh1OQDQGbBACEQZIEEUj | |
| 4 | RiMJSBBE/wFFI0YjBQgLZU9mZ2hkaRkUMggAgB4CIeLiQTMIAPAQAovF4kFkAxVGAEAKXAWH8gln | |
| 5 | jCj7wnvCe8IAh/B8h4Pke8I7wnvCQAUURgBAAAAJBAUURgAAAAASABEgKFNtArpWcU+AsrjC8JNY | |
| 6 | RQo/QCNkARXUNSA7oAMVRgBACj9AIm9GCC70WAqACQEKTAIPUq7GcA5CJYzgBRRGAIAAAAkEBRRG | |
| 7 | AAAAABIAESAJY0kvgp5dSp0WwhnX6NwFCj9AI2QBFdQ1IDugAxVGAEAKP0Aib0YILvRYCoA=</one:Data></one:InkDrawing></one:Page> | |
| 2 | <one:Page xmlns:one="http://schemas.microsoft.com/office/onenote/2010/onenote" ID="{493E9D0C-5976-0886-2ADB-636A30B81D20}{1}{B0}" name="Delete sole cell paragraph" dateTime="2026-09-13T08:12:56.000Z" lastModifiedTime="2026-09-13T08:14:27.000Z" pageLevel="1" lang="en-US"><one:TagDef index="0" type="0" symbol="3" fontColor="automatic" highlightColor="none" name="Preserved task"/><one:QuickStyleDef index="0" name="PageTitle" font="Calibri" fontSize="17.0"/><one:QuickStyleDef index="1" 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 showDate="false" showTime="false" lang="en-US"><one:OE author="Copier" lastModifiedBy="Copier" creationTime="2026-09-13T08:12:56.000Z" lastModifiedTime="2026-09-13T08:12:56.000Z" objectID="{493E9D0C-5976-0886-2ADB-636A30B81D20}{15}{B0}" alignment="left" quickStyleIndex="0" style="font-family:Calibri;font-size:17.0pt"><one:T><![CDATA[Delete sole cell paragraph]]></one:T></one:OE></one:Title><one:Outline author="Copier" lastModifiedBy="Copier" lastModifiedTime="2026-09-13T08:12:57.000Z" objectID="{9721CF72-8007-0180-29C3-D0F422003C1B}{1}{B0}"><one:Position x="72.0" y="108.0" z="0"/><one:Size width="428.1300048828125" height="21.94771385192871"/><one:OEChildren><one:OE creationTime="2026-09-13T08:12:56.000Z" lastModifiedTime="2026-09-13T08:12:57.000Z" objectID="{76A5FFBC-C8EC-0E30-2663-51714300B179}{1}{B0}" alignment="left"><one:Table bordersVisible="true" lastModifiedTime="2026-09-13T08:12:57.000Z" objectID="{EFDBE2D8-39D5-0EDF-075C-26A7D704FD28}{1}{B0}"><one:Columns><one:Column index="0" width="240.0" isLocked="true"/><one:Column index="1" width="180.0" isLocked="true"/></one:Columns><one:Row objectID="{8D1D5F63-2DD1-0274-04FA-38A73347200A}{1}{B0}" lastModifiedTime="2026-09-13T08:12:57.000Z"><one:Cell lastModifiedTime="2026-09-13T08:12:57.000Z" objectID="{7258A0AD-D622-0854-0122-8EBEB7B70203}{1}{B0}"><one:OEChildren><one:OE creationTime="2026-09-13T08:12:56.000Z" lastModifiedTime="2026-09-13T08:12:57.000Z" objectID="{63217049-E82C-0F04-08AE-9CB184551B5D}{1}{B0}" alignment="left" quickStyleIndex="1"><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 | |
| 3 | style='font-weight:bold'>Target &#129408; é</span> <a | |
| 4 | href="https://example.invalid/tree">Link label</a>]]></one:T></one:OE></one:OEChildren></one:Cell><one:Cell lastModifiedTime="2026-09-13T08:12:56.000Z" objectID="{05B95457-4B57-0270-392F-6988B33CE2A8}{1}{B0}"><one:OEChildren><one:OE creationTime="2026-09-13T08:12:56.000Z" lastModifiedTime="2026-09-13T08:12:56.000Z" objectID="{D490ACFE-4E2D-09CE-1F5F-0866F94CA145}{1}{B0}" alignment="left" quickStyleIndex="1"><one:T><![CDATA[Other cell]]></one:T></one:OE></one:OEChildren></one:Cell></one:Row></one:Table></one:OE></one:OEChildren></one:Outline><one:Outline author="Copier" lastModifiedBy="Copier" lastModifiedTime="2026-09-13T08:12:56.000Z" objectID="{4D870AE7-2513-0CB4-3066-2217A47AB044}{1}{B0}"><one:Position x="540.0" y="108.0" z="1"/><one:Size width="99.85796356201171" height="13.42771339416504"/><one:OEChildren><one:OE creationTime="2026-09-13T08:12:56.000Z" lastModifiedTime="2026-09-13T08:12:56.000Z" objectID="{EFA33014-C3C9-0764-0876-5357D230EE70}{1}{B0}" alignment="left" quickStyleIndex="1"><one:T><![CDATA[Other outline]]></one:T></one:OE></one:OEChildren></one:Outline></one:Page> |
corpus/page-copy/cold/read/page-005.navigation.json+1-1| ... | ... | @@ -6,7 +6,7 @@ |
| 6 | 6 | "h": 600, |
| 7 | 7 | "error": null, |
| 8 | 8 | "win": { |
| 9 | "title": "Before the picture - Microsoft OneNote", | |
| 9 | "title": "Indent first subtree - Microsoft OneNote", | |
| 10 | 10 | "class": "Framework::CFrame", |
| 11 | 11 | "dialog": false |
| 12 | 12 | } |
corpus/page-copy/cold/read/page-005.png| Binary files a/corpus/page-copy/cold/read/page-005.png and b/corpus/page-copy/cold/read/page-005.png differ |
corpus/page-copy/cold/read/page-005.xml+4-3| ... | ... | @@ -1,4 +1,5 @@ |
| 1 | 1 | <?xml version="1.0"?> |
| 2 | <one:Page xmlns:one="http://schemas.microsoft.com/office/onenote/2010/onenote" ID="{B5A45771-4A39-05F8-1953-4F2F9B2B33A5}{1}{B0}" name="Before the picture" dateTime="2026-09-13T07:33:14.000Z" lastModifiedTime="2026-09-13T07:34:36.000Z" pageLevel="1" lang="en-US"><one:QuickStyleDef index="0" name="PageTitle" font="Calibri" fontSize="17.0"/><one:PageSettings RTL="false" color="automatic"><one:PageSize><one:Automatic/></one:PageSize><one:RuleLines visible="false"/></one:PageSettings><one:Title showDate="false" showTime="false" lang="en-US"><one:OE author="Copier" lastModifiedBy="Copier" creationTime="2026-09-13T07:33:14.000Z" lastModifiedTime="2026-09-13T07:33:14.000Z" objectID="{B5A45771-4A39-05F8-1953-4F2F9B2B33A5}{15}{B0}" alignment="left" quickStyleIndex="0" style="font-family:Calibri;font-size:17.0pt"><one:T><![CDATA[Before the picture]]></one:T></one:OE></one:Title><one:Outline author="Copier" lastModifiedBy="Copier" lastModifiedTime="2026-09-13T07:33:14.000Z" objectID="{6323EB68-A315-07CD-37C1-E46DAF4BAB42}{1}{B0}"><one:Position x="36.0" y="36.0" z="0"/><one:Size width="148.3100738525391" height="27.60543251037598"/><one:Indents><one:Indent level="0" indent="0.0"/></one:Indents><one:OEChildren><one:OE creationTime="2026-09-13T07:33:14.000Z" lastModifiedTime="2026-09-13T07:33:14.000Z" objectID="{078AE9E1-0253-0D93-182A-750B047E4D60}{1}{B0}" alignment="left" style="font-family:Calibri;font-size:11.0pt"><one:T><![CDATA[Before the picture]]></one:T></one:OE><one:OE creationTime="2026-09-13T07:33:14.000Z" lastModifiedTime="2026-09-13T07:33:14.000Z" objectID="{4DBAC23A-2DBC-0548-3811-E4D1B951886F}{1}{B0}" alignment="left"><one:Image format="png"><one:Data>iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAIAAACQd1PeAAAADElEQVQI12P4z8AAAAMBAQAY3Y2w | |
| 3 | AAAAAElFTkSuQmCC | |
| 4 | </one:Data></one:Image></one:OE><one:OE creationTime="2026-09-13T07:33:14.000Z" lastModifiedTime="2026-09-13T07:33:14.000Z" objectID="{79D39D0E-8F58-05A6-1C44-0CB6265FFE97}{1}{B0}" alignment="left" style="font-family:Calibri;font-size:11.0pt"><one:T><![CDATA[After the picture]]></one:T></one:OE></one:OEChildren></one:Outline></one:Page> | |
| 2 | <one:Page xmlns:one="http://schemas.microsoft.com/office/onenote/2010/onenote" ID="{55B596AA-4540-085D-142D-9F788431ACE5}{1}{B0}" name="Indent first subtree" dateTime="2026-09-13T08:12:55.000Z" lastModifiedTime="2026-09-13T08:14:27.000Z" pageLevel="1" lang="en-US"><one:TagDef index="0" type="0" symbol="3" fontColor="automatic" highlightColor="none" name="Preserved task"/><one:QuickStyleDef index="0" name="PageTitle" font="Calibri" fontSize="17.0"/><one:QuickStyleDef index="1" 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 showDate="false" showTime="false" lang="en-US"><one:OE author="Copier" lastModifiedBy="Copier" creationTime="2026-09-13T08:12:55.000Z" lastModifiedTime="2026-09-13T08:12:55.000Z" objectID="{55B596AA-4540-085D-142D-9F788431ACE5}{15}{B0}" alignment="left" quickStyleIndex="0" style="font-family:Calibri;font-size:17.0pt"><one:T><![CDATA[Indent first subtree]]></one:T></one:OE></one:Title><one:Outline author="Copier" lastModifiedBy="Copier" lastModifiedTime="2026-09-13T08:12:56.000Z" objectID="{5BD6B4E1-21C1-08FD-38E8-4C7ADD81FBB1}{1}{B0}"><one:Position x="72.0" y="108.0" z="0"/><one:Size width="142.6107788085937" height="53.71086883544922"/><one:OEChildren><one:OE creationTime="2026-09-13T08:12:56.000Z" lastModifiedTime="2026-09-13T08:12:56.000Z" objectID="{8B6DEB92-F345-02E1-1FB6-90BBC691E721}{1}{B0}" alignment="left" quickStyleIndex="1"><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 | |
| 3 | style='font-weight:bold'>Target &#129408; é</span> <a | |
| 4 | href="https://example.invalid/tree">Link label</a>]]></one:T><one:OEChildren><one:OE creationTime="2026-09-13T08:12:56.000Z" lastModifiedTime="2026-09-13T08:12:56.000Z" objectID="{365B8C25-37F9-0C75-1AD0-A969AB393EEC}{1}{B0}" alignment="left" quickStyleIndex="1"><one:T style="font-family:Calibri;font-size:11.0pt"><![CDATA[<span | |
| 5 | style='font-style:italic'>Child</span>]]></one:T><one:OEChildren><one:OE creationTime="2026-09-13T08:12:56.000Z" lastModifiedTime="2026-09-13T08:12:56.000Z" objectID="{53D9A482-FB38-09F8-318E-E7A2A0EA655A}{1}{B0}" alignment="left" quickStyleIndex="1"><one:T><![CDATA[Grandchild]]></one:T></one:OE></one:OEChildren></one:OE></one:OEChildren></one:OE><one:OE creationTime="2026-09-13T08:12:56.000Z" lastModifiedTime="2026-09-13T08:12:56.000Z" objectID="{C7BC8628-6A45-0A7E-10CA-1A957E36B827}{1}{B0}" alignment="left" quickStyleIndex="1"><one:T><![CDATA[Trailing sibling]]></one:T></one:OE></one:OEChildren></one:Outline><one:Outline author="Copier" lastModifiedBy="Copier" lastModifiedTime="2026-09-13T08:12:56.000Z" objectID="{B5066461-BBDD-09E8-223D-5B839E2A8637}{1}{B0}"><one:Position x="540.0" y="108.0" z="1"/><one:Size width="99.85796356201171" height="13.42771339416504"/><one:OEChildren><one:OE creationTime="2026-09-13T08:12:56.000Z" lastModifiedTime="2026-09-13T08:12:56.000Z" objectID="{EDB23709-B01D-0CD2-08A7-A9EB953087ED}{1}{B0}" alignment="left" quickStyleIndex="1"><one:T><![CDATA[Other outline]]></one:T></one:OE></one:OEChildren></one:Outline></one:Page> |
corpus/page-copy/cold/read/page-006.navigation.json+1-1| ... | ... | @@ -6,7 +6,7 @@ |
| 6 | 6 | "h": 600, |
| 7 | 7 | "error": null, |
| 8 | 8 | "win": { |
| 9 | "title": "Before the file - Microsoft OneNote", | |
| 9 | "title": "Bold \ud83e\udd80 italic e\u0301 color \u6771\u4eac - Microsoft OneNote", | |
| 10 | 10 | "class": "Framework::CFrame", |
| 11 | 11 | "dialog": false |
| 12 | 12 | } |
corpus/page-copy/cold/read/page-006.png| Binary files a/corpus/page-copy/cold/read/page-006.png and b/corpus/page-copy/cold/read/page-006.png differ |
corpus/page-copy/cold/read/page-006.xml+19-1| ... | ... | @@ -1,2 +1,20 @@ |
| 1 | 1 | <?xml version="1.0"?> |
| 2 | <one:Page xmlns:one="http://schemas.microsoft.com/office/onenote/2010/onenote" ID="{C12C0ECF-DDF8-0A21-11BE-3074429542E0}{1}{B0}" name="Before the file" dateTime="2026-09-13T07:33:14.000Z" lastModifiedTime="2026-09-13T07:34:35.000Z" pageLevel="1" lang="en-US"><one:QuickStyleDef index="0" name="PageTitle" font="Calibri" fontSize="17.0"/><one:PageSettings RTL="false" color="automatic"><one:PageSize><one:Automatic/></one:PageSize><one:RuleLines visible="false"/></one:PageSettings><one:Title showDate="false" showTime="false" lang="en-US"><one:OE author="Copier" lastModifiedBy="Copier" creationTime="2026-09-13T07:33:14.000Z" lastModifiedTime="2026-09-13T07:33:14.000Z" objectID="{C12C0ECF-DDF8-0A21-11BE-3074429542E0}{15}{B0}" alignment="left" quickStyleIndex="0" style="font-family:Calibri;font-size:17.0pt"><one:T><![CDATA[Before the file]]></one:T></one:OE></one:Title><one:Outline author="Copier" lastModifiedBy="Copier" lastModifiedTime="2026-09-13T07:33:14.000Z" objectID="{A4D24969-1B13-0F34-3174-834AD8FF8832}{1}{B0}"><one:Position x="36.0" y="36.0" z="0"/><one:Size width="130.4619598388672" height="89.85542297363281"/><one:Indents><one:Indent level="0" indent="0.0"/></one:Indents><one:OEChildren><one:OE creationTime="2026-09-13T07:33:14.000Z" lastModifiedTime="2026-09-13T07:33:14.000Z" objectID="{6D8ADE9E-3EE4-03A9-2EC9-0A80C321B126}{1}{B0}" alignment="left" style="font-family:Calibri;font-size:11.0pt"><one:T><![CDATA[Before the file]]></one:T></one:OE><one:OE creationTime="2026-09-13T07:33:14.000Z" lastModifiedTime="2026-09-13T07:33:14.000Z" objectID="{03AD9394-425B-0B9C-0D27-CA384DFFCEBF}{1}{B0}" alignment="left"><one:InsertedFile pathCache="C:\Users\clover\AppData\Local\Microsoft\OneNote\14.0\OneNoteOfflineCache_Files\6d823ba5-6b7e-4df3-947b-a1047440dfa2.txt" preferredName="notes 🦀.txt"/></one:OE><one:OE creationTime="2026-09-13T07:33:14.000Z" lastModifiedTime="2026-09-13T07:33:14.000Z" objectID="{A6E026B4-3D17-078E-20A3-50C86A85A2AB}{1}{B0}" alignment="left" style="font-family:Calibri;font-size:11.0pt"><one:T><![CDATA[After the file]]></one:T></one:OE></one:OEChildren></one:Outline></one:Page> | |
| 2 | <one:Page xmlns:one="http://schemas.microsoft.com/office/onenote/2010/onenote" ID="{5E04C302-1E83-0CCD-1715-B0A2566E0191}{1}{B0}" name="Bold 🦀 italic é color 東京" dateTime="2026-09-13T08:12:55.000Z" lastModifiedTime="2026-09-13T08:14:26.000Z" pageLevel="1" lang="en-US"><one:QuickStyleDef index="0" name="PageTitle" font="Calibri" fontSize="17.0"/><one:QuickStyleDef index="1" 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 showDate="false" showTime="false" lang="en-US"><one:OE author="Copier" lastModifiedBy="Copier" creationTime="2026-09-13T08:12:55.000Z" lastModifiedTime="2026-09-13T08:12:55.000Z" objectID="{5E04C302-1E83-0CCD-1715-B0A2566E0191}{15}{B0}" alignment="left" quickStyleIndex="0" style="font-family:Calibri;font-size:17.0pt"><one:T><![CDATA[Bold &#129408; italic é color 東京]]></one:T></one:OE></one:Title><one:Outline author="Copier" lastModifiedBy="Copier" lastModifiedTime="2026-09-13T08:12:56.000Z" objectID="{B63306AF-2B95-0428-2EB2-67405305D5CD}{1}{B0}"><one:Position x="36.0" y="14.40000057220459" z="0"/><one:Size width="127.5136947631836" height="42.03070831298828"/><one:OEChildren><one:OE creationTime="2026-09-13T08:12:55.000Z" lastModifiedTime="2026-09-13T08:12:56.000Z" objectID="{07F96F7E-EE93-0108-00D0-9E4BE9011C40}{1}{B0}" alignment="left"><one:T><![CDATA[<span style='font-weight:bold; | |
| 3 | text-decoration:underline;font-family:Calibri;font-size:11.0pt'>Bold</span><span | |
| 4 | style='font-family:Calibri;font-size:11.0pt'> </span><span style='font-family: | |
| 5 | Arial;font-size:13.5pt'>&#129408;</span><span style='font-family:Calibri; | |
| 6 | font-size:11.0pt'> </span><span style='font-style:italic;text-decoration:line-through; | |
| 7 | font-family:Calibri;font-size:11.0pt'>italic</span><span style='font-family: | |
| 8 | Calibri;font-size:11.0pt'> </span><span style='vertical-align:super;font-family: | |
| 9 | Calibri;font-size:11.0pt'>é</span><span style='font-family:Calibri;font-size: | |
| 10 | 11.0pt'> </span><span style='font-family:Calibri;font-size:11.0pt;color:#0C2238; | |
| 11 | background:yellow;mso-highlight:yellow'>color</span><span style='font-family: | |
| 12 | Calibri;font-size:11.0pt'> </span><span style='vertical-align:sub;font-family: | |
| 13 | Calibri;font-size:11.0pt'>東京</span><span style='font-family:Calibri;font-size: | |
| 14 | 11.0pt'><br> | |
| 15 | End</span>]]></one:T></one:OE><one:OE creationTime="2026-09-13T08:12:55.000Z" lastModifiedTime="2026-09-13T08:12:55.000Z" objectID="{EEA4A13A-3CBD-04DA-02B1-47CF8F1BE77E}{1}{B0}" alignment="left" quickStyleIndex="1" style="font-size:11.0pt;color:#1F4E79"><one:T><![CDATA[<span | |
| 16 | style='font-weight:bold;font-family:Calibri' lang=en-US>Fictitious: café, </span><span | |
| 17 | style='font-weight:bold;font-family:SimSun' lang=en-US>東京</span><span | |
| 18 | style='font-weight:bold;font-family:Calibri' lang=en-US>, </span><span | |
| 19 | style='font-weight:bold;font-family:Arial;direction:rtl;unicode-bidi:embed' | |
| 20 | lang=ar-SA>مرحبا</span>]]></one:T></one:OE></one:OEChildren></one:Outline></one:Page> |
corpus/page-copy/cold/read/page-007.navigation.json+1-1| ... | ... | @@ -6,7 +6,7 @@ |
| 6 | 6 | "h": 600, |
| 7 | 7 | "error": null, |
| 8 | 8 | "win": { |
| 9 | "title": "Bullet item - Microsoft OneNote", | |
| 9 | "title": "Before the file - Microsoft OneNote", | |
| 10 | 10 | "class": "Framework::CFrame", |
| 11 | 11 | "dialog": false |
| 12 | 12 | } |
corpus/page-copy/cold/read/page-007.png| Binary files a/corpus/page-copy/cold/read/page-007.png and b/corpus/page-copy/cold/read/page-007.png differ |
corpus/page-copy/cold/read/page-007.xml+1-1| ... | ... | @@ -1,2 +1,2 @@ |
| 1 | 1 | <?xml version="1.0"?> |
| 2 | <one:Page xmlns:one="http://schemas.microsoft.com/office/onenote/2010/onenote" ID="{C5E005CB-753E-07E2-0C53-CD40FBB64A63}{1}{B0}" name="Bullet item" dateTime="2026-09-13T07:33:14.000Z" lastModifiedTime="2026-09-13T07:34:36.000Z" pageLevel="1" style="font-family:Calibri;font-size:11.0pt" lang="en-US"><one:QuickStyleDef index="0" name="PageTitle" font="Calibri" fontSize="17.0"/><one:PageSettings RTL="false" color="automatic"><one:PageSize><one:Automatic/></one:PageSize><one:RuleLines visible="false"/></one:PageSettings><one:Title showDate="false" showTime="false" lang="en-US"><one:OE author="Copier" lastModifiedBy="Copier" creationTime="2026-09-13T07:33:14.000Z" lastModifiedTime="2026-09-13T07:33:14.000Z" objectID="{C5E005CB-753E-07E2-0C53-CD40FBB64A63}{15}{B0}" alignment="left" quickStyleIndex="0" style="font-family:Calibri;font-size:17.0pt"><one:T><![CDATA[Bullet item]]></one:T></one:OE></one:Title><one:Outline author="Copier" lastModifiedBy="Copier" lastModifiedTime="2026-09-13T07:33:15.000Z" objectID="{04550845-DFD8-0D15-199D-14BBB6068FC4}{1}{B0}"><one:Position x="36.0" y="36.0" z="0"/><one:Size width="174.7353515625" height="93.99401092529296"/><one:Indents><one:Indent level="0" indent="0.0"/></one:Indents><one:OEChildren><one:OE creationTime="2026-09-13T07:33:15.000Z" lastModifiedTime="2026-09-13T07:33:15.000Z" objectID="{FADAD1EB-13D4-0679-1470-A27D6E3C4C82}{1}{B0}" alignment="left"><one:List><one:Bullet bullet="3" fontSize="11.0"/></one:List><one:T><![CDATA[Bullet item]]></one:T></one:OE><one:OE creationTime="2026-09-13T07:33:15.000Z" lastModifiedTime="2026-09-13T07:33:15.000Z" objectID="{D1386D56-B57F-01DD-3DCE-AE2F7E41CF7B}{1}{B0}" alignment="left"><one:List><one:Number numberSequence="1" numberFormat="##." fontSize="11.0" font="Calibri" text="I."/></one:List><one:T><![CDATA[First numbered]]></one:T></one:OE><one:OE creationTime="2026-09-13T07:33:15.000Z" lastModifiedTime="2026-09-13T07:33:15.000Z" objectID="{8F5A5D13-ADD9-0514-013E-D1A0CBA1E68F}{1}{B0}" alignment="left"><one:List><one:Number numberSequence="1" numberFormat="##." fontSize="11.0" font="Calibri" text="II."/></one:List><one:T><![CDATA[Second numbered]]></one:T><one:OEChildren><one:OE creationTime="2026-09-13T07:33:15.000Z" lastModifiedTime="2026-09-13T07:33:15.000Z" objectID="{448444D9-663C-0454-150E-544F2D29DAED}{1}{B0}" alignment="left"><one:List><one:Number numberSequence="1" numberFormat="##." fontSize="11.0" font="Calibri" text="I."/></one:List><one:T><![CDATA[Nested numbered]]></one:T></one:OE></one:OEChildren></one:OE><one:OE creationTime="2026-09-13T07:33:15.000Z" lastModifiedTime="2026-09-13T07:33:15.000Z" objectID="{AB4C6543-D5B5-02F2-18CD-1EA3C75D0B5F}{1}{B0}" alignment="left"><one:List><one:Number numberSequence="1" numberFormat="##." fontSize="11.0" font="Calibri" text="III."/></one:List><one:T><![CDATA[Restarted at three]]></one:T><one:OEChildren><one:OE creationTime="2026-09-13T07:33:15.000Z" lastModifiedTime="2026-09-13T07:33:15.000Z" objectID="{1E15DFFF-2CEC-03FA-0FEF-75E2303FB336}{1}{B0}" alignment="left"><one:T><![CDATA[Nested plain]]></one:T></one:OE></one:OEChildren></one:OE><one:OE creationTime="2026-09-13T07:33:15.000Z" lastModifiedTime="2026-09-13T07:33:15.000Z" objectID="{49D667B4-861E-0253-29DB-8BA25CF21B9E}{1}{B0}" alignment="left"><one:T><![CDATA[Plain again]]></one:T></one:OE></one:OEChildren></one:Outline></one:Page> | |
| 2 | <one:Page xmlns:one="http://schemas.microsoft.com/office/onenote/2010/onenote" ID="{62E12C49-D5FE-0850-17D5-B4DC95B736E9}{1}{B0}" name="Before the file" dateTime="2026-09-13T08:12:55.000Z" lastModifiedTime="2026-09-13T08:14:26.000Z" pageLevel="1" lang="en-US"><one:QuickStyleDef index="0" name="PageTitle" font="Calibri" fontSize="17.0"/><one:PageSettings RTL="false" color="automatic"><one:PageSize><one:Automatic/></one:PageSize><one:RuleLines visible="false"/></one:PageSettings><one:Title showDate="false" showTime="false" lang="en-US"><one:OE author="Copier" lastModifiedBy="Copier" creationTime="2026-09-13T08:12:55.000Z" lastModifiedTime="2026-09-13T08:12:55.000Z" objectID="{62E12C49-D5FE-0850-17D5-B4DC95B736E9}{15}{B0}" alignment="left" quickStyleIndex="0" style="font-family:Calibri;font-size:17.0pt"><one:T><![CDATA[Before the file]]></one:T></one:OE></one:Title><one:Outline author="Copier" lastModifiedBy="Copier" lastModifiedTime="2026-09-13T08:12:55.000Z" objectID="{FBCA9C23-1A13-020A-35BC-1365A45C381E}{1}{B0}"><one:Position x="36.0" y="36.0" z="0"/><one:Size width="130.4619598388672" height="89.85542297363281"/><one:Indents><one:Indent level="0" indent="0.0"/></one:Indents><one:OEChildren><one:OE creationTime="2026-09-13T08:12:55.000Z" lastModifiedTime="2026-09-13T08:12:55.000Z" objectID="{2A6BB41D-EDD1-0546-0571-2950BFD2D187}{1}{B0}" alignment="left" style="font-family:Calibri;font-size:11.0pt"><one:T><![CDATA[Before the file]]></one:T></one:OE><one:OE creationTime="2026-09-13T08:12:55.000Z" lastModifiedTime="2026-09-13T08:12:55.000Z" objectID="{9E89195D-B7EC-0AC4-34FD-F47D633F0533}{1}{B0}" alignment="left"><one:InsertedFile pathCache="C:\Users\clover\AppData\Local\Microsoft\OneNote\14.0\OneNoteOfflineCache_Files\6bf086f4-be12-4374-9140-4ddaf36216fe.txt" preferredName="notes 🦀.txt"/></one:OE><one:OE creationTime="2026-09-13T08:12:55.000Z" lastModifiedTime="2026-09-13T08:12:55.000Z" objectID="{48D46AA0-F634-084B-171A-1D72CF298968}{1}{B0}" alignment="left" style="font-family:Calibri;font-size:11.0pt"><one:T><![CDATA[After the file]]></one:T></one:OE></one:OEChildren></one:Outline></one:Page> |
corpus/page-copy/cold/read/page-008.navigation.json+1-1| ... | ... | @@ -6,7 +6,7 @@ |
| 6 | 6 | "h": 600, |
| 7 | 7 | "error": null, |
| 8 | 8 | "win": { |
| 9 | "title": "A notebook created in Rust. - Microsoft OneNote", | |
| 9 | "title": "Delete numbered subtree - Microsoft OneNote", | |
| 10 | 10 | "class": "Framework::CFrame", |
| 11 | 11 | "dialog": false |
| 12 | 12 | } |
corpus/page-copy/cold/read/page-008.png| Binary files a/corpus/page-copy/cold/read/page-008.png and b/corpus/page-copy/cold/read/page-008.png differ |
corpus/page-copy/cold/read/page-008.xml+4-1| ... | ... | @@ -1,2 +1,5 @@ |
| 1 | 1 | <?xml version="1.0"?> |
| 2 | <one:Page xmlns:one="http://schemas.microsoft.com/office/onenote/2010/onenote" ID="{D4C06049-3C91-0190-0C2E-1BB1EBA49EBA}{1}{B0}" name="A notebook created in Rust." dateTime="2026-09-13T07:33:15.000Z" lastModifiedTime="2026-09-13T07:34:36.000Z" pageLevel="1" style="font-family:Calibri;font-size:11.0pt" lang="en-US"><one:QuickStyleDef index="0" name="PageTitle" font="Calibri" fontSize="17.0"/><one:PageSettings RTL="false" color="automatic"><one:PageSize><one:Automatic/></one:PageSize><one:RuleLines visible="false"/></one:PageSettings><one:Title showDate="false" showTime="false" lang="en-US"><one:OE author="Copier" lastModifiedBy="Copier" creationTime="2026-09-13T07:33:15.000Z" lastModifiedTime="2026-09-13T07:33:15.000Z" objectID="{D4C06049-3C91-0190-0C2E-1BB1EBA49EBA}{15}{B0}" alignment="left" quickStyleIndex="0" style="font-family:Calibri;font-size:17.0pt"><one:T><![CDATA[A notebook created in Rust.]]></one:T></one:OE></one:Title><one:Outline author="Copier" lastModifiedBy="Copier" lastModifiedTime="2026-09-13T07:33:16.000Z" objectID="{F0CA7185-BDBF-066E-0D2C-CAE46E036850}{1}{B0}"><one:Position x="36.0" y="36.0" z="0"/><one:Size width="191.1661224365234" height="13.4277172088623"/><one:Indents><one:Indent level="0" indent="0.0"/></one:Indents><one:OEChildren><one:OE creationTime="2026-09-13T07:33:16.000Z" lastModifiedTime="2026-09-13T07:33:16.000Z" objectID="{F7D0FEC9-71DC-00E3-30D7-07DB00C2623B}{1}{B0}" alignment="left"><one:T><![CDATA[A notebook created in Rust.]]></one:T></one:OE></one:OEChildren></one:Outline></one:Page> | |
| 2 | <one:Page xmlns:one="http://schemas.microsoft.com/office/onenote/2010/onenote" ID="{6EC9E652-85BD-0524-17E7-232F5951B731}{1}{B0}" name="Delete numbered subtree" dateTime="2026-09-13T08:12:57.000Z" lastModifiedTime="2026-09-13T08:14:27.000Z" pageLevel="1" lang="en-US"><one:TagDef index="0" type="0" symbol="3" fontColor="automatic" highlightColor="none" name="Preserved task"/><one:QuickStyleDef index="0" name="PageTitle" font="Calibri" fontSize="17.0"/><one:QuickStyleDef index="1" 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 showDate="false" showTime="false" lang="en-US"><one:OE author="Copier" lastModifiedBy="Copier" creationTime="2026-09-13T08:12:57.000Z" lastModifiedTime="2026-09-13T08:12:57.000Z" objectID="{6EC9E652-85BD-0524-17E7-232F5951B731}{15}{B0}" alignment="left" quickStyleIndex="0" style="font-family:Calibri;font-size:17.0pt"><one:T><![CDATA[Delete numbered subtree]]></one:T></one:OE></one:Title><one:Outline author="Copier" lastModifiedBy="Copier" lastModifiedTime="2026-09-13T08:12:58.000Z" objectID="{7D694249-C0B4-02DD-1DC7-3136ED2FFA27}{1}{B0}"><one:Position x="72.0" y="108.0" z="0"/><one:Size width="142.6107788085937" height="67.13858032226562"/><one:OEChildren><one:OE creationTime="2026-09-13T08:12:57.000Z" lastModifiedTime="2026-09-13T08:12:57.000Z" objectID="{758447BB-8217-0430-1A24-108E47546937}{1}{B0}" alignment="left" quickStyleIndex="1"><one:List><one:Number numberSequence="1" numberFormat="##." fontSize="11.0" font="Calibri" text="I."/></one:List><one:T><![CDATA[Anchor]]></one:T></one:OE><one:OE creationTime="2026-09-13T08:12:57.000Z" lastModifiedTime="2026-09-13T08:12:58.000Z" objectID="{72575BCE-8279-0163-3BD9-443858B25152}{1}{B0}" alignment="left" quickStyleIndex="1"><one:Tag index="0" completed="true" disabled="false" creationDate="2020-01-02T03:04:05.000Z" completionDate="2020-01-02T04:05:06.000Z"/><one:List><one:Number numberSequence="1" numberFormat="##." fontSize="11.0" font="Calibri" text="II."/></one:List><one:T><![CDATA[<span | |
| 3 | style='font-weight:bold'>Target &#129408; é</span> <a | |
| 4 | href="https://example.invalid/tree">Link label</a>]]></one:T><one:OEChildren><one:OE creationTime="2026-09-13T08:12:57.000Z" lastModifiedTime="2026-09-13T08:12:57.000Z" objectID="{59A91EE5-A5B6-06B1-328F-DCF3FC7EDAAC}{1}{B0}" alignment="left" quickStyleIndex="1"><one:T style="font-family:Calibri;font-size:11.0pt"><![CDATA[<span | |
| 5 | style='font-style:italic'>Child</span>]]></one:T><one:OEChildren><one:OE creationTime="2026-09-13T08:12:57.000Z" lastModifiedTime="2026-09-13T08:12:57.000Z" objectID="{9B857AAD-2B9A-0AB3-1341-A048617E97BC}{1}{B0}" alignment="left" quickStyleIndex="1"><one:T><![CDATA[Grandchild]]></one:T></one:OE></one:OEChildren></one:OE></one:OEChildren></one:OE><one:OE creationTime="2026-09-13T08:12:57.000Z" lastModifiedTime="2026-09-13T08:12:57.000Z" objectID="{C4A6021B-B90F-0CD2-2BDB-0BDD084AB0A6}{1}{B0}" alignment="left" quickStyleIndex="1"><one:List><one:Number numberSequence="1" numberFormat="##." fontSize="11.0" font="Calibri" text="III."/></one:List><one:T><![CDATA[Trailing sibling]]></one:T></one:OE></one:OEChildren></one:Outline><one:Outline author="Copier" lastModifiedBy="Copier" lastModifiedTime="2026-09-13T08:12:57.000Z" objectID="{194A9C6A-9CCD-07AA-13B8-DE3F2E45394E}{1}{B0}"><one:Position x="540.0" y="108.0" z="1"/><one:Size width="99.85796356201171" height="13.42771339416504"/><one:OEChildren><one:OE creationTime="2026-09-13T08:12:57.000Z" lastModifiedTime="2026-09-13T08:12:57.000Z" objectID="{D3A6B926-9395-0950-1BB5-A6C460D39349}{1}{B0}" alignment="left" quickStyleIndex="1"><one:T><![CDATA[Other outline]]></one:T></one:OE></one:OEChildren></one:Outline></one:Page> |
corpus/page-copy/cold/read/page-009.navigation.json created+13| ... | ... | @@ -0,0 +1,13 @@ |
| 1 | { | |
| 2 | "exit": 0, | |
| 3 | "stdout": "", | |
| 4 | "stderr": "", | |
| 5 | "w": 800, | |
| 6 | "h": 600, | |
| 7 | "error": null, | |
| 8 | "win": { | |
| 9 | "title": "Equations below - Microsoft OneNote", | |
| 10 | "class": "Framework::CFrame", | |
| 11 | "dialog": false | |
| 12 | } | |
| 13 | } | |
| \ No newline at end of file |
corpus/page-copy/cold/read/page-009.png created| Binary files /dev/null and b/corpus/page-copy/cold/read/page-009.png differ |
corpus/page-copy/cold/read/page-009.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="{78595C91-C5E1-0D03-3A98-A98CA31DE5A8}{1}{B0}" name="Equations below" dateTime="2026-09-13T08:12:59.000Z" lastModifiedTime="2026-09-13T08:14:27.000Z" pageLevel="1" style="font-family:Calibri;font-size:11.0pt" lang="en-US"><one:QuickStyleDef index="0" name="PageTitle" font="Calibri" fontSize="17.0"/><one:PageSettings RTL="false" color="automatic"><one:PageSize><one:Automatic/></one:PageSize><one:RuleLines visible="false"/></one:PageSettings><one:Title showDate="false" showTime="false" lang="en-US"><one:OE author="Copier" lastModifiedBy="Copier" creationTime="2026-09-13T08:12:59.000Z" lastModifiedTime="2026-09-13T08:12:59.000Z" objectID="{78595C91-C5E1-0D03-3A98-A98CA31DE5A8}{15}{B0}" alignment="left" quickStyleIndex="0" style="font-family:Calibri;font-size:17.0pt"><one:T><![CDATA[Equations below]]></one:T></one:OE></one:Title><one:Outline author="Copier" lastModifiedBy="Copier" lastModifiedTime="2026-09-13T08:13:01.000Z" objectID="{FF465D92-B6F0-0E57-3F42-D3F428E0F163}{1}{B0}"><one:Position x="36.0" y="36.0" z="0"/><one:Size width="140.9678649902344" height="208.9916534423828"/><one:Indents><one:Indent level="0" indent="0.0"/></one:Indents><one:OEChildren><one:OE creationTime="2026-09-13T08:13:01.000Z" lastModifiedTime="2026-09-13T08:13:01.000Z" objectID="{25D933DF-AC4B-0333-0643-3483B2E2652A}{1}{B0}" alignment="left"><one:T><![CDATA[Equations below]]></one:T></one:OE><one:OE creationTime="2026-09-13T08:13:01.000Z" lastModifiedTime="2026-09-13T08:13:01.000Z" objectID="{73426626-83B5-05D8-26F7-5D6887ED2AB5}{1}{B0}" alignment="left" style="font-family:'Cambria Math';font-size:11.0pt"><one:T><![CDATA[<!--[if mathML]><mml:math xmlns:mml="http://www.w3.org/1998/Math/MathML" display="block"><mml:msup><mml:mi>x</mml:mi><mml:mn>2</mml:mn></mml:msup><mml:mo>+</mml:mo><mml:msup><mml:mi>y</mml:mi><mml:mn>2</mml:mn></mml:msup><mml:mo>=</mml:mo><mml:msup><mml:mi>z</mml:mi><mml:mn>2</mml:mn></mml:msup></mml:math><![endif]-->]]></one:T></one:OE><one:OE creationTime="2026-09-13T08:13:01.000Z" lastModifiedTime="2026-09-13T08:13:01.000Z" objectID="{45DEE337-060F-078E-1093-87D9A54DF41A}{1}{B0}" alignment="left" style="font-family:'Cambria Math';font-size:11.0pt"><one:T><![CDATA[<!--[if mathML]><mml:math xmlns:mml="http://www.w3.org/1998/Math/MathML" display="block"><mml:mfrac><mml:mrow><mml:mi>a</mml:mi><mml:mo>+</mml:mo><mml:mi>b</mml:mi></mml:mrow><mml:mrow><mml:mi>c</mml:mi><mml:mo>+</mml:mo><mml:mi>d</mml:mi></mml:mrow></mml:mfrac></mml:math><![endif]-->]]></one:T></one:OE><one:OE creationTime="2026-09-13T08:13:01.000Z" lastModifiedTime="2026-09-13T08:13:01.000Z" objectID="{68218407-AC5B-0355-295E-667A238EAC19}{1}{B0}" alignment="left" style="font-size:11.0pt"><one:T><![CDATA[<span | |
| 3 | style='font-family:Calibri' lang=en-US>Inline </span><!--[if mathML]><mml:math xmlns:mml="http://www.w3.org/1998/Math/MathML"><mml:mi>&#120572;</mml:mi><mml:mo>+</mml:mo><mml:mi>&#120573;</mml:mi></mml:math><![endif]-->]]></one:T></one:OE><one:OE creationTime="2026-09-13T08:13:01.000Z" lastModifiedTime="2026-09-13T08:13:01.000Z" objectID="{3F067690-E557-00BC-3846-0628BB3D7133}{1}{B0}" alignment="left" style="font-family:'Cambria Math';font-size:11.0pt"><one:T><![CDATA[<!--[if mathML]><mml:math xmlns:mml="http://www.w3.org/1998/Math/MathML" display="block"><mml:msub><mml:mi>a</mml:mi><mml:mn>1</mml:mn></mml:msub><mml:mo>+</mml:mo><mml:msub><mml:mi>b</mml:mi><mml:mn>2</mml:mn></mml:msub></mml:math><![endif]-->]]></one:T></one:OE><one:OE creationTime="2026-09-13T08:13:01.000Z" lastModifiedTime="2026-09-13T08:13:01.000Z" objectID="{7156930C-7D25-0CD1-1992-346BE0DD05FD}{1}{B0}" alignment="left" style="font-family:'Cambria Math';font-size:11.0pt"><one:T><![CDATA[<!--[if mathML]><mml:math xmlns:mml="http://www.w3.org/1998/Math/MathML" display="block"><mml:msubsup><mml:mi>x</mml:mi><mml:mi>i</mml:mi><mml:mn>2</mml:mn></mml:msubsup></mml:math><![endif]-->]]></one:T></one:OE><one:OE creationTime="2026-09-13T08:13:01.000Z" lastModifiedTime="2026-09-13T08:13:01.000Z" objectID="{1DE19BC8-B93A-02DB-2FA8-92B03D373A73}{1}{B0}" alignment="left" style="font-family:'Cambria Math';font-size:11.0pt"><one:T><![CDATA[<!--[if mathML]><mml:math xmlns:mml="http://www.w3.org/1998/Math/MathML" display="block"><mml:mfenced><mml:mrow><mml:mi>a</mml:mi><mml:mo>+</mml:mo><mml:mi>b</mml:mi></mml:mrow></mml:mfenced></mml:math><![endif]-->]]></one:T></one:OE><one:OE creationTime="2026-09-13T08:13:01.000Z" lastModifiedTime="2026-09-13T08:13:01.000Z" objectID="{5C43FBBD-302D-09D2-28A9-18789A71A072}{1}{B0}" alignment="left" style="font-family:'Cambria Math';font-size:11.0pt"><one:T><![CDATA[<!--[if mathML]><mml:math xmlns:mml="http://www.w3.org/1998/Math/MathML" display="block"><mml:msubsup><mml:mo stretchy="false">∫</mml:mo><mml:mn>0</mml:mn><mml:mn>1</mml:mn></mml:msubsup><mml:mrow><mml:mi>x</mml:mi><mml:mo>&nbsp;</mml:mo><mml:mi>d</mml:mi><mml:mi>x</mml:mi><mml:mo>&nbsp;</mml:mo></mml:mrow></mml:math><![endif]-->]]></one:T></one:OE><one:OE creationTime="2026-09-13T08:13:01.000Z" lastModifiedTime="2026-09-13T08:13:01.000Z" objectID="{8DBDED4C-17CA-0463-240E-91F1134B5E9F}{1}{B0}" alignment="left" style="font-family:'Cambria Math';font-size:11.0pt"><one:T><![CDATA[<!--[if mathML]><mml:math xmlns:mml="http://www.w3.org/1998/Math/MathML" display="block"><mml:munderover><mml:mo stretchy="false">∑</mml:mo><mml:mrow><mml:mi>i</mml:mi><mml:mo>=</mml:mo><mml:mn>1</mml:mn></mml:mrow><mml:mi>n</mml:mi></mml:munderover><mml:mrow><mml:mi>i</mml:mi><mml:mo>&nbsp;</mml:mo></mml:mrow></mml:math><![endif]-->]]></one:T></one:OE><one:OE creationTime="2026-09-13T08:13:01.000Z" lastModifiedTime="2026-09-13T08:13:01.000Z" objectID="{214F8EE1-64A0-0957-0A3F-F8E7D05B6586}{1}{B0}" alignment="left" style="font-family:'Cambria Math';font-size:11.0pt"><one:T><![CDATA[<!--[if mathML]><mml:math xmlns:mml="http://www.w3.org/1998/Math/MathML" display="block"><mml:msup><mml:mi>x</mml:mi><mml:mn>2</mml:mn></mml:msup><mml:mo>+</mml:mo><mml:mn>1</mml:mn></mml:math><![endif]-->]]></one:T></one:OE><one:OE creationTime="2026-09-13T08:13:01.000Z" lastModifiedTime="2026-09-13T08:13:01.000Z" objectID="{3715C26F-37BB-031C-1197-F79A9E19EE60}{1}{B0}" alignment="left" style="font-family:'Cambria Math';font-size:11.0pt"><one:T><![CDATA[<!--[if mathML]><mml:math xmlns:mml="http://www.w3.org/1998/Math/MathML" display="block"><mml:mfrac><mml:mrow><mml:mi>a</mml:mi><mml:mo>+</mml:mo><mml:mi>b</mml:mi></mml:mrow><mml:mrow><mml:msup><mml:mi>c</mml:mi><mml:mn>2</mml:mn></mml:msup></mml:mrow></mml:mfrac></mml:math><![endif]-->]]></one:T></one:OE></one:OEChildren></one:Outline></one:Page> |
corpus/page-copy/cold/read/page-010.navigation.json created+13| ... | ... | @@ -0,0 +1,13 @@ |
| 1 | { | |
| 2 | "exit": 0, | |
| 3 | "stdout": "", | |
| 4 | "stderr": "", | |
| 5 | "w": 800, | |
| 6 | "h": 600, | |
| 7 | "error": null, | |
| 8 | "win": { | |
| 9 | "title": "Move numbered subtree down - Microsoft OneNote", | |
| 10 | "class": "Framework::CFrame", | |
| 11 | "dialog": false | |
| 12 | } | |
| 13 | } | |
| \ No newline at end of file |
corpus/page-copy/cold/read/page-010.png created| Binary files /dev/null and b/corpus/page-copy/cold/read/page-010.png differ |
corpus/page-copy/cold/read/page-010.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="{79EFBB50-C028-09DE-005B-75E21D0ED54C}{1}{B0}" name="Move numbered subtree down" dateTime="2026-09-13T08:12:56.000Z" lastModifiedTime="2026-09-13T08:14:27.000Z" pageLevel="1" lang="en-US"><one:TagDef index="0" type="0" symbol="3" fontColor="automatic" highlightColor="none" name="Preserved task"/><one:QuickStyleDef index="0" name="PageTitle" font="Calibri" fontSize="17.0"/><one:QuickStyleDef index="1" 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 showDate="false" showTime="false" lang="en-US"><one:OE author="Copier" lastModifiedBy="Copier" creationTime="2026-09-13T08:12:56.000Z" lastModifiedTime="2026-09-13T08:12:56.000Z" objectID="{79EFBB50-C028-09DE-005B-75E21D0ED54C}{15}{B0}" alignment="left" quickStyleIndex="0" style="font-family:Calibri;font-size:17.0pt"><one:T><![CDATA[Move numbered subtree down]]></one:T></one:OE></one:Title><one:Outline author="Copier" lastModifiedBy="Copier" lastModifiedTime="2026-09-13T08:12:57.000Z" objectID="{0A534E63-2DFE-07C6-0A28-71334DEE9E4D}{1}{B0}"><one:Position x="72.0" y="108.0" z="0"/><one:Size width="142.6107788085937" height="67.13858032226562"/><one:OEChildren><one:OE creationTime="2026-09-13T08:12:57.000Z" lastModifiedTime="2026-09-13T08:12:57.000Z" objectID="{ED619F07-F6A1-0AC3-1461-04C34315FB37}{1}{B0}" alignment="left" quickStyleIndex="1"><one:List><one:Number numberSequence="1" numberFormat="##." fontSize="11.0" font="Calibri" text="I."/></one:List><one:T><![CDATA[Anchor]]></one:T></one:OE><one:OE creationTime="2026-09-13T08:12:57.000Z" lastModifiedTime="2026-09-13T08:12:57.000Z" objectID="{055B6314-3B1F-00E1-2734-2684ACC53EA4}{1}{B0}" alignment="left" quickStyleIndex="1"><one:Tag index="0" completed="true" disabled="false" creationDate="2020-01-02T03:04:05.000Z" completionDate="2020-01-02T04:05:06.000Z"/><one:List><one:Number numberSequence="1" numberFormat="##." fontSize="11.0" font="Calibri" text="II."/></one:List><one:T><![CDATA[<span | |
| 3 | style='font-weight:bold'>Target &#129408; é</span> <a | |
| 4 | href="https://example.invalid/tree">Link label</a>]]></one:T><one:OEChildren><one:OE creationTime="2026-09-13T08:12:57.000Z" lastModifiedTime="2026-09-13T08:12:57.000Z" objectID="{BC5317C5-A40F-01F9-038E-5AED4EB7626B}{1}{B0}" alignment="left" quickStyleIndex="1"><one:T style="font-family:Calibri;font-size:11.0pt"><![CDATA[<span | |
| 5 | style='font-style:italic'>Child</span>]]></one:T><one:OEChildren><one:OE creationTime="2026-09-13T08:12:57.000Z" lastModifiedTime="2026-09-13T08:12:57.000Z" objectID="{7F1F3536-4683-03A0-2FCB-4FF372F15926}{1}{B0}" alignment="left" quickStyleIndex="1"><one:T><![CDATA[Grandchild]]></one:T></one:OE></one:OEChildren></one:OE></one:OEChildren></one:OE><one:OE creationTime="2026-09-13T08:12:57.000Z" lastModifiedTime="2026-09-13T08:12:57.000Z" objectID="{4ECF5731-6B02-0ABE-1485-8D4A0B859DBE}{1}{B0}" alignment="left" quickStyleIndex="1"><one:List><one:Number numberSequence="1" numberFormat="##." fontSize="11.0" font="Calibri" text="III."/></one:List><one:T><![CDATA[Trailing sibling]]></one:T></one:OE></one:OEChildren></one:Outline><one:Outline author="Copier" lastModifiedBy="Copier" lastModifiedTime="2026-09-13T08:12:57.000Z" objectID="{4A7372E3-CEB5-09D5-18D7-2A37D082BE91}{1}{B0}"><one:Position x="540.0" y="108.0" z="1"/><one:Size width="99.85796356201171" height="13.42771339416504"/><one:OEChildren><one:OE creationTime="2026-09-13T08:12:57.000Z" lastModifiedTime="2026-09-13T08:12:57.000Z" objectID="{DB6D2123-9BB9-016D-3D56-77B46F2BEE20}{1}{B0}" alignment="left" quickStyleIndex="1"><one:T><![CDATA[Other outline]]></one:T></one:OE></one:OEChildren></one:Outline></one:Page> |
corpus/page-copy/cold/read/page-011.navigation.json created+13| ... | ... | @@ -0,0 +1,13 @@ |
| 1 | { | |
| 2 | "exit": 0, | |
| 3 | "stdout": "", | |
| 4 | "stderr": "", | |
| 5 | "w": 800, | |
| 6 | "h": 600, | |
| 7 | "error": null, | |
| 8 | "win": { | |
| 9 | "title": "Open task - Microsoft OneNote", | |
| 10 | "class": "Framework::CFrame", | |
| 11 | "dialog": false | |
| 12 | } | |
| 13 | } | |
| \ No newline at end of file |
corpus/page-copy/cold/read/page-011.png created| Binary files /dev/null and b/corpus/page-copy/cold/read/page-011.png differ |
corpus/page-copy/cold/read/page-011.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="{8E5634C2-26CB-0458-2810-125D129037C8}{1}{B0}" name="Open task" dateTime="2026-09-13T08:12:59.000Z" lastModifiedTime="2026-09-13T08:14:27.000Z" pageLevel="1" style="font-family:Calibri;font-size:11.0pt" lang="en-US"><one:TagDef index="0" type="0" symbol="3" fontColor="automatic" highlightColor="none" name="Rust task"/><one:TagDef index="1" type="1" symbol="13" fontColor="#FF0000" highlightColor="#FFFF00" name="Important"/><one:QuickStyleDef index="0" name="PageTitle" font="Calibri" fontSize="17.0"/><one:PageSettings RTL="false" color="automatic"><one:PageSize><one:Automatic/></one:PageSize><one:RuleLines visible="false"/></one:PageSettings><one:Title showDate="false" showTime="false" lang="en-US"><one:OE author="Copier" lastModifiedBy="Copier" creationTime="2026-09-13T08:12:59.000Z" lastModifiedTime="2026-09-13T08:12:59.000Z" objectID="{8E5634C2-26CB-0458-2810-125D129037C8}{15}{B0}" alignment="left" quickStyleIndex="0" style="font-family:Calibri;font-size:17.0pt"><one:T><![CDATA[Open task]]></one:T></one:OE></one:Title><one:Outline author="Copier" lastModifiedBy="Copier" lastModifiedTime="2026-09-13T08:13:00.000Z" objectID="{0F36D11A-3FE8-0019-2E63-9AD912439D52}{1}{B0}"><one:Position x="36.0" y="36.0" z="0"/><one:Size width="158.2036895751953" height="53.71086883544922"/><one:Indents><one:Indent level="0" indent="0.0"/></one:Indents><one:OEChildren><one:OE creationTime="2026-09-13T08:13:00.000Z" lastModifiedTime="2026-09-13T08:13:00.000Z" objectID="{89DFA126-B932-01B1-1C58-55D810AA0133}{1}{B0}" alignment="left"><one:Tag index="0" completed="false" disabled="false" creationDate="2020-01-02T03:04:05.000Z"/><one:T><![CDATA[Open task]]></one:T></one:OE><one:OE creationTime="2026-09-13T08:13:00.000Z" lastModifiedTime="2026-09-13T08:13:00.000Z" objectID="{AD861E4A-D898-031B-25E9-10EBF29DCD25}{1}{B0}" alignment="left"><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[Completed task]]></one:T></one:OE><one:OE creationTime="2026-09-13T08:13:00.000Z" lastModifiedTime="2026-09-13T08:13:00.000Z" objectID="{EF2ED991-5964-0515-2042-9727E177E093}{1}{B0}" alignment="left"><one:Tag index="0" completed="false" disabled="false" creationDate="2020-01-02T03:04:05.000Z"/><one:Tag index="1" completed="false" disabled="false" creationDate="2020-01-02T03:04:05.000Z"/><one:T><![CDATA[Important open task]]></one:T></one:OE><one:OE creationTime="2026-09-13T08:13:00.000Z" lastModifiedTime="2026-09-13T08:13:00.000Z" objectID="{C1E4EF5F-DDB5-09B3-355F-A6449BF88678}{1}{B0}" alignment="left"><one:T><![CDATA[Untagged]]></one:T></one:OE></one:OEChildren></one:Outline></one:Page> |
corpus/page-copy/cold/read/page-012.navigation.json created+13| ... | ... | @@ -0,0 +1,13 @@ |
| 1 | { | |
| 2 | "exit": 0, | |
| 3 | "stdout": "", | |
| 4 | "stderr": "", | |
| 5 | "w": 800, | |
| 6 | "h": 600, | |
| 7 | "error": null, | |
| 8 | "win": { | |
| 9 | "title": "Move cell subtree down - Microsoft OneNote", | |
| 10 | "class": "Framework::CFrame", | |
| 11 | "dialog": false | |
| 12 | } | |
| 13 | } | |
| \ No newline at end of file |
corpus/page-copy/cold/read/page-012.png created| Binary files /dev/null and b/corpus/page-copy/cold/read/page-012.png differ |
corpus/page-copy/cold/read/page-012.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="{AA29BE5C-9249-0610-1036-E2735CEC0BB9}{1}{B0}" name="Move cell subtree down" dateTime="2026-09-13T08:12:58.000Z" lastModifiedTime="2026-09-13T08:14:27.000Z" pageLevel="1" lang="en-US"><one:TagDef index="0" type="0" symbol="3" fontColor="automatic" highlightColor="none" name="Preserved task"/><one:QuickStyleDef index="0" name="PageTitle" font="Calibri" fontSize="17.0"/><one:QuickStyleDef index="1" 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 showDate="false" showTime="false" lang="en-US"><one:OE author="Copier" lastModifiedBy="Copier" creationTime="2026-09-13T08:12:58.000Z" lastModifiedTime="2026-09-13T08:12:58.000Z" objectID="{AA29BE5C-9249-0610-1036-E2735CEC0BB9}{15}{B0}" alignment="left" quickStyleIndex="0" style="font-family:Calibri;font-size:17.0pt"><one:T><![CDATA[Move cell subtree down]]></one:T></one:OE></one:Title><one:Outline author="Copier" lastModifiedBy="Copier" lastModifiedTime="2026-09-13T08:12:59.000Z" objectID="{5DFCE2F7-804C-019E-3F4A-DD0FF39FFE62}{1}{B0}"><one:Position x="72.0" y="108.0" z="0"/><one:Size width="428.1300048828125" height="62.23086929321289"/><one:OEChildren><one:OE creationTime="2026-09-13T08:12:58.000Z" lastModifiedTime="2026-09-13T08:12:59.000Z" objectID="{2A47635E-2030-0AED-007C-5D9D0EE60320}{1}{B0}" alignment="left"><one:Table bordersVisible="true" lastModifiedTime="2026-09-13T08:12:59.000Z" objectID="{132A6189-E6A3-06C8-2C3B-1301E8466F92}{1}{B0}"><one:Columns><one:Column index="0" width="240.0" isLocked="true"/><one:Column index="1" width="180.0" isLocked="true"/></one:Columns><one:Row objectID="{FFF81FBB-C1B7-0BED-2BAB-5A466882083D}{1}{B0}" lastModifiedTime="2026-09-13T08:12:59.000Z"><one:Cell lastModifiedTime="2026-09-13T08:12:59.000Z" objectID="{DE630286-2FC5-0B54-347C-FF399A93BA12}{1}{B0}"><one:OEChildren><one:OE creationTime="2026-09-13T08:12:58.000Z" lastModifiedTime="2026-09-13T08:12:59.000Z" objectID="{4B5A9D99-8F4C-0DE8-0E0A-5A618E02264F}{1}{B0}" alignment="left" quickStyleIndex="1"><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 | |
| 3 | style='font-weight:bold'>Target &#129408; é</span> <a | |
| 4 | href="https://example.invalid/tree">Link label</a>]]></one:T><one:OEChildren><one:OE creationTime="2026-09-13T08:12:58.000Z" lastModifiedTime="2026-09-13T08:12:59.000Z" objectID="{27BE0601-EB2D-059C-24C6-205D71642566}{1}{B0}" alignment="left" quickStyleIndex="1"><one:T style="font-family:Calibri;font-size:11.0pt"><![CDATA[<span | |
| 5 | style='font-style:italic'>Child</span>]]></one:T><one:OEChildren><one:OE creationTime="2026-09-13T08:12:58.000Z" lastModifiedTime="2026-09-13T08:12:58.000Z" objectID="{E96A9E1E-A5AB-0668-1244-4836285586EF}{1}{B0}" alignment="left" quickStyleIndex="1"><one:T><![CDATA[Grandchild]]></one:T></one:OE></one:OEChildren></one:OE></one:OEChildren></one:OE><one:OE creationTime="2026-09-13T08:12:58.000Z" lastModifiedTime="2026-09-13T08:12:58.000Z" objectID="{6E58F561-F9E2-085E-1864-3AEDF1A5E9F7}{1}{B0}" alignment="left" quickStyleIndex="1"><one:T><![CDATA[Cell tail]]></one:T></one:OE></one:OEChildren></one:Cell><one:Cell lastModifiedTime="2026-09-13T08:12:58.000Z" objectID="{703BD781-4848-05D8-0381-00C40C756723}{1}{B0}"><one:OEChildren><one:OE creationTime="2026-09-13T08:12:58.000Z" lastModifiedTime="2026-09-13T08:12:58.000Z" objectID="{3A828837-47ED-0922-39C9-7A291414EFE2}{1}{B0}" alignment="left" quickStyleIndex="1"><one:T><![CDATA[Other cell]]></one:T></one:OE></one:OEChildren></one:Cell></one:Row></one:Table></one:OE></one:OEChildren></one:Outline><one:Outline author="Copier" lastModifiedBy="Copier" lastModifiedTime="2026-09-13T08:12:58.000Z" objectID="{68C4CF29-651E-0F55-2987-5FF0DC3E0D05}{1}{B0}"><one:Position x="540.0" y="108.0" z="1"/><one:Size width="99.85796356201171" height="13.42771339416504"/><one:OEChildren><one:OE creationTime="2026-09-13T08:12:58.000Z" lastModifiedTime="2026-09-13T08:12:58.000Z" objectID="{901AFAAD-146E-0CB5-1C0A-135DFC01AF28}{1}{B0}" alignment="left" quickStyleIndex="1"><one:T><![CDATA[Other outline]]></one:T></one:OE></one:OEChildren></one:Outline></one:Page> |
corpus/page-copy/cold/read/page-013.navigation.json created+13| ... | ... | @@ -0,0 +1,13 @@ |
| 1 | { | |
| 2 | "exit": 0, | |
| 3 | "stdout": "", | |
| 4 | "stderr": "", | |
| 5 | "w": 800, | |
| 6 | "h": 600, | |
| 7 | "error": null, | |
| 8 | "win": { | |
| 9 | "title": "Delete cell subtree - Microsoft OneNote", | |
| 10 | "class": "Framework::CFrame", | |
| 11 | "dialog": false | |
| 12 | } | |
| 13 | } | |
| \ No newline at end of file |
corpus/page-copy/cold/read/page-013.png created| Binary files /dev/null and b/corpus/page-copy/cold/read/page-013.png differ |
corpus/page-copy/cold/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="{BA810F75-DBC0-0827-0990-F9FBFC84B7D7}{1}{B0}" name="Delete cell subtree" dateTime="2026-09-13T08:12:56.000Z" lastModifiedTime="2026-09-13T08:14:27.000Z" pageLevel="1" lang="en-US"><one:TagDef index="0" type="0" symbol="3" fontColor="automatic" highlightColor="none" name="Preserved task"/><one:QuickStyleDef index="0" name="PageTitle" font="Calibri" fontSize="17.0"/><one:QuickStyleDef index="1" 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 showDate="false" showTime="false" lang="en-US"><one:OE author="Copier" lastModifiedBy="Copier" creationTime="2026-09-13T08:12:56.000Z" lastModifiedTime="2026-09-13T08:12:56.000Z" objectID="{BA810F75-DBC0-0827-0990-F9FBFC84B7D7}{15}{B0}" alignment="left" quickStyleIndex="0" style="font-family:Calibri;font-size:17.0pt"><one:T><![CDATA[Delete cell subtree]]></one:T></one:OE></one:Title><one:Outline author="Copier" lastModifiedBy="Copier" lastModifiedTime="2026-09-13T08:12:56.000Z" objectID="{EF2F80B0-92D7-0C40-3469-9AB6923AC934}{1}{B0}"><one:Position x="72.0" y="108.0" z="0"/><one:Size width="428.1300048828125" height="62.30315780639648"/><one:OEChildren><one:OE creationTime="2026-09-13T08:12:56.000Z" lastModifiedTime="2026-09-13T08:12:56.000Z" objectID="{A3D5DD07-CAAA-0FC1-3434-2BFCD5EAFB3A}{1}{B0}" alignment="left"><one:Table bordersVisible="true" lastModifiedTime="2026-09-13T08:12:56.000Z" objectID="{1C90E39E-CEB9-072B-1045-5350DE91C9BA}{1}{B0}"><one:Columns><one:Column index="0" width="240.0" isLocked="true"/><one:Column index="1" width="180.0" isLocked="true"/></one:Columns><one:Row objectID="{00FE4CB7-3AD9-0A13-02EC-F45825DA0837}{1}{B0}" lastModifiedTime="2026-09-13T08:12:56.000Z"><one:Cell lastModifiedTime="2026-09-13T08:12:56.000Z" objectID="{C0215DC2-A310-09E1-2C56-611011EEDEDA}{1}{B0}"><one:OEChildren><one:OE creationTime="2026-09-13T08:12:56.000Z" lastModifiedTime="2026-09-13T08:12:56.000Z" objectID="{B168AA68-D0D0-0783-3211-7CBCF62C1878}{1}{B0}" alignment="left" quickStyleIndex="1"><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 | |
| 3 | style='font-weight:bold'>Target &#129408; é</span> <a | |
| 4 | href="https://example.invalid/tree">Link label</a>]]></one:T><one:OEChildren><one:OE creationTime="2026-09-13T08:12:56.000Z" lastModifiedTime="2026-09-13T08:12:56.000Z" objectID="{51E78125-5D88-02B2-1F60-3564BF9AB799}{1}{B0}" alignment="left" quickStyleIndex="1"><one:T style="font-family:Calibri;font-size:11.0pt"><![CDATA[<span | |
| 5 | style='font-style:italic'>Child</span>]]></one:T><one:OEChildren><one:OE creationTime="2026-09-13T08:12:56.000Z" lastModifiedTime="2026-09-13T08:12:56.000Z" objectID="{9EE1315E-F0F0-01F2-236C-CED603CE6C83}{1}{B0}" alignment="left" quickStyleIndex="1"><one:T><![CDATA[Grandchild]]></one:T></one:OE></one:OEChildren></one:OE></one:OEChildren></one:OE><one:OE creationTime="2026-09-13T08:12:56.000Z" lastModifiedTime="2026-09-13T08:12:56.000Z" objectID="{FD8B95A9-B069-065B-24ED-358E77DA9126}{1}{B0}" alignment="left" quickStyleIndex="1"><one:T><![CDATA[Cell tail]]></one:T></one:OE></one:OEChildren></one:Cell><one:Cell lastModifiedTime="2026-09-13T08:12:56.000Z" objectID="{C371CC3D-4164-0E42-20D2-92CDC0E0162E}{1}{B0}"><one:OEChildren><one:OE creationTime="2026-09-13T08:12:56.000Z" lastModifiedTime="2026-09-13T08:12:56.000Z" objectID="{3A7C1016-52CD-0EE0-1D98-5D6464F47C40}{1}{B0}" alignment="left" quickStyleIndex="1"><one:T><![CDATA[Other cell]]></one:T></one:OE><one:OE creationTime="2026-09-13T08:12:56.000Z" lastModifiedTime="2026-09-13T08:12:56.000Z" objectID="{D4CC12A4-5B3C-0061-0FC8-329CFD2237A8}{1}{B0}" alignment="left" style="font-family:Calibri;font-size:11.0pt"><one:Table bordersVisible="true" lastModifiedTime="2026-09-13T08:12:56.000Z" objectID="{2BDFCA04-550A-0B11-3229-C359C02CEC1A}{1}{B0}"><one:Columns><one:Column index="0" width="72.0" isLocked="true"/></one:Columns><one:Row objectID="{933BCC33-B101-006B-1B06-D1EA10BD608E}{1}{B0}" lastModifiedTime="2026-09-13T08:12:56.000Z"><one:Cell lastModifiedTime="2026-09-13T08:12:56.000Z" objectID="{C9AC97DE-B8A6-079A-05EA-1C006AE7F1F6}{1}{B0}"><one:OEChildren><one:OE creationTime="2026-09-13T08:12:56.000Z" lastModifiedTime="2026-09-13T08:12:56.000Z" objectID="{F3B663D9-B871-0F4A-0480-14D1C093E86C}{1}{B0}" alignment="left"><one:T><![CDATA[Inner one]]></one:T></one:OE></one:OEChildren></one:Cell></one:Row><one:Row objectID="{49CDA646-4B5C-05D4-1D4A-377146640436}{1}{B0}" lastModifiedTime="2026-09-13T08:12:56.000Z"><one:Cell lastModifiedTime="2026-09-13T08:12:56.000Z" objectID="{4C20D881-145C-0B85-3B52-D9FC9DA41CF8}{1}{B0}"><one:OEChildren><one:OE creationTime="2026-09-13T08:12:56.000Z" lastModifiedTime="2026-09-13T08:12:56.000Z" objectID="{23ACBCB6-41CC-0F28-29A2-649DCD1F070A}{1}{B0}" alignment="left"><one:T><![CDATA[Inner two]]></one:T></one:OE></one:OEChildren></one:Cell></one:Row></one:Table></one:OE></one:OEChildren></one:Cell></one:Row></one:Table></one:OE></one:OEChildren></one:Outline><one:Outline author="Copier" lastModifiedBy="Copier" lastModifiedTime="2026-09-13T08:12:56.000Z" objectID="{DD272184-6150-017E-0C7B-E0A6C9D33F67}{1}{B0}"><one:Position x="540.0" y="108.0" z="1"/><one:Size width="99.85796356201171" height="13.42771339416504"/><one:OEChildren><one:OE creationTime="2026-09-13T08:12:56.000Z" lastModifiedTime="2026-09-13T08:12:56.000Z" objectID="{E23E61E5-7407-0548-006A-201CB1623B82}{1}{B0}" alignment="left" quickStyleIndex="1"><one:T><![CDATA[Other outline]]></one:T></one:OE></one:OEChildren></one:Outline></one:Page> |
corpus/page-copy/cold/read/page-014.navigation.json created+13| ... | ... | @@ -0,0 +1,13 @@ |
| 1 | { | |
| 2 | "exit": 0, | |
| 3 | "stdout": "", | |
| 4 | "stderr": "", | |
| 5 | "w": 800, | |
| 6 | "h": 600, | |
| 7 | "error": null, | |
| 8 | "win": { | |
| 9 | "title": "Beside the drawing - Microsoft OneNote", | |
| 10 | "class": "Framework::CFrame", | |
| 11 | "dialog": false | |
| 12 | } | |
| 13 | } | |
| \ No newline at end of file |
corpus/page-copy/cold/read/page-014.png created| Binary files /dev/null and b/corpus/page-copy/cold/read/page-014.png differ |
corpus/page-copy/cold/read/page-014.xml created+7| ... | ... | @@ -0,0 +1,7 @@ |
| 1 | <?xml version="1.0"?> | |
| 2 | <one:Page xmlns:one="http://schemas.microsoft.com/office/onenote/2010/onenote" ID="{D28E7576-C55F-0047-2C51-4C855C536D13}{1}{B0}" name="Beside the drawing" dateTime="2026-09-13T08:12:58.000Z" lastModifiedTime="2026-09-13T08:14:27.000Z" pageLevel="1" style="font-family:Calibri;font-size:11.0pt" lang="en-US"><one:QuickStyleDef index="0" name="PageTitle" font="Calibri" fontSize="17.0"/><one:PageSettings RTL="false" color="automatic"><one:PageSize><one:Automatic/></one:PageSize><one:RuleLines visible="false"/></one:PageSettings><one:Title showDate="false" showTime="false" lang="en-US"><one:OE author="Copier" lastModifiedBy="Copier" creationTime="2026-09-13T08:12:58.000Z" lastModifiedTime="2026-09-13T08:12:58.000Z" objectID="{D28E7576-C55F-0047-2C51-4C855C536D13}{15}{B0}" alignment="left" quickStyleIndex="0" style="font-family:Calibri;font-size:17.0pt"><one:T><![CDATA[Beside the drawing]]></one:T></one:OE></one:Title><one:Outline author="Copier" lastModifiedBy="Copier" lastModifiedTime="2026-09-13T08:12:59.000Z" objectID="{110E90F1-B6EC-0EE0-1F13-367858D96194}{1}{B0}"><one:Position x="36.0" y="36.0" z="0"/><one:Size width="152.4244079589843" height="13.4277172088623"/><one:Indents><one:Indent level="0" indent="0.0"/></one:Indents><one:OEChildren><one:OE creationTime="2026-09-13T08:12:59.000Z" lastModifiedTime="2026-09-13T08:12:59.000Z" objectID="{14A2DDB9-EF56-053E-2D5F-B9FF92056636}{1}{B0}" alignment="left"><one:T><![CDATA[Beside the drawing]]></one:T></one:OE></one:OEChildren></one:Outline><one:InkDrawing lastModifiedTime="2026-09-13T08:12:59.000Z" objectID="{A013EA2B-3C74-0FE2-0325-A02BD639D5F9}{1}{B0}"><one:Position x="299.9905395507812" y="119.9905471801758" z="1"/><one:Size width="60.03781127929687" height="60.03779220581055"/><one:Data>AM8CHQSiAaIBAWAqABofi0JwRYR1gL7QRdkE+oeVMvLsF0G4wBa/8yv0et67E4vlXrNInJuhJVq3 | |
| 3 | URK/7HHMzCKxQYkOuxMs7nqhWM9UiuaXxU+PBvi60uGbIsRmbacNslhJmh1OQDQGbBACEQZIEEUj | |
| 4 | RiMJSBBE/wFFI0YjBQgLZU9mZ2hkaRkUMggAgB4CIeLiQTMIAPAQAovF4kFkAxVGAEAKXAWH8gln | |
| 5 | jCj7wnvCe8IAh/B8h4Pke8I7wnvCQAUURgBAAAAJBAUURgAAAAASABEgNO2fBK2iXEeJsDGBngJF | |
| 6 | LQoAESCAd0ywV0PdAQMVRgBACj9AIm9GCC70WAqACQEKTAIPUq7GcA5CJYzgBRRGAIAAAAkEBRRG | |
| 7 | AAAAABIAESDm2ofXdOgLSJUWT/x4VvZtCgARIIB3TLBXQ90BAxVGAEAKP0Aib0YILvRYCoA=</one:Data></one:InkDrawing></one:Page> |
corpus/page-copy/cold/read/page-015.navigation.json created+13| ... | ... | @@ -0,0 +1,13 @@ |
| 1 | { | |
| 2 | "exit": 0, | |
| 3 | "stdout": "", | |
| 4 | "stderr": "", | |
| 5 | "w": 800, | |
| 6 | "h": 600, | |
| 7 | "error": null, | |
| 8 | "win": { | |
| 9 | "title": "A notebook created in Rust. - Microsoft OneNote", | |
| 10 | "class": "Framework::CFrame", | |
| 11 | "dialog": false | |
| 12 | } | |
| 13 | } | |
| \ No newline at end of file |
corpus/page-copy/cold/read/page-015.png created| Binary files /dev/null and b/corpus/page-copy/cold/read/page-015.png differ |
corpus/page-copy/cold/read/page-015.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="{EF547C09-87EA-0A35-039B-F5512549E931}{1}{B0}" name="A notebook created in Rust." dateTime="2026-09-13T08:13:00.000Z" lastModifiedTime="2026-09-13T08:14:27.000Z" pageLevel="1" style="font-family:Calibri;font-size:11.0pt" lang="en-US"><one:QuickStyleDef index="0" name="PageTitle" font="Calibri" fontSize="17.0"/><one:PageSettings RTL="false" color="automatic"><one:PageSize><one:Automatic/></one:PageSize><one:RuleLines visible="false"/></one:PageSettings><one:Title showDate="false" showTime="false" lang="en-US"><one:OE author="Copier" lastModifiedBy="Copier" creationTime="2026-09-13T08:13:00.000Z" lastModifiedTime="2026-09-13T08:13:00.000Z" objectID="{EF547C09-87EA-0A35-039B-F5512549E931}{15}{B0}" alignment="left" quickStyleIndex="0" style="font-family:Calibri;font-size:17.0pt"><one:T><![CDATA[A notebook created in Rust.]]></one:T></one:OE></one:Title><one:Outline author="Copier" lastModifiedBy="Copier" lastModifiedTime="2026-09-13T08:13:01.000Z" objectID="{B7774BCB-9107-00A0-2BFE-95DC3CB2134F}{1}{B0}"><one:Position x="36.0" y="36.0" z="0"/><one:Size width="191.1661224365234" height="13.4277172088623"/><one:Indents><one:Indent level="0" indent="0.0"/></one:Indents><one:OEChildren><one:OE creationTime="2026-09-13T08:13:01.000Z" lastModifiedTime="2026-09-13T08:13:01.000Z" objectID="{C3848036-370C-04C5-0022-5090B87608DD}{1}{B0}" alignment="left"><one:T><![CDATA[A notebook created in Rust.]]></one:T></one:OE></one:OEChildren></one:Outline></one:Page> |
corpus/page-copy/cold/read/page-016.navigation.json created+13| ... | ... | @@ -0,0 +1,13 @@ |
| 1 | { | |
| 2 | "exit": 0, | |
| 3 | "stdout": "", | |
| 4 | "stderr": "", | |
| 5 | "w": 800, | |
| 6 | "h": 600, | |
| 7 | "error": null, | |
| 8 | "win": { | |
| 9 | "title": "Before the table - Microsoft OneNote", | |
| 10 | "class": "Framework::CFrame", | |
| 11 | "dialog": false | |
| 12 | } | |
| 13 | } | |
| \ No newline at end of file |
corpus/page-copy/cold/read/page-016.png created| Binary files /dev/null and b/corpus/page-copy/cold/read/page-016.png differ |
corpus/page-copy/cold/read/page-016.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="{FBBA4589-4114-0DBB-1DDE-9AEBE04435E8}{1}{B0}" name="Before the table" dateTime="2026-09-13T08:12:55.000Z" lastModifiedTime="2026-09-13T08:14:26.000Z" pageLevel="1" style="font-family:Calibri;font-size:11.0pt" lang="en-US"><one:QuickStyleDef index="0" name="PageTitle" font="Calibri" fontSize="17.0"/><one:PageSettings RTL="false" color="automatic"><one:PageSize><one:Automatic/></one:PageSize><one:RuleLines visible="false"/></one:PageSettings><one:Title showDate="false" showTime="false" lang="en-US"><one:OE author="Copier" lastModifiedBy="Copier" creationTime="2026-09-13T08:12:55.000Z" lastModifiedTime="2026-09-13T08:12:55.000Z" objectID="{FBBA4589-4114-0DBB-1DDE-9AEBE04435E8}{15}{B0}" alignment="left" quickStyleIndex="0" style="font-family:Calibri;font-size:17.0pt"><one:T><![CDATA[Before the table]]></one:T></one:OE></one:Title><one:Outline author="Copier" lastModifiedBy="Copier" lastModifiedTime="2026-09-13T08:12:55.000Z" objectID="{B66EC4E0-90E0-065D-16BD-8AE6D17D38E2}{1}{B0}"><one:Position x="36.0" y="36.0" z="0"/><one:Size width="395.1299438476562" height="67.21086883544922"/><one:Indents><one:Indent level="0" indent="0.0"/></one:Indents><one:OEChildren><one:OE creationTime="2026-09-13T08:12:55.000Z" lastModifiedTime="2026-09-13T08:12:55.000Z" objectID="{D00B3AB9-E98D-02AC-00A5-64F7F0B73D24}{1}{B0}" alignment="left"><one:T><![CDATA[Before the table]]></one:T></one:OE><one:OE creationTime="2026-09-13T08:12:55.000Z" lastModifiedTime="2026-09-13T08:12:55.000Z" objectID="{A910B5E4-106E-091B-042B-85260A415D85}{1}{B0}" alignment="left"><one:Table bordersVisible="true" lastModifiedTime="2026-09-13T08:12:55.000Z" objectID="{E2111011-156E-0E62-3045-C3CA9B0171B1}{1}{B0}"><one:Columns><one:Column index="0" width="144.0" isLocked="true"/><one:Column index="1" width="216.0" isLocked="true"/></one:Columns><one:Row objectID="{EFFCB8A1-87E0-0D1C-2007-873484353285}{1}{B0}" lastModifiedTime="2026-09-13T08:12:55.000Z"><one:Cell lastModifiedTime="2026-09-13T08:12:55.000Z" objectID="{58537E0F-3889-000A-30F5-5B63A4AEDDF4}{1}{B0}"><one:OEChildren><one:OE creationTime="2026-09-13T08:12:55.000Z" lastModifiedTime="2026-09-13T08:12:55.000Z" objectID="{766E8FDE-7B1E-0BE1-2EA2-786315A5EE3A}{1}{B0}" alignment="left"><one:T><![CDATA[Name]]></one:T></one:OE></one:OEChildren></one:Cell><one:Cell lastModifiedTime="2026-09-13T08:12:55.000Z" objectID="{33808FC6-C25F-040B-157F-8170CE036733}{1}{B0}"><one:OEChildren><one:OE creationTime="2026-09-13T08:12:55.000Z" lastModifiedTime="2026-09-13T08:12:55.000Z" objectID="{90D3178B-5FBE-03CD-3CC8-4D2F6E8B7FD3}{1}{B0}" alignment="left"><one:T><![CDATA[Value]]></one:T></one:OE></one:OEChildren></one:Cell></one:Row><one:Row objectID="{EA57AB8A-1061-0815-135C-39D97AF028C6}{1}{B0}" lastModifiedTime="2026-09-13T08:12:55.000Z"><one:Cell lastModifiedTime="2026-09-13T08:12:55.000Z" objectID="{92B2BEB0-1EE8-0D4A-1D27-79EC8DB2F9A2}{1}{B0}"><one:OEChildren><one:OE creationTime="2026-09-13T08:12:55.000Z" lastModifiedTime="2026-09-13T08:12:55.000Z" objectID="{DCEBCF8B-F7DA-0C20-0F76-44AC9B43F901}{1}{B0}" alignment="left"><one:T><![CDATA[Rust &#129408;]]></one:T></one:OE></one:OEChildren></one:Cell><one:Cell lastModifiedTime="2026-09-13T08:12:55.000Z" objectID="{71E65FA6-5919-0FAD-16C0-ADD201204FEE}{1}{B0}"><one:OEChildren><one:OE creationTime="2026-09-13T08:12:55.000Z" lastModifiedTime="2026-09-13T08:12:55.000Z" objectID="{A457D70F-1E86-09AC-0205-D8DFEA8EEC54}{1}{B0}" alignment="left"><one:T><![CDATA[Written natively]]></one:T></one:OE></one:OEChildren></one:Cell></one:Row></one:Table></one:OE><one:OE creationTime="2026-09-13T08:12:55.000Z" lastModifiedTime="2026-09-13T08:12:55.000Z" objectID="{534343F8-0718-0974-08DF-524AD8D8860E}{1}{B0}" alignment="left"><one:T><![CDATA[After the table]]></one:T></one:OE></one:OEChildren></one:Outline></one:Page> |
corpus/page-copy/cold/read/payloads.json+2-2| ... | ... | @@ -2,9 +2,9 @@ |
| 2 | 2 | { |
| 3 | 3 | "sha256": "b20a14e044e33eac39b4665e7d79813b8a3672dbbd27ed9d2e4ac866c13ec4b6", |
| 4 | 4 | "name": "notes 🦀.txt", |
| 5 | "object": "{03AD9394-425B-0B9C-0D27-CA384DFFCEBF}{1}{B0}", | |
| 5 | "object": "{9E89195D-B7EC-0AC4-34FD-F47D633F0533}{1}{B0}", | |
| 6 | 6 | "kind": "InsertedFile", |
| 7 | "page": "{C12C0ECF-DDF8-0A21-11BE-3074429542E0}{1}{B0}", | |
| 7 | "page": "{62E12C49-D5FE-0850-17D5-B4DC95B736E9}{1}{B0}", | |
| 8 | 8 | "bytes": 28 |
| 9 | 9 | } |
| 10 | 10 | ] |
| \ No newline at end of file |
corpus/page-copy/cold/run.json+1-1| ... | ... | @@ -1,6 +1,6 @@ |
| 1 | 1 | { |
| 2 | 2 | "notebook": "/private/tmp/m4/copy", |
| 3 | "expected_pages": 9, | |
| 3 | "expected_pages": 17, | |
| 4 | 4 | "author": null, |
| 5 | 5 | "author_timeout_seconds": 600, |
| 6 | 6 | "inspect": false, |
corpus/page-copy/cold/source.json+8-8| ... | ... | @@ -2,19 +2,19 @@ |
| 2 | 2 | { |
| 3 | 3 | "path": "Open Notebook.onetoc2", |
| 4 | 4 | "bytes": 1604, |
| 5 | "sha256": "bf856a7700054971543fb890257cba327dfd35ef6e5438a41483490c4e06407b", | |
| 6 | "mtime_ns": 1789284797191547350 | |
| 5 | "sha256": "acb0747c250f7bebed1e90b18d5dbbf8c32731f9287571b1e732681921fd323a", | |
| 6 | "mtime_ns": 1789287183577857848 | |
| 7 | 7 | }, |
| 8 | 8 | { |
| 9 | 9 | "path": "copies.one", |
| 10 | "bytes": 91008, | |
| 11 | "sha256": "8f6c9b66379c4bf6730e281d8363737d88fbe1c521a62fd4d054f735b0505cc7", | |
| 12 | "mtime_ns": 1789284797187906252 | |
| 10 | "bytes": 185400, | |
| 11 | "sha256": "dcd7c226d86477adc1ad2f8da8a408ffa2b993b372517ab8d464e5746a971aac", | |
| 12 | "mtime_ns": 1789287183575141938 | |
| 13 | 13 | }, |
| 14 | 14 | { |
| 15 | 15 | "path": "expected-count.txt", |
| 16 | "bytes": 1, | |
| 17 | "sha256": "19581e27de7ced00ff1ce50b2047e7a567c76b1cbaebabe5ef03f7c3017bb5b7", | |
| 18 | "mtime_ns": 1789284797191633183 | |
| 16 | "bytes": 2, | |
| 17 | "sha256": "4523540f1504cd17100c4835e85b7eefd49911580f8efff0599a8f283be6b9e3", | |
| 18 | "mtime_ns": 1789287183577930514 | |
| 19 | 19 | } |
| 20 | 20 | ] |
crates/notebook/README.md+5-2| ... | ... | @@ -334,8 +334,11 @@ metadata; a deleted section moves into `OneNote_RecycleBin`, a group with its |
| 334 | 334 | own TOC. Every created, renamed or moved file is placed with |
| 335 | 335 | `onestore::place_file`, which sets the header's ancestor to the parent TOC's |
| 336 | 336 | identity and the name CRC OneNote checks on open; a file without them is |
| 337 | re-identified and listed anew. These operate on the mounted directory; | |
| 338 | the SMB transport has no create, rename or delete. | |
| 337 | re-identified and listed anew. They run over `Storage`: a mounted directory | |
| 338 | (`Notebook::open`) or an SMB share (`Notebook::open_smb` with a | |
| 339 | `smb::Client`, which gained create, directory creation, rename, delete and | |
| 340 | header placement under native writer coordination); `tools/test_smb_structure.py | |
| 341 | VM OUTPUT` drives them against a disposable Samba lab VM. | |
| 339 | 342 | |
| 340 | 343 | `Notebook::find_page(url)` resolves a stored internal link to a section path |
| 341 | 344 | and page space by identity: the linked section first, then every readable |
crates/notebook/src/session.rs+303-114| ... | ... | @@ -66,9 +66,195 @@ fn entries(folder: &discover::Folder) -> Entries { |
| 66 | 66 | out |
| 67 | 67 | } |
| 68 | 68 | |
| 69 | /// A notebook directory and the cache directory holding its section replicas. | |
| 69 | /// Where a notebook's files live: a mounted directory or an SMB share. Paths are catalog | |
| 70 | /// paths, `/`-separated and relative to the notebook root. | |
| 71 | pub trait Storage: Send + Sync { | |
| 72 | fn discover(&self, limits: discover::Limits) -> Result<discover::Folder>; | |
| 73 | fn exists(&self, path: &str) -> bool; | |
| 74 | fn read(&self, path: &str) -> Result<Vec<u8>>; | |
| 75 | /// Creates a file holding `bytes`; an existing file is an error. | |
| 76 | fn create(&self, path: &str, bytes: &[u8]) -> Result<()>; | |
| 77 | fn create_directory(&self, path: &str) -> Result<()>; | |
| 78 | /// Renames or moves a file or directory; an existing target is an error. | |
| 79 | fn rename(&self, from: &str, to: &str) -> Result<()>; | |
| 80 | /// Names a section or TOC file for its notebook, as `onestore::place`. | |
| 81 | fn place(&self, path: &str, ancestor: [u8; 16], name: &str) -> Result<()>; | |
| 82 | fn commit(&self, path: &str, edit: &PreparedEdit<'_>) -> Result<()>; | |
| 83 | fn set_property( | |
| 84 | &self, | |
| 85 | path: &str, | |
| 86 | source: &[u8], | |
| 87 | space: ExGuid, | |
| 88 | object: ExGuid, | |
| 89 | property: u32, | |
| 90 | value: &[u8], | |
| 91 | ) -> Result<()>; | |
| 92 | } | |
| 93 | ||
| 94 | /// A mounted notebook directory. | |
| 95 | struct Directory(PathBuf); | |
| 96 | ||
| 97 | impl Directory { | |
| 98 | fn path(&self, relative: &str) -> PathBuf { | |
| 99 | if relative.is_empty() { | |
| 100 | self.0.clone() | |
| 101 | } else { | |
| 102 | self.0.join(relative) | |
| 103 | } | |
| 104 | } | |
| 105 | } | |
| 106 | ||
| 107 | impl Storage for Directory { | |
| 108 | fn discover(&self, limits: discover::Limits) -> Result<discover::Folder> { | |
| 109 | Ok(discover::discover( | |
| 110 | &mut discover::Local::open(&self.0)?, | |
| 111 | limits, | |
| 112 | )?) | |
| 113 | } | |
| 114 | ||
| 115 | fn exists(&self, path: &str) -> bool { | |
| 116 | self.path(path).exists() | |
| 117 | } | |
| 118 | ||
| 119 | fn read(&self, path: &str) -> Result<Vec<u8>> { | |
| 120 | Ok(onestore::read_file(self.path(path))?) | |
| 121 | } | |
| 122 | ||
| 123 | fn create(&self, path: &str, bytes: &[u8]) -> Result<()> { | |
| 124 | std::fs::File::create_new(self.path(path))?.write_all(bytes)?; | |
| 125 | Ok(()) | |
| 126 | } | |
| 127 | ||
| 128 | fn create_directory(&self, path: &str) -> Result<()> { | |
| 129 | Ok(std::fs::create_dir(self.path(path))?) | |
| 130 | } | |
| 131 | ||
| 132 | fn rename(&self, from: &str, to: &str) -> Result<()> { | |
| 133 | Ok(std::fs::rename(self.path(from), self.path(to))?) | |
| 134 | } | |
| 135 | ||
| 136 | fn place(&self, path: &str, ancestor: [u8; 16], name: &str) -> Result<()> { | |
| 137 | Ok(onestore::place_file(self.path(path), ancestor, name)?) | |
| 138 | } | |
| 139 | ||
| 140 | fn commit(&self, path: &str, edit: &PreparedEdit<'_>) -> Result<()> { | |
| 141 | Ok(edit.commit_file(self.path(path))?) | |
| 142 | } | |
| 143 | ||
| 144 | fn set_property( | |
| 145 | &self, | |
| 146 | path: &str, | |
| 147 | source: &[u8], | |
| 148 | space: ExGuid, | |
| 149 | object: ExGuid, | |
| 150 | property: u32, | |
| 151 | value: &[u8], | |
| 152 | ) -> Result<()> { | |
| 153 | Ok(onestore::commit_file_property( | |
| 154 | self.path(path), | |
| 155 | source, | |
| 156 | space, | |
| 157 | object, | |
| 158 | property, | |
| 159 | value, | |
| 160 | )?) | |
| 161 | } | |
| 162 | } | |
| 163 | ||
| 164 | /// A notebook directory on an SMB share, reached through the native-compatible client. | |
| 165 | #[cfg(feature = "smb")] | |
| 166 | pub struct Share { | |
| 167 | client: Arc<crate::smb::Client>, | |
| 168 | root: String, | |
| 169 | } | |
| 170 | ||
| 171 | #[cfg(feature = "smb")] | |
| 172 | impl Share { | |
| 173 | fn path(&self, relative: &str) -> String { | |
| 174 | match (self.root.is_empty(), relative.is_empty()) { | |
| 175 | (_, true) => self.root.clone(), | |
| 176 | (true, false) => relative.to_owned(), | |
| 177 | (false, false) => format!("{}/{relative}", self.root), | |
| 178 | } | |
| 179 | } | |
| 180 | } | |
| 181 | ||
| 182 | #[cfg(feature = "smb")] | |
| 183 | impl Storage for Share { | |
| 184 | fn discover(&self, limits: discover::Limits) -> Result<discover::Folder> { | |
| 185 | Ok(discover::discover( | |
| 186 | &mut discover::Smb::new(&self.client, &self.root)?, | |
| 187 | limits, | |
| 188 | )?) | |
| 189 | } | |
| 190 | ||
| 191 | fn exists(&self, path: &str) -> bool { | |
| 192 | let (folder, name) = split(path); | |
| 193 | self.client | |
| 194 | .read_dir(&self.path(folder), 100_000) | |
| 195 | .is_ok_and(|entries| entries.iter().any(|entry| entry.name == name)) | |
| 196 | } | |
| 197 | ||
| 198 | fn read(&self, path: &str) -> Result<Vec<u8>> { | |
| 199 | Ok(self | |
| 200 | .client | |
| 201 | .read_storage(&self.path(path), 256 * 1024 * 1024)?) | |
| 202 | } | |
| 203 | ||
| 204 | fn create(&self, path: &str, bytes: &[u8]) -> Result<()> { | |
| 205 | Ok(self.client.create(&self.path(path), bytes)?) | |
| 206 | } | |
| 207 | ||
| 208 | fn create_directory(&self, path: &str) -> Result<()> { | |
| 209 | Ok(self.client.create_directory(&self.path(path))?) | |
| 210 | } | |
| 211 | ||
| 212 | fn rename(&self, from: &str, to: &str) -> Result<()> { | |
| 213 | Ok(self.client.rename(&self.path(from), &self.path(to))?) | |
| 214 | } | |
| 215 | ||
| 216 | fn place(&self, path: &str, ancestor: [u8; 16], name: &str) -> Result<()> { | |
| 217 | Ok(self.client.place(&self.path(path), ancestor, name)?) | |
| 218 | } | |
| 219 | ||
| 220 | fn commit(&self, path: &str, edit: &PreparedEdit<'_>) -> Result<()> { | |
| 221 | Ok(self.client.commit_prepared(&self.path(path), edit)?) | |
| 222 | } | |
| 223 | ||
| 224 | fn set_property( | |
| 225 | &self, | |
| 226 | path: &str, | |
| 227 | source: &[u8], | |
| 228 | space: ExGuid, | |
| 229 | object: ExGuid, | |
| 230 | property: u32, | |
| 231 | value: &[u8], | |
| 232 | ) -> Result<()> { | |
| 233 | Ok(self.client.commit_property_bytes( | |
| 234 | &self.path(path), | |
| 235 | source, | |
| 236 | space, | |
| 237 | object, | |
| 238 | property, | |
| 239 | value, | |
| 240 | )?) | |
| 241 | } | |
| 242 | } | |
| 243 | ||
| 244 | const LIMITS: discover::Limits = discover::Limits { | |
| 245 | entries: 100_000, | |
| 246 | bytes_per_file: 256 * 1024 * 1024, | |
| 247 | depth: 64, | |
| 248 | }; | |
| 249 | ||
| 250 | const TOC: &str = "Open Notebook.onetoc2"; | |
| 251 | const RECYCLE_BIN: &str = "OneNote_RecycleBin"; | |
| 252 | ||
| 253 | /// A notebook's files and the cache directory holding its section replicas. | |
| 70 | 254 | pub struct Notebook { |
| 71 | root: PathBuf, | |
| 255 | storage: Box<dyn Storage>, | |
| 256 | /// The mounted directory, when sections open through local replicas. | |
| 257 | root: Option<PathBuf>, | |
| 72 | 258 | cache: PathBuf, |
| 73 | 259 | catalog: discover::Folder, |
| 74 | 260 | } |
| ... | ... | @@ -76,17 +262,31 @@ pub struct Notebook { |
| 76 | 262 | impl Notebook { |
| 77 | 263 | pub fn open(root: impl AsRef<Path>, cache: impl AsRef<Path>) -> Result<Self> { |
| 78 | 264 | let root = root.as_ref().canonicalize()?; |
| 265 | Self::with(Box::new(Directory(root.clone())), Some(root), cache) | |
| 266 | } | |
| 267 | ||
| 268 | /// Opens the notebook at `root` on the share `client` is connected to. Sections open | |
| 269 | /// through `Section::resume_smb` with the catalog's paths. | |
| 270 | #[cfg(feature = "smb")] | |
| 271 | pub fn open_smb( | |
| 272 | client: Arc<crate::smb::Client>, | |
| 273 | root: &str, | |
| 274 | cache: impl AsRef<Path>, | |
| 275 | ) -> Result<Self> { | |
| 276 | let root = root.replace('\\', "/"); | |
| 277 | Self::with(Box::new(Share { client, root }), None, cache) | |
| 278 | } | |
| 279 | ||
| 280 | fn with( | |
| 281 | storage: Box<dyn Storage>, | |
| 282 | root: Option<PathBuf>, | |
| 283 | cache: impl AsRef<Path>, | |
| 284 | ) -> Result<Self> { | |
| 79 | 285 | let cache = cache.as_ref().to_path_buf(); |
| 80 | 286 | std::fs::create_dir_all(&cache)?; |
| 81 | let catalog = discover::discover( | |
| 82 | &mut discover::Local::open(&root)?, | |
| 83 | discover::Limits { | |
| 84 | entries: 100_000, | |
| 85 | bytes_per_file: 256 * 1024 * 1024, | |
| 86 | depth: 64, | |
| 87 | }, | |
| 88 | )?; | |
| 287 | let catalog = storage.discover(LIMITS)?; | |
| 89 | 288 | Ok(Self { |
| 289 | storage, | |
| 90 | 290 | root, |
| 91 | 291 | cache, |
| 92 | 292 | catalog, |
| ... | ... | @@ -97,18 +297,11 @@ impl Notebook { |
| 97 | 297 | &self.catalog |
| 98 | 298 | } |
| 99 | 299 | |
| 100 | /// Rereads the notebook directory and reports what changed since the last catalog, | |
| 101 | /// keyed by file identity so a renamed or moved section stays the same section. A | |
| 102 | /// failed read keeps the previous catalog: an unreachable notebook is not an empty one. | |
| 300 | /// Rereads the notebook and reports what changed since the last catalog, keyed by | |
| 301 | /// file identity so a renamed or moved section stays the same section. A failed read | |
| 302 | /// keeps the previous catalog: an unreachable notebook is not an empty one. | |
| 103 | 303 | pub fn refresh(&mut self) -> Result<Vec<Change>> { |
| 104 | let catalog = discover::discover( | |
| 105 | &mut discover::Local::open(&self.root)?, | |
| 106 | discover::Limits { | |
| 107 | entries: 100_000, | |
| 108 | bytes_per_file: 256 * 1024 * 1024, | |
| 109 | depth: 64, | |
| 110 | }, | |
| 111 | )?; | |
| 304 | let catalog = self.storage.discover(LIMITS)?; | |
| 112 | 305 | let (before, before_orders) = entries(&self.catalog); |
| 113 | 306 | let (after, after_orders) = entries(&catalog); |
| 114 | 307 | let mut changes = Vec::new(); |
| ... | ... | @@ -158,28 +351,27 @@ impl Notebook { |
| 158 | 351 | Err(io::Error::from(io::ErrorKind::NotFound).into()) |
| 159 | 352 | } |
| 160 | 353 | |
| 161 | fn directory(&self, path: &str) -> Result<PathBuf> { | |
| 162 | let directory = if path.is_empty() { | |
| 163 | self.root.clone() | |
| 164 | } else { | |
| 165 | self.root.join(path).canonicalize()? | |
| 166 | }; | |
| 167 | if !directory.starts_with(&self.root) || !directory.is_dir() { | |
| 168 | return Err(io::Error::from(io::ErrorKind::PermissionDenied).into()); | |
| 354 | /// A catalog section's path, refusing paths the catalog does not list. | |
| 355 | fn section_path(&self, path: &str) -> Result<&discover::Section> { | |
| 356 | let mut folders = vec![&self.catalog]; | |
| 357 | while let Some(folder) = folders.pop() { | |
| 358 | if let Some(section) = folder.sections.iter().find(|section| section.path == path) { | |
| 359 | return Ok(section); | |
| 360 | } | |
| 361 | folders.extend(&folder.groups); | |
| 169 | 362 | } |
| 170 | Ok(directory) | |
| 363 | Err(io::Error::from(io::ErrorKind::NotFound).into()) | |
| 171 | 364 | } |
| 172 | 365 | |
| 173 | 366 | /// A folder's TOC path and file identity, creating the TOC when the folder has none |
| 174 | 367 | /// (OneNote names it `Open Notebook.onetoc2`). |
| 175 | fn toc(&self, folder: &str) -> Result<(PathBuf, [u8; 16])> { | |
| 176 | let directory = self.directory(folder)?; | |
| 368 | fn toc(&self, folder: &str) -> Result<(String, [u8; 16])> { | |
| 177 | 369 | match &self.folder(folder)?.toc { |
| 178 | Some(toc) => Ok((directory.join(&toc.filename), toc.file_id)), | |
| 370 | Some(toc) => Ok((catalog_path(folder, &toc.filename), toc.file_id)), | |
| 179 | 371 | None => { |
| 180 | let path = directory.join("Open Notebook.onetoc2"); | |
| 181 | let bytes = onestore::create_table_of_contents("Open Notebook.onetoc2", &[])?; | |
| 182 | std::fs::File::create_new(&path)?.write_all(&bytes)?; | |
| 372 | let path = catalog_path(folder, TOC); | |
| 373 | let bytes = onestore::create_table_of_contents(TOC, &[])?; | |
| 374 | self.storage.create(&path, &bytes)?; | |
| 183 | 375 | Ok((path, onestore::Store::parse(&bytes)?.header.file_id)) |
| 184 | 376 | } |
| 185 | 377 | } |
| ... | ... | @@ -187,23 +379,21 @@ impl Notebook { |
| 187 | 379 | |
| 188 | 380 | fn edit_toc(&self, folder: &str, edits: &[onestore::TocEdit]) -> Result<()> { |
| 189 | 381 | let (toc, _) = self.toc(folder)?; |
| 190 | let source = onestore::read_file(&toc)?; | |
| 191 | PreparedEdit::table_of_contents(&source, edits)? | |
| 192 | .commit_file(&toc) | |
| 193 | .map_err(|error| error.error)?; | |
| 194 | Ok(()) | |
| 382 | let source = self.storage.read(&toc)?; | |
| 383 | self.storage | |
| 384 | .commit(&toc, &PreparedEdit::table_of_contents(&source, edits)?) | |
| 195 | 385 | } |
| 196 | 386 | |
| 197 | 387 | /// Creates `name.one` in `folder` with one empty page and lists it last in the folder's |
| 198 | 388 | /// TOC, as OneNote creates a section. Returns the new catalog path. |
| 199 | 389 | pub fn create_section(&mut self, folder: &str, name: &str, author: &str) -> Result<String> { |
| 200 | 390 | let filename = format!("{name}.one"); |
| 201 | let directory = self.directory(folder)?; | |
| 391 | self.folder(folder)?; | |
| 202 | 392 | let (_, ancestor) = self.toc(folder)?; |
| 203 | 393 | let bytes = onestore::create_section(&filename, "", author)?; |
| 204 | let path = directory.join(&filename); | |
| 205 | std::fs::File::create_new(&path)?.write_all(&bytes)?; | |
| 206 | onestore::place_file(&path, ancestor, &filename)?; | |
| 394 | let path = catalog_path(folder, &filename); | |
| 395 | self.storage.create(&path, &bytes)?; | |
| 396 | self.storage.place(&path, ancestor, &filename)?; | |
| 207 | 397 | let identity = onestore::Store::parse(&bytes)?.header.file_id; |
| 208 | 398 | self.edit_toc( |
| 209 | 399 | folder, |
| ... | ... | @@ -214,22 +404,22 @@ impl Notebook { |
| 214 | 404 | }], |
| 215 | 405 | )?; |
| 216 | 406 | self.refresh()?; |
| 217 | Ok(catalog_path(folder, &filename)) | |
| 407 | Ok(path) | |
| 218 | 408 | } |
| 219 | 409 | |
| 220 | 410 | /// Creates a section group: a folder with its own TOC, listed last in the parent's TOC. |
| 221 | 411 | pub fn create_group(&mut self, folder: &str, name: &str) -> Result<String> { |
| 222 | let directory = self.directory(folder)?; | |
| 412 | self.folder(folder)?; | |
| 223 | 413 | if !component(name) { |
| 224 | 414 | return Err(io::Error::from(io::ErrorKind::InvalidInput).into()); |
| 225 | 415 | } |
| 226 | let group = directory.join(name); | |
| 227 | 416 | let (_, ancestor) = self.toc(folder)?; |
| 228 | std::fs::create_dir(&group)?; | |
| 229 | let bytes = onestore::create_table_of_contents("Open Notebook.onetoc2", &[])?; | |
| 230 | let path = group.join("Open Notebook.onetoc2"); | |
| 231 | std::fs::File::create_new(&path)?.write_all(&bytes)?; | |
| 232 | onestore::place_file(&path, ancestor, name)?; | |
| 417 | let group = catalog_path(folder, name); | |
| 418 | self.storage.create_directory(&group)?; | |
| 419 | let bytes = onestore::create_table_of_contents(TOC, &[])?; | |
| 420 | let path = catalog_path(&group, TOC); | |
| 421 | self.storage.create(&path, &bytes)?; | |
| 422 | self.storage.place(&path, ancestor, name)?; | |
| 233 | 423 | let identity = onestore::Store::parse(&bytes)?.header.file_id; |
| 234 | 424 | self.edit_toc( |
| 235 | 425 | folder, |
| ... | ... | @@ -240,48 +430,46 @@ impl Notebook { |
| 240 | 430 | }], |
| 241 | 431 | )?; |
| 242 | 432 | self.refresh()?; |
| 243 | Ok(catalog_path(folder, name)) | |
| 433 | Ok(group) | |
| 244 | 434 | } |
| 245 | 435 | |
| 246 | /// Renames a section or section group: the file or folder on disk and its TOC entry. | |
| 436 | /// Renames a section or section group: the file or folder and its TOC entry. | |
| 247 | 437 | pub fn rename(&mut self, path: &str, name: &str) -> Result<String> { |
| 248 | 438 | let (folder, entry) = split(path); |
| 249 | let directory = self.directory(folder)?; | |
| 250 | 439 | let (filename, identity) = self.entry(folder, entry)?; |
| 251 | 440 | let target = if filename.to_ascii_lowercase().ends_with(".one") { |
| 252 | 441 | format!("{name}.one") |
| 253 | 442 | } else { |
| 254 | 443 | name.to_owned() |
| 255 | 444 | }; |
| 256 | if !component(&target) || directory.join(&target).exists() { | |
| 445 | let renamed = catalog_path(folder, &target); | |
| 446 | if !component(&target) || self.storage.exists(&renamed) { | |
| 257 | 447 | return Err(io::Error::from(io::ErrorKind::AlreadyExists).into()); |
| 258 | 448 | } |
| 259 | std::fs::rename(directory.join(&filename), directory.join(&target))?; | |
| 449 | self.storage | |
| 450 | .rename(&catalog_path(folder, &filename), &renamed)?; | |
| 260 | 451 | let (_, ancestor) = self.toc(folder)?; |
| 261 | 452 | let placed = if target.ends_with(".one") { |
| 262 | directory.join(&target) | |
| 453 | renamed.clone() | |
| 263 | 454 | } else { |
| 264 | directory.join(&target).join("Open Notebook.onetoc2") | |
| 455 | catalog_path(&renamed, TOC) | |
| 265 | 456 | }; |
| 266 | onestore::place_file(placed, ancestor, &target)?; | |
| 457 | self.storage.place(&placed, ancestor, &target)?; | |
| 267 | 458 | self.edit_toc( |
| 268 | 459 | folder, |
| 269 | 460 | &[onestore::TocEdit::Rename { |
| 270 | 461 | identity, |
| 271 | filename: target.clone(), | |
| 462 | filename: target, | |
| 272 | 463 | }], |
| 273 | 464 | )?; |
| 274 | 465 | self.refresh()?; |
| 275 | Ok(catalog_path(folder, &target)) | |
| 466 | Ok(renamed) | |
| 276 | 467 | } |
| 277 | 468 | |
| 278 | 469 | /// Sets a section's colour (COLORREF) in its own metadata, where OneNote keeps it. |
| 279 | 470 | pub fn set_section_color(&mut self, path: &str, color: Option<u32>) -> Result<()> { |
| 280 | let file = self.root.join(path).canonicalize()?; | |
| 281 | if !file.starts_with(&self.root) { | |
| 282 | return Err(io::Error::from(io::ErrorKind::PermissionDenied).into()); | |
| 283 | } | |
| 284 | let source = onestore::read_file(&file)?; | |
| 471 | let path = self.section_path(path)?.path.clone(); | |
| 472 | let source = self.storage.read(&path)?; | |
| 285 | 473 | let store = onestore::Store::parse(&source)?; |
| 286 | 474 | let index = onestore::RevisionIndex::parse(&store)?; |
| 287 | 475 | let document = Document::parse(&index)?; |
| ... | ... | @@ -290,15 +478,14 @@ impl Notebook { |
| 290 | 478 | .roots |
| 291 | 479 | .get(&2) |
| 292 | 480 | .ok_or_else(|| io::Error::from(io::ErrorKind::InvalidData))?; |
| 293 | onestore::commit_file_property( | |
| 294 | &file, | |
| 481 | self.storage.set_property( | |
| 482 | &path, | |
| 295 | 483 | &source, |
| 296 | 484 | document.root, |
| 297 | 485 | metadata, |
| 298 | 486 | 0x14001cbe, |
| 299 | 487 | &color.unwrap_or(0xffff_ffff).to_le_bytes(), |
| 300 | ) | |
| 301 | .map_err(|error| error.error)?; | |
| 488 | )?; | |
| 302 | 489 | self.refresh()?; |
| 303 | 490 | Ok(()) |
| 304 | 491 | } |
| ... | ... | @@ -322,23 +509,23 @@ impl Notebook { |
| 322 | 509 | /// the root TOC lists), and its own folder's TOC entry goes. |
| 323 | 510 | pub fn delete(&mut self, path: &str) -> Result<()> { |
| 324 | 511 | let (folder, entry) = split(path); |
| 325 | let directory = self.directory(folder)?; | |
| 326 | 512 | let (filename, identity) = self.entry(folder, entry)?; |
| 327 | 513 | if !filename.to_ascii_lowercase().ends_with(".one") { |
| 328 | 514 | return Err(io::Error::from(io::ErrorKind::InvalidInput).into()); |
| 329 | 515 | } |
| 330 | let bin = self.root.join("OneNote_RecycleBin"); | |
| 331 | let bin_toc = bin.join("Open Notebook.onetoc2"); | |
| 332 | if !bin_toc.exists() { | |
| 333 | std::fs::create_dir_all(&bin)?; | |
| 334 | let bytes = onestore::create_table_of_contents("Open Notebook.onetoc2", &[])?; | |
| 335 | std::fs::File::create_new(&bin_toc)?.write_all(&bytes)?; | |
| 336 | onestore::place_file(&bin_toc, self.toc("")?.1, "OneNote_RecycleBin")?; | |
| 516 | let bin_toc = catalog_path(RECYCLE_BIN, TOC); | |
| 517 | if !self.storage.exists(&bin_toc) { | |
| 518 | if !self.storage.exists(RECYCLE_BIN) { | |
| 519 | self.storage.create_directory(RECYCLE_BIN)?; | |
| 520 | } | |
| 521 | let bytes = onestore::create_table_of_contents(TOC, &[])?; | |
| 522 | self.storage.create(&bin_toc, &bytes)?; | |
| 523 | self.storage.place(&bin_toc, self.toc("")?.1, RECYCLE_BIN)?; | |
| 337 | 524 | let bin_identity = onestore::Store::parse(&bytes)?.header.file_id; |
| 338 | 525 | self.edit_toc( |
| 339 | 526 | "", |
| 340 | 527 | &[onestore::TocEdit::Add { |
| 341 | filename: "OneNote_RecycleBin".into(), | |
| 528 | filename: RECYCLE_BIN.into(), | |
| 342 | 529 | identity: bin_identity, |
| 343 | 530 | group: true, |
| 344 | 531 | }], |
| ... | ... | @@ -346,28 +533,31 @@ impl Notebook { |
| 346 | 533 | } |
| 347 | 534 | let mut target = filename.clone(); |
| 348 | 535 | let mut attempt = 1; |
| 349 | while bin.join(&target).exists() { | |
| 536 | while self.storage.exists(&catalog_path(RECYCLE_BIN, &target)) { | |
| 350 | 537 | attempt += 1; |
| 351 | 538 | let (stem, extension) = filename.rsplit_once('.').unwrap_or((&filename, "")); |
| 352 | 539 | target = format!("{stem} ({attempt}).{extension}"); |
| 353 | 540 | } |
| 354 | std::fs::rename(directory.join(&filename), bin.join(&target))?; | |
| 355 | let source = onestore::read_file(&bin_toc)?; | |
| 356 | onestore::place_file( | |
| 357 | bin.join(&target), | |
| 541 | let binned = catalog_path(RECYCLE_BIN, &target); | |
| 542 | self.storage | |
| 543 | .rename(&catalog_path(folder, &filename), &binned)?; | |
| 544 | let source = self.storage.read(&bin_toc)?; | |
| 545 | self.storage.place( | |
| 546 | &binned, | |
| 358 | 547 | onestore::Store::parse(&source)?.header.file_id, |
| 359 | 548 | &target, |
| 360 | 549 | )?; |
| 361 | PreparedEdit::table_of_contents( | |
| 362 | &source, | |
| 363 | &[onestore::TocEdit::Add { | |
| 364 | filename: target, | |
| 365 | identity, | |
| 366 | group: false, | |
| 367 | }], | |
| 368 | )? | |
| 369 | .commit_file(&bin_toc) | |
| 370 | .map_err(|error| error.error)?; | |
| 550 | self.storage.commit( | |
| 551 | &bin_toc, | |
| 552 | &PreparedEdit::table_of_contents( | |
| 553 | &source, | |
| 554 | &[onestore::TocEdit::Add { | |
| 555 | filename: target, | |
| 556 | identity, | |
| 557 | group: false, | |
| 558 | }], | |
| 559 | )?, | |
| 560 | )?; | |
| 371 | 561 | self.edit_toc(folder, &[onestore::TocEdit::Remove { identity }])?; |
| 372 | 562 | self.refresh().map(drop) |
| 373 | 563 | } |
| ... | ... | @@ -419,7 +609,7 @@ impl Notebook { |
| 419 | 609 | .map(|section| (section.path.clone(), None))); |
| 420 | 610 | }; |
| 421 | 611 | for section in sections { |
| 422 | let bytes = onestore::read_file(self.root.join(&section.path))?; | |
| 612 | let bytes = self.storage.read(&section.path)?; | |
| 423 | 613 | let store = Store::parse(&bytes)?; |
| 424 | 614 | let index = RevisionIndex::parse(&store)?; |
| 425 | 615 | let document = Document::parse(&index)?; |
| ... | ... | @@ -436,11 +626,8 @@ impl Notebook { |
| 436 | 626 | /// written, and the decoded buffers go when the pages have been built. |
| 437 | 627 | #[cfg(feature = "protected")] |
| 438 | 628 | pub fn unlock(&self, path: &str, password: &str) -> Result<Vec<(ExGuid, Page)>> { |
| 439 | let file = self.root.join(path).canonicalize()?; | |
| 440 | if !file.starts_with(&self.root) { | |
| 441 | return Err(io::Error::from(io::ErrorKind::PermissionDenied).into()); | |
| 442 | } | |
| 443 | let bytes = onestore::read_file(&file)?; | |
| 629 | let path = self.section_path(path)?.path.clone(); | |
| 630 | let bytes = self.storage.read(&path)?; | |
| 444 | 631 | let store = Store::parse(&bytes)?; |
| 445 | 632 | let index = RevisionIndex::parse(&store)?; |
| 446 | 633 | let unlocked = onestore::protected::UnlockedSection::open( |
| ... | ... | @@ -456,20 +643,22 @@ impl Notebook { |
| 456 | 643 | .collect() |
| 457 | 644 | } |
| 458 | 645 | |
| 459 | /// Opens a section by its catalog path. | |
| 646 | /// Opens a section of a mounted notebook by its catalog path. | |
| 460 | 647 | pub fn section(&self, path: &str, notify: impl Fn() + Send + 'static) -> Result<Section> { |
| 461 | let mut folders = vec![&self.catalog]; | |
| 462 | while let Some(folder) = folders.pop() { | |
| 463 | if folder.sections.iter().any(|section| section.path == path) { | |
| 464 | let file = self.root.join(path).canonicalize()?; | |
| 465 | if !file.starts_with(&self.root) { | |
| 466 | return Err(io::Error::from(io::ErrorKind::PermissionDenied).into()); | |
| 467 | } | |
| 468 | return Section::open(file, &self.cache, notify); | |
| 469 | } | |
| 470 | folders.extend(&folder.groups); | |
| 648 | let path = self.section_path(path)?.path.clone(); | |
| 649 | let Some(root) = &self.root else { | |
| 650 | return Err(io::Error::new( | |
| 651 | io::ErrorKind::Unsupported, | |
| 652 | "Sections on a share open through Section::resume_smb", | |
| 653 | ) | |
| 654 | .into()); | |
| 655 | }; | |
| 656 | // A section replaced by a link out of the notebook is not the catalog's section. | |
| 657 | let file = root.join(path).canonicalize()?; | |
| 658 | if !file.starts_with(root) { | |
| 659 | return Err(io::Error::from(io::ErrorKind::PermissionDenied).into()); | |
| 471 | 660 | } |
| 472 | Err(io::Error::from(io::ErrorKind::NotFound).into()) | |
| 661 | Section::open(file, &self.cache, notify) | |
| 473 | 662 | } |
| 474 | 663 | } |
| 475 | 664 |
crates/notebook/src/smb/mod.rs+93-3| ... | ... | @@ -13,6 +13,7 @@ use smb2::{ |
| 13 | 13 | lock::{LockElement, LockRequest, LockResponse}, |
| 14 | 14 | query_info::{InfoType, QueryInfoRequest, QueryInfoResponse}, |
| 15 | 15 | read::{ReadRequest, ReadResponse}, |
| 16 | set_info::{SetInfoRequest, SetInfoResponse}, | |
| 16 | 17 | write::{WriteRequest, WriteResponse}, |
| 17 | 18 | }, |
| 18 | 19 | pack::{Pack, ReadCursor, Unpack}, |
| ... | ... | @@ -180,6 +181,23 @@ impl Client { |
| 180 | 181 | } |
| 181 | 182 | |
| 182 | 183 | fn open_shared(&self, path: &str, write: bool, sharing: u32) -> io::Result<File<'_>> { |
| 184 | self.open_with( | |
| 185 | path, | |
| 186 | if write { 0xc0000000 } else { 0x80000000 }, | |
| 187 | sharing, | |
| 188 | CreateDisposition::FileOpen, | |
| 189 | 0x42, | |
| 190 | ) | |
| 191 | } | |
| 192 | ||
| 193 | fn open_with( | |
| 194 | &self, | |
| 195 | path: &str, | |
| 196 | access: u32, | |
| 197 | sharing: u32, | |
| 198 | disposition: CreateDisposition, | |
| 199 | options: u32, | |
| 200 | ) -> io::Result<File<'_>> { | |
| 183 | 201 | if path.is_empty() || path.contains('\0') || path.encode_utf16().count() > 32767 { |
| 184 | 202 | return Err(io::ErrorKind::InvalidInput.into()); |
| 185 | 203 | } |
| ... | ... | @@ -188,11 +206,11 @@ impl Client { |
| 188 | 206 | CreateRequest { |
| 189 | 207 | requested_oplock_level: OplockLevel::None, |
| 190 | 208 | impersonation_level: ImpersonationLevel::Impersonation, |
| 191 | desired_access: FileAccessMask::new(if write { 0xc0000000 } else { 0x80000000 }), | |
| 209 | desired_access: FileAccessMask::new(access), | |
| 192 | 210 | file_attributes: 0, |
| 193 | 211 | share_access: ShareAccess(sharing), |
| 194 | create_disposition: CreateDisposition::FileOpen, | |
| 195 | create_options: 0x42, | |
| 212 | create_disposition: disposition, | |
| 213 | create_options: options, | |
| 196 | 214 | name: smb2::encode_path(&path.replace('\\', "/")), |
| 197 | 215 | create_contexts: Vec::new(), |
| 198 | 216 | }, |
| ... | ... | @@ -203,6 +221,78 @@ impl Client { |
| 203 | 221 | }) |
| 204 | 222 | } |
| 205 | 223 | |
| 224 | /// Creates a file holding `bytes`; an existing file is an error. | |
| 225 | pub fn create(&self, path: &str, bytes: &[u8]) -> io::Result<()> { | |
| 226 | let mut file = self.open_with(path, 0xc0000000, 0, CreateDisposition::FileCreate, 0x40)?; | |
| 227 | let mut written = 0; | |
| 228 | while written < bytes.len() { | |
| 229 | let count = file.write_at(written as u64, &bytes[written..])?; | |
| 230 | if count == 0 { | |
| 231 | return Err(io::ErrorKind::WriteZero.into()); | |
| 232 | } | |
| 233 | written += count; | |
| 234 | } | |
| 235 | file.flush()?; | |
| 236 | file.close() | |
| 237 | } | |
| 238 | ||
| 239 | /// Creates a directory; an existing one is an error. | |
| 240 | pub fn create_directory(&self, path: &str) -> io::Result<()> { | |
| 241 | self.open_with(path, 0x80000000, 7, CreateDisposition::FileCreate, 0x1)? | |
| 242 | .close() | |
| 243 | } | |
| 244 | ||
| 245 | /// Renames or moves a file or directory within the share; an existing target is an | |
| 246 | /// error. | |
| 247 | pub fn rename(&self, from: &str, to: &str) -> io::Result<()> { | |
| 248 | if to.is_empty() || to.contains('\0') { | |
| 249 | return Err(io::ErrorKind::InvalidInput.into()); | |
| 250 | } | |
| 251 | let file = self.open_with( | |
| 252 | from, | |
| 253 | 0x00010000 | 0x80000000, | |
| 254 | 7, | |
| 255 | CreateDisposition::FileOpen, | |
| 256 | 0, | |
| 257 | )?; | |
| 258 | let name: Vec<u8> = to | |
| 259 | .replace('/', "\\") | |
| 260 | .encode_utf16() | |
| 261 | .flat_map(u16::to_le_bytes) | |
| 262 | .collect(); | |
| 263 | let mut buffer = vec![0; 16]; | |
| 264 | buffer.extend_from_slice(&u32::try_from(name.len()).unwrap().to_le_bytes()); | |
| 265 | buffer.extend_from_slice(&name); | |
| 266 | let _: SetInfoResponse = self.request( | |
| 267 | Command::SetInfo, | |
| 268 | SetInfoRequest { | |
| 269 | info_type: InfoType::File, | |
| 270 | file_info_class: 10, | |
| 271 | additional_information: 0, | |
| 272 | file_id: file.id.ok_or(io::ErrorKind::InvalidInput)?, | |
| 273 | buffer, | |
| 274 | }, | |
| 275 | )?; | |
| 276 | file.close() | |
| 277 | } | |
| 278 | ||
| 279 | /// Deletes a file or an empty directory. | |
| 280 | pub fn delete(&self, path: &str) -> io::Result<()> { | |
| 281 | self.open_with(path, 0x00010000, 7, CreateDisposition::FileOpen, 0x1000)? | |
| 282 | .close() | |
| 283 | } | |
| 284 | ||
| 285 | /// Names a section or TOC file for its notebook (`onestore::place`) under native | |
| 286 | /// writer coordination. | |
| 287 | pub fn place(&self, path: &str, ancestor: [u8; 16], name: &str) -> Result<(), CommitError> { | |
| 288 | self.commit(path, |file| { | |
| 289 | onestore::place(file, ancestor, name).map_err(|error| CommitError { | |
| 290 | state: CommitState::NotCommitted, | |
| 291 | error, | |
| 292 | }) | |
| 293 | }) | |
| 294 | } | |
| 295 | ||
| 206 | 296 | /// Reads a bounded external payload while denying concurrent writes and deletion. |
| 207 | 297 | /// Empty files succeed; limits, sharing contention and failed close return no payload. |
| 208 | 298 | pub fn read_asset(&self, path: &str, limit: usize) -> io::Result<Vec<u8>> { |
crates/notebook/src/smb/tests.rs+99| ... | ... | @@ -505,3 +505,102 @@ fn read_limits_respect_negotiation_and_available_credits() { |
| 505 | 505 | } |
| 506 | 506 | } |
| 507 | 507 | } |
| 508 | ||
| 509 | /// Notebook structure over the share: sections and groups created, renamed, coloured, | |
| 510 | /// ordered and deleted through `Notebook::open_smb`, seen again by a fresh discovery. | |
| 511 | #[test] | |
| 512 | #[ignore = "requires an owned Samba share at ONESTORE_SMB_LAB"] | |
| 513 | fn live_structure() { | |
| 514 | use crate::session::Notebook; | |
| 515 | let client = std::sync::Arc::new(client()); | |
| 516 | let root = format!("structure-{}", std::process::id()); | |
| 517 | client.create_directory(&root).unwrap(); | |
| 518 | let first = onestore::create_section("First.one", "First page", "Author").unwrap(); | |
| 519 | client.create(&format!("{root}/First.one"), &first).unwrap(); | |
| 520 | let first_id = onestore::Store::parse(&first).unwrap().header.file_id; | |
| 521 | let toc = | |
| 522 | onestore::create_table_of_contents("Open Notebook.onetoc2", &[("First.one", first_id)]) | |
| 523 | .unwrap(); | |
| 524 | client | |
| 525 | .create(&format!("{root}/Open Notebook.onetoc2"), &toc) | |
| 526 | .unwrap(); | |
| 527 | let toc_id = onestore::Store::parse(&toc).unwrap().header.file_id; | |
| 528 | client | |
| 529 | .place(&format!("{root}/First.one"), toc_id, "First.one") | |
| 530 | .unwrap(); | |
| 531 | let cache = tempfile::tempdir().unwrap(); | |
| 532 | let mut notebook = | |
| 533 | Notebook::open_smb(std::sync::Arc::clone(&client), &root, cache.path()).unwrap(); | |
| 534 | assert_eq!( | |
| 535 | notebook.create_section("", "Second", "Author").unwrap(), | |
| 536 | "Second.one" | |
| 537 | ); | |
| 538 | assert_eq!(notebook.create_group("", "Archive").unwrap(), "Archive"); | |
| 539 | assert_eq!( | |
| 540 | notebook | |
| 541 | .create_section("Archive", "Inner", "Author") | |
| 542 | .unwrap(), | |
| 543 | "Archive/Inner.one" | |
| 544 | ); | |
| 545 | assert_eq!( | |
| 546 | notebook.rename("Second.one", "Renamed").unwrap(), | |
| 547 | "Renamed.one" | |
| 548 | ); | |
| 549 | assert_eq!(notebook.rename("Archive", "Kept").unwrap(), "Kept"); | |
| 550 | notebook | |
| 551 | .set_section_color("Renamed.one", Some(0x5ed7ff)) | |
| 552 | .unwrap(); | |
| 553 | notebook.reorder("", &["Kept", "Renamed.one"]).unwrap(); | |
| 554 | notebook.delete("First.one").unwrap(); | |
| 555 | let names = |folder: &crate::discover::Folder| { | |
| 556 | ( | |
| 557 | folder | |
| 558 | .sections | |
| 559 | .iter() | |
| 560 | .map(|s| s.path.clone()) | |
| 561 | .collect::<Vec<_>>(), | |
| 562 | folder | |
| 563 | .groups | |
| 564 | .iter() | |
| 565 | .map(|g| g.path.clone()) | |
| 566 | .collect::<Vec<_>>(), | |
| 567 | ) | |
| 568 | }; | |
| 569 | let fresh = Notebook::open_smb(std::sync::Arc::clone(&client), &root, cache.path()).unwrap(); | |
| 570 | assert_eq!( | |
| 571 | names(fresh.catalog()), | |
| 572 | ( | |
| 573 | vec!["Renamed.one".to_owned()], | |
| 574 | vec!["Kept".to_owned(), "OneNote_RecycleBin".to_owned()] | |
| 575 | ) | |
| 576 | ); | |
| 577 | assert_eq!( | |
| 578 | names(&fresh.catalog().groups[0]), | |
| 579 | (vec!["Kept/Inner.one".to_owned()], vec![]) | |
| 580 | ); | |
| 581 | assert_eq!( | |
| 582 | names(&fresh.catalog().groups[1]), | |
| 583 | (vec!["OneNote_RecycleBin/First.one".to_owned()], vec![]) | |
| 584 | ); | |
| 585 | assert!(fresh.catalog().toc.as_ref().unwrap().unresolved.is_empty()); | |
| 586 | let renamed = client | |
| 587 | .read_storage(&format!("{root}/Renamed.one"), 1 << 20) | |
| 588 | .unwrap(); | |
| 589 | let header = onestore::Store::parse(&renamed).unwrap().header; | |
| 590 | assert_eq!(header.ancestor, toc_id); | |
| 591 | assert_eq!(header.name_crc, 0x6108912a); | |
| 592 | assert!(fresh.section("Renamed.one", || {}).is_err()); | |
| 593 | for path in [ | |
| 594 | "Renamed.one", | |
| 595 | "Kept/Inner.one", | |
| 596 | "Kept/Open Notebook.onetoc2", | |
| 597 | "Kept", | |
| 598 | "OneNote_RecycleBin/First.one", | |
| 599 | "OneNote_RecycleBin/Open Notebook.onetoc2", | |
| 600 | "OneNote_RecycleBin", | |
| 601 | "Open Notebook.onetoc2", | |
| 602 | ] { | |
| 603 | client.delete(&format!("{root}/{path}")).unwrap(); | |
| 604 | } | |
| 605 | client.delete(&root).unwrap(); | |
| 606 | } |
crates/notebook/tests/copy.rs+25-4| ... | ... | @@ -15,11 +15,12 @@ use std::{ |
| 15 | 15 | }; |
| 16 | 16 | |
| 17 | 17 | /// Pages the writer authored for other rows: text with an attachment and its icon, a |
| 18 | /// table, an inserted picture, a page-level ink drawing, tags, lists, equations | |
| 18 | /// table, nested tables with cell subtrees, an inserted picture, a page-level ink drawing, tags, lists, equations | |
| 19 | 19 | /// and paragraph formatting. |
| 20 | 20 | const SOURCES: &[&str] = &[ |
| 21 | 21 | "attachment-edit/icon/candidate/files.one", |
| 22 | 22 | "table-edit/created/candidate/tables.one", |
| 23 | "table-edit/nested/candidate/synthetic.one", | |
| 23 | 24 | "picture-edit/inserted/candidate/pictures.one", |
| 24 | 25 | "ink-edit/drawing/candidate/ink.one", |
| 25 | 26 | "tag-edit/candidate/tags.one", |
| ... | ... | @@ -64,8 +65,10 @@ fn shape(page: &Page) -> String { |
| 64 | 65 | serde_json::Value::Object(fields) => { |
| 65 | 66 | // The writer's canonical formatting: an unset flag is false and unset |
| 66 | 67 | // spacing is zero. |
| 67 | fields.retain(|_, value| { | |
| 68 | !value.is_null() | |
| 68 | fields.retain(|key, value| { | |
| 69 | // OneNote lays outlines out again on open. | |
| 70 | key != "max_height" | |
| 71 | && !value.is_null() | |
| 69 | 72 | && *value != serde_json::Value::Bool(false) |
| 70 | 73 | && value.as_f64() != Some(0.0) |
| 71 | 74 | }); |
| ... | ... | @@ -153,6 +156,7 @@ fn pages_copy_into_another_section_with_their_content_and_fresh_identities() { |
| 153 | 156 | .unwrap(); |
| 154 | 157 | let section = Section::open(&file, &cache, || {}).unwrap(); |
| 155 | 158 | let mut expected = Vec::new(); |
| 159 | let mut grouped = Vec::new(); | |
| 156 | 160 | for source in SOURCES { |
| 157 | 161 | let bytes = std::fs::read( |
| 158 | 162 | Path::new(concat!(env!("CARGO_MANIFEST_DIR"), "/../../corpus")).join(source), |
| ... | ... | @@ -166,7 +170,14 @@ fn pages_copy_into_another_section_with_their_content_and_fresh_identities() { |
| 166 | 170 | { |
| 167 | 171 | continue; |
| 168 | 172 | } |
| 169 | let copy = page.copy().unwrap(); | |
| 173 | let copy = match page.copy() { | |
| 174 | Ok(copy) => copy, | |
| 175 | Err(error) if error.message == "Outline groups cannot be copied" => { | |
| 176 | grouped.push(page.title.clone()); | |
| 177 | continue; | |
| 178 | } | |
| 179 | Err(error) => panic!("{source} {}: {error}", page.title), | |
| 180 | }; | |
| 170 | 181 | assert_ne!(copy.identity, page.identity); |
| 171 | 182 | let space = section |
| 172 | 183 | .import_page(&page, "Copier") |
| ... | ... | @@ -175,6 +186,16 @@ fn pages_copy_into_another_section_with_their_content_and_fresh_identities() { |
| 175 | 186 | } |
| 176 | 187 | } |
| 177 | 188 | assert!(expected.len() >= 8, "{} pages", expected.len()); |
| 189 | // Outdenting leaves paragraphs at levels only an outline group carries. | |
| 190 | assert_eq!( | |
| 191 | grouped, | |
| 192 | [ | |
| 193 | "Outdent first group", | |
| 194 | "Delete only grouped subtree", | |
| 195 | "Delete unindented sibling after group", | |
| 196 | "Outdent child across indentation gap" | |
| 197 | ] | |
| 198 | ); | |
| 178 | 199 | let deadline = Instant::now() + Duration::from_secs(120); |
| 179 | 200 | while section |
| 180 | 201 | .queue() |
crates/onestore/README.md+2-2| ... | ... | @@ -43,7 +43,7 @@ harness also accepts `--client-profile release`. |
| 43 | 43 | | `Object::file_reference`, `Store::file_data` | Identify internal/external payloads and read internal payload bytes | |
| 44 | 44 | | `document::Document`, `Revision::text_runs` | Interpret document objects and inherited text formatting while retaining unknown properties and revision identities | |
| 45 | 45 | | `Document::active`, `Document::pages_in`, `Revision::parents`, `RevisionIndex::active` | Resolve the active revision, the pages of a space and parent links without repeating the lookups | |
| 46 | | `Page::copy` | The page's content under fresh identities for copying into another section, definitions and payloads included | | |
| 46 | | `Page::copy` | The page's content under fresh identities for copying into another section, definitions and payloads included; indent levels only an outline group carries refuse | | |
| 47 | 47 | | `page::link::internal_link`, `page::link::parse_internal_link` | Build and read the `onenote:#…` URLs OneNote stores for links to sections, pages and paragraphs, by identity | |
| 48 | 48 | | `page::Page`, `page::Paragraph`, `page::Ink`, `page::Math` | Build an editable page model (title, outlines, paragraphs with coalesced text spans, tables, images, attachments, ink drawings and handwriting decoded to stroke polylines in page points) with stored identities; equations parse from their linear text and run data into a tree that renders the MathML OneNote exports; content outside the model is retained as `Unsupported` | |
| 49 | 49 | | `protected::UnlockedSection` (optional feature) | Own decoded buffers for explicit known-password inspection; clear those buffers on drop; derived document strings/exports remain caller-owned | |
| ... | ... | @@ -53,7 +53,7 @@ harness also accepts `--client-profile release`. |
| 53 | 53 | | `PreparedEdit::delete_pages_permanently` | Remove explicit pages and their section references atomically while retaining stored revisions | |
| 54 | 54 | | `create_table_of_contents` | Create ordered section entries from filenames and file identities | |
| 55 | 55 | | `TocEdit`, `PreparedEdit::table_of_contents` | Add, rename, colour, order and remove a table of contents' section and group entries as one revision | |
| 56 | | `place_file` | Name a file for its notebook as OneNote does on adoption (parent TOC identity and name CRC in the header), so OneNote keeps its identity | | |
| 56 | | `place`, `place_file` | Name a file for its notebook as OneNote does on adoption (parent TOC identity and name CRC in the header), so OneNote keeps its identity, on any `CommitIo` or under the filesystem adapter | | |
| 57 | 57 | | `replace_property_bytes` | Append one scalar-property revision; preserve prior revisions and unrelated property values and references | |
| 58 | 58 | | `replace_text`, `commit_text`, `commit_file_text` | Replace a UTF-16 range across ordinary text runs; publish text, run boundaries and modification time together | |
| 59 | 59 | | `Insertion`, `PreparedEdit::insert` | Insert paragraphs into editable containers or positioned outlines into a page, retaining intent identities across rebases | |
crates/onestore/src/commit.rs+18-14| ... | ... | @@ -74,23 +74,27 @@ impl Drop for FileIo { |
| 74 | 74 | /// Places a file in its notebook the way OneNote does on adoption: the header's |
| 75 | 75 | /// `guidAncestor` becomes the parent table of contents' file identity and `crcName` the CRC |
| 76 | 76 | /// of `name` (a section's file name, a group's folder name). OneNote re-identifies a file |
| 77 | /// whose header disagrees with its location, which orphans its TOC entry. | |
| 77 | /// whose header disagrees with its location, which orphans its TOC entry. The caller holds | |
| 78 | /// OneNote-compatible exclusion on `io`. | |
| 79 | pub fn place(io: &mut impl CommitIo, ancestor: [u8; 16], name: &str) -> io::Result<()> { | |
| 80 | let mut header = [0; 1024]; | |
| 81 | if io.read_at(0, &mut header)? != header.len() { | |
| 82 | return Err(io::Error::from(ErrorKind::UnexpectedEof)); | |
| 83 | } | |
| 84 | crate::Header::parse(&header) | |
| 85 | .map_err(|error| io::Error::new(ErrorKind::InvalidData, error.message))?; | |
| 86 | let placement = crate::create::placement(ancestor, name); | |
| 87 | if io.write_at(128, &placement)? != placement.len() { | |
| 88 | return Err(io::Error::from(ErrorKind::WriteZero)); | |
| 89 | } | |
| 90 | io.flush() | |
| 91 | } | |
| 92 | ||
| 93 | /// `place` under the conservative filesystem adapter's whole-file exclusion. | |
| 78 | 94 | #[cfg(any(unix, windows))] |
| 79 | 95 | pub fn place_file(path: impl AsRef<Path>, ancestor: [u8; 16], name: &str) -> io::Result<()> { |
| 80 | 96 | let mut io = FileIo::open(path, true)?; |
| 81 | let mut header = [0; 1024]; | |
| 82 | let result = (|| { | |
| 83 | if io.read_at(0, &mut header)? != header.len() { | |
| 84 | return Err(io::Error::from(ErrorKind::UnexpectedEof)); | |
| 85 | } | |
| 86 | crate::Header::parse(&header) | |
| 87 | .map_err(|error| io::Error::new(ErrorKind::InvalidData, error.message))?; | |
| 88 | let placement = crate::create::placement(ancestor, name); | |
| 89 | if io.write_at(128, &placement)? != placement.len() { | |
| 90 | return Err(io::Error::from(ErrorKind::WriteZero)); | |
| 91 | } | |
| 92 | io.flush() | |
| 93 | })(); | |
| 97 | let result = place(&mut io, ancestor, name); | |
| 94 | 98 | let released = io.release(); |
| 95 | 99 | result?; |
| 96 | 100 | released |
crates/onestore/src/formatting.rs+3| ... | ... | @@ -35,6 +35,8 @@ pub enum TextAttribute { |
| 35 | 35 | Color(Option<[u8; 3]>), |
| 36 | 36 | /// RGB, or None to clear highlighting. |
| 37 | 37 | Highlight(Option<[u8; 3]>), |
| 38 | /// Windows language id of the run, such as 1033 for US English. | |
| 39 | Language(u32), | |
| 38 | 40 | /// Hidden text, such as a hyperlink's field code. |
| 39 | 41 | Hidden(bool), |
| 40 | 42 | /// The run belongs to a hyperlink field. |
| ... | ... | @@ -73,6 +75,7 @@ impl TextAttribute { |
| 73 | 75 | } |
| 74 | 76 | (0x10001c0b, ((*points * 2.0) as u16).to_le_bytes().to_vec()) |
| 75 | 77 | } |
| 78 | Self::Language(language) => (0x14001c3b, language.to_le_bytes().to_vec()), | |
| 76 | 79 | Self::Color(color) | Self::Highlight(color) => ( |
| 77 | 80 | if matches!(self, Self::Color(_)) { |
| 78 | 81 | 0x14001c0c |
crates/onestore/src/lib.rs+1-1| ... | ... | @@ -27,7 +27,7 @@ mod write; |
| 27 | 27 | |
| 28 | 28 | pub use commit::{ |
| 29 | 29 | CommitError, CommitIo, CommitState, PreparedEdit, commit_property_bytes, commit_text, |
| 30 | confirm_snapshot, | |
| 30 | confirm_snapshot, place, | |
| 31 | 31 | }; |
| 32 | 32 | #[cfg(any(unix, windows))] |
| 33 | 33 | pub use commit::{ |
crates/onestore/src/page/mod.rs+27| ... | ... | @@ -421,6 +421,33 @@ impl Page { |
| 421 | 421 | let mut copy: Self = |
| 422 | 422 | serde_json::from_value(value).map_err(|_| invalid("Page copy does not deserialize"))?; |
| 423 | 423 | copy.identity = Some(crate::write::fresh_guid()?); |
| 424 | // A paragraph's indent level follows its parent chain; a level beyond that comes | |
| 425 | // from an outline group, which the model does not hold. | |
| 426 | fn levels(paragraphs: &[PageParagraph]) -> bool { | |
| 427 | let by_id: BTreeMap<ExGuid, u32> = paragraphs.iter().map(|p| (p.id, p.level)).collect(); | |
| 428 | paragraphs.iter().all(|paragraph| { | |
| 429 | let expected = match paragraph.parent { | |
| 430 | Some(parent) => by_id.get(&parent).map_or(0, |level| level + 1), | |
| 431 | None => 1, | |
| 432 | }; | |
| 433 | paragraph.level == expected | |
| 434 | && match &paragraph.content { | |
| 435 | ParagraphContent::Table(table) => table | |
| 436 | .rows | |
| 437 | .iter() | |
| 438 | .flat_map(|row| &row.cells) | |
| 439 | .all(|cell| levels(&cell.paragraphs)), | |
| 440 | _ => true, | |
| 441 | } | |
| 442 | }) | |
| 443 | } | |
| 444 | let expressible = copy.objects.iter().all(|object| match object { | |
| 445 | PageObject::Outline(outline) => levels(&outline.paragraphs), | |
| 446 | _ => true, | |
| 447 | }); | |
| 448 | if !expressible { | |
| 449 | return Err(invalid("Outline groups cannot be copied")); | |
| 450 | } | |
| 424 | 451 | Ok(copy) |
| 425 | 452 | } |
| 426 | 453 |
crates/onestore/src/page/write.rs+55-7| ... | ... | @@ -355,6 +355,7 @@ pub(crate) fn write_page( |
| 355 | 355 | page: *page, |
| 356 | 356 | author, |
| 357 | 357 | alias: BTreeMap::new(), |
| 358 | built: BTreeSet::new(), | |
| 358 | 359 | }; |
| 359 | 360 | lowering.run(&before, after, &raw.objects.keys().copied().collect())?; |
| 360 | 361 | if lowering.image == source { |
| ... | ... | @@ -457,6 +458,8 @@ struct Lowering<'a> { |
| 457 | 458 | author: &'a str, |
| 458 | 459 | /// Model identities of new objects mapped to the identities the typed writers allocated. |
| 459 | 460 | alias: BTreeMap<ExGuid, ExGuid>, |
| 461 | /// Tables whose structure this run has written. | |
| 462 | built: BTreeSet<ExGuid>, | |
| 460 | 463 | } |
| 461 | 464 | |
| 462 | 465 | impl Lowering<'_> { |
| ... | ... | @@ -900,20 +903,48 @@ impl Lowering<'_> { |
| 900 | 903 | collect_containers(&outline.paragraphs, &mut containers); |
| 901 | 904 | } |
| 902 | 905 | } |
| 903 | // Cells that do not exist yet receive their paragraphs once the table structure does. | |
| 906 | // Cells that do not exist yet, and containers inside them, receive their | |
| 907 | // paragraphs once the table structure does. | |
| 908 | let new_cell = |id: &ExGuid| { | |
| 909 | !(old.children.contains_key(id) | |
| 910 | || new.paragraphs.contains_key(id) | |
| 911 | || new.outlines.contains_key(id)) | |
| 912 | }; | |
| 904 | 913 | let (existing, deferred): (Vec<ExGuid>, Vec<ExGuid>) = |
| 905 | 914 | containers.into_iter().partition(|container| { |
| 906 | old.children.contains_key(container) | |
| 907 | || new.paragraphs.contains_key(container) | |
| 908 | || new.outlines.contains_key(container) | |
| 915 | let mut at = *container; | |
| 916 | loop { | |
| 917 | if new_cell(&at) { | |
| 918 | return false; | |
| 919 | } | |
| 920 | match new.container.get(&at) { | |
| 921 | Some(parent) => at = *parent, | |
| 922 | None => return true, | |
| 923 | } | |
| 924 | } | |
| 909 | 925 | }); |
| 910 | 926 | self.place_containers(old, new, placed, &existing)?; |
| 911 | self.edit_table_structure(old, new)?; | |
| 927 | // Each round builds the tables whose holders exist and fills their cells, which | |
| 928 | // may hold further new tables. | |
| 929 | let mut pending = deferred; | |
| 930 | loop { | |
| 931 | self.edit_table_structure(old, new)?; | |
| 932 | if pending.is_empty() { | |
| 933 | break; | |
| 934 | } | |
| 935 | let (ready, waiting): (Vec<ExGuid>, Vec<ExGuid>) = pending | |
| 936 | .into_iter() | |
| 937 | .partition(|container| self.alias.contains_key(container)); | |
| 938 | if ready.is_empty() { | |
| 939 | return Err(invalid("Table content has no table to hold it")); | |
| 940 | } | |
| 941 | self.place_containers(old, new, placed, &ready)?; | |
| 942 | pending = waiting; | |
| 943 | } | |
| 912 | 944 | self.edit_cells(old, new)?; |
| 913 | 945 | self.edit_images(old, new)?; |
| 914 | 946 | self.edit_ink_paragraphs(old, new)?; |
| 915 | 947 | self.edit_attachments(old, new)?; |
| 916 | self.place_containers(old, new, placed, &deferred)?; | |
| 917 | 948 | Ok(()) |
| 918 | 949 | } |
| 919 | 950 | |
| ... | ... | @@ -1577,6 +1608,13 @@ impl Lowering<'_> { |
| 1577 | 1608 | continue; |
| 1578 | 1609 | }; |
| 1579 | 1610 | let previous = old_tables.get(&table.id).copied(); |
| 1611 | // A table is built once its holder is placed, and only once. | |
| 1612 | if !(old.paragraphs.contains_key(paragraph_id) || self.alias.contains_key(paragraph_id)) | |
| 1613 | || self.built.contains(&table.id) | |
| 1614 | { | |
| 1615 | continue; | |
| 1616 | } | |
| 1617 | self.built.insert(table.id); | |
| 1580 | 1618 | let unchanged = previous.is_some_and(|previous| { |
| 1581 | 1619 | previous.columns == table.columns |
| 1582 | 1620 | && previous.borders == table.borders |
| ... | ... | @@ -2450,6 +2488,9 @@ impl Lowering<'_> { |
| 2450 | 2488 | spacing!(space_before, 0x1400342e); |
| 2451 | 2489 | spacing!(space_after, 0x1400342f); |
| 2452 | 2490 | spacing!(line_spacing, 0x14003430); |
| 2491 | field!(language, value, { | |
| 2492 | (0x14001c3b, value.to_le_bytes().to_vec()) | |
| 2493 | }); | |
| 2453 | 2494 | if values.is_empty() { |
| 2454 | 2495 | continue; |
| 2455 | 2496 | } |
| ... | ... | @@ -2827,6 +2868,13 @@ fn attributes(current: &Format, target: &Format, fresh: bool) -> Result<Vec<Text |
| 2827 | 2868 | None => return Err(inherited()), |
| 2828 | 2869 | } |
| 2829 | 2870 | } |
| 2871 | if current.language != target.language { | |
| 2872 | match target.language { | |
| 2873 | Some(language) => out.push(TextAttribute::Language(language)), | |
| 2874 | None if fresh => {} | |
| 2875 | None => return Err(inherited()), | |
| 2876 | } | |
| 2877 | } | |
| 2830 | 2878 | // An absent value and its stored default are the same formatting. |
| 2831 | 2879 | let flag = |a: Option<bool>, b: Option<bool>| a.unwrap_or(false) == b.unwrap_or(false); |
| 2832 | 2880 | let points = |a: Option<f32>, b: Option<f32>| a.unwrap_or(0.0) == b.unwrap_or(0.0); |
| ... | ... | @@ -2840,7 +2888,7 @@ fn attributes(current: &Format, target: &Format, fresh: bool) -> Result<Vec<Text |
| 2840 | 2888 | && points(current.list_spacing, target.list_spacing); |
| 2841 | 2889 | if !same_rest { |
| 2842 | 2890 | return Err(invalid( |
| 2843 | "Fields, language and paragraph spacing cannot be edited through the page model", | |
| 2891 | "Fields and paragraph spacing cannot be edited through the page model", | |
| 2844 | 2892 | )); |
| 2845 | 2893 | } |
| 2846 | 2894 | Ok(out) |
tools/test_smb_structure.py created+29| ... | ... | @@ -0,0 +1,29 @@ |
| 1 | #!/usr/bin/env python3 | |
| 2 | """Run the notebook-structure lane against a disposable Linux lab VM's Samba share.""" | |
| 3 | import argparse | |
| 4 | import os | |
| 5 | from pathlib import Path | |
| 6 | import subprocess | |
| 7 | import sys | |
| 8 | ||
| 9 | sys.path.insert(0, str(Path(__file__).resolve().parent / 'w7')) | |
| 10 | from linux_vm import load_instance | |
| 11 | ||
| 12 | ||
| 13 | def main(): | |
| 14 | parser = argparse.ArgumentParser(description=__doc__) | |
| 15 | parser.add_argument('vm', help='An already running, caller-owned Linux lab VM') | |
| 16 | parser.add_argument('output', type=Path) | |
| 17 | args = parser.parse_args() | |
| 18 | output = args.output.resolve() | |
| 19 | output.mkdir(parents=True, exist_ok=False) | |
| 20 | config = load_instance(args.vm) | |
| 21 | env = dict(os.environ, ONESTORE_SMB_LAB=f'127.0.0.1:{config["samba_port"]}') | |
| 22 | with (output / 'structure.log').open('w') as result: | |
| 23 | subprocess.run(['cargo', 'test', '-p', 'notebook', '--features', 'smb', 'smb::tests::live_structure', '--', '--ignored', '--exact'], | |
| 24 | env=env, stdout=result, stderr=result, check=True, timeout=600) | |
| 25 | print('structure: passed', flush=True) | |
| 26 | ||
| 27 | ||
| 28 | if __name__ == '__main__': | |
| 29 | main() |