@forevka/wordcanvas 0.8.1 → 0.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist-lib/assets/{worker-BFAbWoje.js → worker-VdvO3cMW.js} +1198 -1182
- package/dist-lib/builder.js +5 -5
- package/dist-lib/{editorApp-CQn18PAu.js → editorApp-BGyP48-P.js} +37 -36
- package/dist-lib/{recalcToc-Dzz8cQho.js → engine-Chvebzwr.js} +525 -548
- package/dist-lib/export.js +8 -7
- package/dist-lib/generate-toc.js +7 -6
- package/dist-lib/import.js +2 -2
- package/dist-lib/{lists-DpmgbDyt.js → lists-BVCy5dMa.js} +2 -2
- package/dist-lib/{parse-CIuWi88O.js → parse-PD2rg4oO.js} +28 -28
- package/dist-lib/{pipeline-DQil8qUX.js → pipeline-r7GVSMFb.js} +60 -60
- package/dist-lib/query.js +977 -0
- package/dist-lib/recalc-docx.js +22 -21
- package/dist-lib/recalcToc-CAeOzLr3.js +37 -0
- package/dist-lib/{stylesheet-BeM16Mvj.js → stylesheet-IH4Hyc8o.js} +3 -3
- package/dist-lib/{toc-C-JErW1U.js → toc-B-TzD-Mr.js} +102 -86
- package/dist-lib/{webmcp-B9Q6w0Vl.js → webmcp-CDpzmTtU.js} +2 -2
- package/dist-lib/{wordcanvas-Cla5Ys8Y.js → wordcanvas-CIqBAV2w.js} +3 -3
- package/dist-lib/wordcanvas.js +1 -1
- package/dist-node/{chunk-JVSPB6WM.js → chunk-A53KB3BE.js} +2 -2
- package/dist-node/{chunk-HMBQQDXD.js → chunk-TLGEFCLV.js} +64 -1
- package/dist-node/chunk-TLGEFCLV.js.map +7 -0
- package/dist-node/{chunk-KZHUXFDE.js → chunk-VNDCELYX.js} +5 -45
- package/dist-node/chunk-VNDCELYX.js.map +7 -0
- package/dist-node/{engine-46GL2RKU.js → engine-QKH45ZHY.js} +5 -4
- package/dist-node/export.js +3 -3
- package/dist-node/generate-toc.js +3 -3
- package/dist-node/import.js +2 -2
- package/dist-node/recalc-docx.js +2 -2
- package/package.json +6 -2
- package/types/builder.d.ts +47 -2
- package/types/model.d.ts +34 -0
- package/types/query.d.ts +416 -0
- package/dist-node/chunk-HMBQQDXD.js.map +0 -7
- package/dist-node/chunk-KZHUXFDE.js.map +0 -7
- /package/dist-node/{chunk-JVSPB6WM.js.map → chunk-A53KB3BE.js.map} +0 -0
- /package/dist-node/{engine-46GL2RKU.js.map → engine-QKH45ZHY.js.map} +0 -0
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../../node_modules/@chenglou/pretext/dist/generated/bidi-data.js", "../../node_modules/@chenglou/pretext/dist/bidi.js", "../../node_modules/@chenglou/pretext/dist/analysis.js", "../../node_modules/@chenglou/pretext/dist/measurement.js", "../../node_modules/@chenglou/pretext/dist/line-break.js", "../../node_modules/@chenglou/pretext/dist/line-text.js", "../../node_modules/@chenglou/pretext/dist/layout.js", "../../node_modules/@chenglou/pretext/dist/rich-inline.js", "../src/layout/math/mathBox.ts", "../src/layout/math/mathAlpha.ts", "../src/layout/math/layoutMath.ts", "../src/layout/math/stixMathConstants.ts", "../src/layout/math/mathFont.ts", "../src/layout/math/equationLayout.ts", "../src/layout/prepareCache.ts", "../src/layout/bidi.ts", "../src/layout/engine.ts"],
|
|
4
|
-
"sourcesContent": ["// Generated by scripts/generate-bidi-data.ts from scripts/unicode/DerivedBidiClass-17.0.0.txt.\n// Do not edit by hand. Regenerate with `bun run generate:bidi-data`.\n// Formatting and isolate controls are projected onto `BN` because the rich\n// bidi helper consumes a simplified class set and does not model UBA isolates.\nexport const unicodeBidiDataVersion = '17.0.0';\nexport const latin1BidiTypes = [\n 'BN',\n 'BN',\n 'BN',\n 'BN',\n 'BN',\n 'BN',\n 'BN',\n 'BN',\n 'BN',\n 'S',\n 'B',\n 'S',\n 'WS',\n 'B',\n 'BN',\n 'BN',\n 'BN',\n 'BN',\n 'BN',\n 'BN',\n 'BN',\n 'BN',\n 'BN',\n 'BN',\n 'BN',\n 'BN',\n 'BN',\n 'BN',\n 'B',\n 'B',\n 'B',\n 'S',\n 'WS',\n 'ON',\n 'ON',\n 'ET',\n 'ET',\n 'ET',\n 'ON',\n 'ON',\n 'ON',\n 'ON',\n 'ON',\n 'ES',\n 'CS',\n 'ES',\n 'CS',\n 'CS',\n 'EN',\n 'EN',\n 'EN',\n 'EN',\n 'EN',\n 'EN',\n 'EN',\n 'EN',\n 'EN',\n 'EN',\n 'CS',\n 'ON',\n 'ON',\n 'ON',\n 'ON',\n 'ON',\n 'ON',\n 'L',\n 'L',\n 'L',\n 'L',\n 'L',\n 'L',\n 'L',\n 'L',\n 'L',\n 'L',\n 'L',\n 'L',\n 'L',\n 'L',\n 'L',\n 'L',\n 'L',\n 'L',\n 'L',\n 'L',\n 'L',\n 'L',\n 'L',\n 'L',\n 'L',\n 'L',\n 'ON',\n 'ON',\n 'ON',\n 'ON',\n 'ON',\n 'ON',\n 'L',\n 'L',\n 'L',\n 'L',\n 'L',\n 'L',\n 'L',\n 'L',\n 'L',\n 'L',\n 'L',\n 'L',\n 'L',\n 'L',\n 'L',\n 'L',\n 'L',\n 'L',\n 'L',\n 'L',\n 'L',\n 'L',\n 'L',\n 'L',\n 'L',\n 'L',\n 'ON',\n 'ON',\n 'ON',\n 'ON',\n 'BN',\n 'BN',\n 'BN',\n 'BN',\n 'BN',\n 'BN',\n 'B',\n 'BN',\n 'BN',\n 'BN',\n 'BN',\n 'BN',\n 'BN',\n 'BN',\n 'BN',\n 'BN',\n 'BN',\n 'BN',\n 'BN',\n 'BN',\n 'BN',\n 'BN',\n 'BN',\n 'BN',\n 'BN',\n 'BN',\n 'BN',\n 'BN',\n 'BN',\n 'BN',\n 'BN',\n 'BN',\n 'BN',\n 'CS',\n 'ON',\n 'ET',\n 'ET',\n 'ET',\n 'ET',\n 'ON',\n 'ON',\n 'ON',\n 'ON',\n 'L',\n 'ON',\n 'ON',\n 'BN',\n 'ON',\n 'ON',\n 'ET',\n 'ET',\n 'EN',\n 'EN',\n 'ON',\n 'L',\n 'ON',\n 'ON',\n 'ON',\n 'EN',\n 'L',\n 'ON',\n 'ON',\n 'ON',\n 'ON',\n 'ON',\n 'L',\n 'L',\n 'L',\n 'L',\n 'L',\n 'L',\n 'L',\n 'L',\n 'L',\n 'L',\n 'L',\n 'L',\n 'L',\n 'L',\n 'L',\n 'L',\n 'L',\n 'L',\n 'L',\n 'L',\n 'L',\n 'L',\n 'L',\n 'ON',\n 'L',\n 'L',\n 'L',\n 'L',\n 'L',\n 'L',\n 'L',\n 'L',\n 'L',\n 'L',\n 'L',\n 'L',\n 'L',\n 'L',\n 'L',\n 'L',\n 'L',\n 'L',\n 'L',\n 'L',\n 'L',\n 'L',\n 'L',\n 'L',\n 'L',\n 'L',\n 'L',\n 'L',\n 'L',\n 'L',\n 'L',\n 'ON',\n 'L',\n 'L',\n 'L',\n 'L',\n 'L',\n 'L',\n 'L',\n 'L',\n];\nexport const nonLatin1BidiRanges = [\n [0x2B9, 0x2BA, 'ON'],\n [0x2C2, 0x2CF, 'ON'],\n [0x2D2, 0x2DF, 'ON'],\n [0x2E5, 0x2ED, 'ON'],\n [0x2EF, 0x2FF, 'ON'],\n [0x300, 0x36F, 'NSM'],\n [0x374, 0x375, 'ON'],\n [0x37E, 0x37E, 'ON'],\n [0x384, 0x385, 'ON'],\n [0x387, 0x387, 'ON'],\n [0x3F6, 0x3F6, 'ON'],\n [0x483, 0x489, 'NSM'],\n [0x58A, 0x58A, 'ON'],\n [0x58D, 0x58E, 'ON'],\n [0x58F, 0x58F, 'ET'],\n [0x590, 0x590, 'R'],\n [0x591, 0x5BD, 'NSM'],\n [0x5BE, 0x5BE, 'R'],\n [0x5BF, 0x5BF, 'NSM'],\n [0x5C0, 0x5C0, 'R'],\n [0x5C1, 0x5C2, 'NSM'],\n [0x5C3, 0x5C3, 'R'],\n [0x5C4, 0x5C5, 'NSM'],\n [0x5C6, 0x5C6, 'R'],\n [0x5C7, 0x5C7, 'NSM'],\n [0x5C8, 0x5FF, 'R'],\n [0x600, 0x605, 'AN'],\n [0x606, 0x607, 'ON'],\n [0x608, 0x608, 'AL'],\n [0x609, 0x60A, 'ET'],\n [0x60B, 0x60B, 'AL'],\n [0x60C, 0x60C, 'CS'],\n [0x60D, 0x60D, 'AL'],\n [0x60E, 0x60F, 'ON'],\n [0x610, 0x61A, 'NSM'],\n [0x61B, 0x64A, 'AL'],\n [0x64B, 0x65F, 'NSM'],\n [0x660, 0x669, 'AN'],\n [0x66A, 0x66A, 'ET'],\n [0x66B, 0x66C, 'AN'],\n [0x66D, 0x66F, 'AL'],\n [0x670, 0x670, 'NSM'],\n [0x671, 0x6D5, 'AL'],\n [0x6D6, 0x6DC, 'NSM'],\n [0x6DD, 0x6DD, 'AN'],\n [0x6DE, 0x6DE, 'ON'],\n [0x6DF, 0x6E4, 'NSM'],\n [0x6E5, 0x6E6, 'AL'],\n [0x6E7, 0x6E8, 'NSM'],\n [0x6E9, 0x6E9, 'ON'],\n [0x6EA, 0x6ED, 'NSM'],\n [0x6EE, 0x6EF, 'AL'],\n [0x6F0, 0x6F9, 'EN'],\n [0x6FA, 0x710, 'AL'],\n [0x711, 0x711, 'NSM'],\n [0x712, 0x72F, 'AL'],\n [0x730, 0x74A, 'NSM'],\n [0x74B, 0x7A5, 'AL'],\n [0x7A6, 0x7B0, 'NSM'],\n [0x7B1, 0x7BF, 'AL'],\n [0x7C0, 0x7EA, 'R'],\n [0x7EB, 0x7F3, 'NSM'],\n [0x7F4, 0x7F5, 'R'],\n [0x7F6, 0x7F9, 'ON'],\n [0x7FA, 0x7FC, 'R'],\n [0x7FD, 0x7FD, 'NSM'],\n [0x7FE, 0x815, 'R'],\n [0x816, 0x819, 'NSM'],\n [0x81A, 0x81A, 'R'],\n [0x81B, 0x823, 'NSM'],\n [0x824, 0x824, 'R'],\n [0x825, 0x827, 'NSM'],\n [0x828, 0x828, 'R'],\n [0x829, 0x82D, 'NSM'],\n [0x82E, 0x858, 'R'],\n [0x859, 0x85B, 'NSM'],\n [0x85C, 0x85F, 'R'],\n [0x860, 0x88F, 'AL'],\n [0x890, 0x891, 'AN'],\n [0x892, 0x896, 'AL'],\n [0x897, 0x89F, 'NSM'],\n [0x8A0, 0x8C9, 'AL'],\n [0x8CA, 0x8E1, 'NSM'],\n [0x8E2, 0x8E2, 'AN'],\n [0x8E3, 0x902, 'NSM'],\n [0x93A, 0x93A, 'NSM'],\n [0x93C, 0x93C, 'NSM'],\n [0x941, 0x948, 'NSM'],\n [0x94D, 0x94D, 'NSM'],\n [0x951, 0x957, 'NSM'],\n [0x962, 0x963, 'NSM'],\n [0x981, 0x981, 'NSM'],\n [0x9BC, 0x9BC, 'NSM'],\n [0x9C1, 0x9C4, 'NSM'],\n [0x9CD, 0x9CD, 'NSM'],\n [0x9E2, 0x9E3, 'NSM'],\n [0x9F2, 0x9F3, 'ET'],\n [0x9FB, 0x9FB, 'ET'],\n [0x9FE, 0x9FE, 'NSM'],\n [0xA01, 0xA02, 'NSM'],\n [0xA3C, 0xA3C, 'NSM'],\n [0xA41, 0xA42, 'NSM'],\n [0xA47, 0xA48, 'NSM'],\n [0xA4B, 0xA4D, 'NSM'],\n [0xA51, 0xA51, 'NSM'],\n [0xA70, 0xA71, 'NSM'],\n [0xA75, 0xA75, 'NSM'],\n [0xA81, 0xA82, 'NSM'],\n [0xABC, 0xABC, 'NSM'],\n [0xAC1, 0xAC5, 'NSM'],\n [0xAC7, 0xAC8, 'NSM'],\n [0xACD, 0xACD, 'NSM'],\n [0xAE2, 0xAE3, 'NSM'],\n [0xAF1, 0xAF1, 'ET'],\n [0xAFA, 0xAFF, 'NSM'],\n [0xB01, 0xB01, 'NSM'],\n [0xB3C, 0xB3C, 'NSM'],\n [0xB3F, 0xB3F, 'NSM'],\n [0xB41, 0xB44, 'NSM'],\n [0xB4D, 0xB4D, 'NSM'],\n [0xB55, 0xB56, 'NSM'],\n [0xB62, 0xB63, 'NSM'],\n [0xB82, 0xB82, 'NSM'],\n [0xBC0, 0xBC0, 'NSM'],\n [0xBCD, 0xBCD, 'NSM'],\n [0xBF3, 0xBF8, 'ON'],\n [0xBF9, 0xBF9, 'ET'],\n [0xBFA, 0xBFA, 'ON'],\n [0xC00, 0xC00, 'NSM'],\n [0xC04, 0xC04, 'NSM'],\n [0xC3C, 0xC3C, 'NSM'],\n [0xC3E, 0xC40, 'NSM'],\n [0xC46, 0xC48, 'NSM'],\n [0xC4A, 0xC4D, 'NSM'],\n [0xC55, 0xC56, 'NSM'],\n [0xC62, 0xC63, 'NSM'],\n [0xC78, 0xC7E, 'ON'],\n [0xC81, 0xC81, 'NSM'],\n [0xCBC, 0xCBC, 'NSM'],\n [0xCCC, 0xCCD, 'NSM'],\n [0xCE2, 0xCE3, 'NSM'],\n [0xD00, 0xD01, 'NSM'],\n [0xD3B, 0xD3C, 'NSM'],\n [0xD41, 0xD44, 'NSM'],\n [0xD4D, 0xD4D, 'NSM'],\n [0xD62, 0xD63, 'NSM'],\n [0xD81, 0xD81, 'NSM'],\n [0xDCA, 0xDCA, 'NSM'],\n [0xDD2, 0xDD4, 'NSM'],\n [0xDD6, 0xDD6, 'NSM'],\n [0xE31, 0xE31, 'NSM'],\n [0xE34, 0xE3A, 'NSM'],\n [0xE3F, 0xE3F, 'ET'],\n [0xE47, 0xE4E, 'NSM'],\n [0xEB1, 0xEB1, 'NSM'],\n [0xEB4, 0xEBC, 'NSM'],\n [0xEC8, 0xECE, 'NSM'],\n [0xF18, 0xF19, 'NSM'],\n [0xF35, 0xF35, 'NSM'],\n [0xF37, 0xF37, 'NSM'],\n [0xF39, 0xF39, 'NSM'],\n [0xF3A, 0xF3D, 'ON'],\n [0xF71, 0xF7E, 'NSM'],\n [0xF80, 0xF84, 'NSM'],\n [0xF86, 0xF87, 'NSM'],\n [0xF8D, 0xF97, 'NSM'],\n [0xF99, 0xFBC, 'NSM'],\n [0xFC6, 0xFC6, 'NSM'],\n [0x102D, 0x1030, 'NSM'],\n [0x1032, 0x1037, 'NSM'],\n [0x1039, 0x103A, 'NSM'],\n [0x103D, 0x103E, 'NSM'],\n [0x1058, 0x1059, 'NSM'],\n [0x105E, 0x1060, 'NSM'],\n [0x1071, 0x1074, 'NSM'],\n [0x1082, 0x1082, 'NSM'],\n [0x1085, 0x1086, 'NSM'],\n [0x108D, 0x108D, 'NSM'],\n [0x109D, 0x109D, 'NSM'],\n [0x135D, 0x135F, 'NSM'],\n [0x1390, 0x1399, 'ON'],\n [0x1400, 0x1400, 'ON'],\n [0x1680, 0x1680, 'WS'],\n [0x169B, 0x169C, 'ON'],\n [0x1712, 0x1714, 'NSM'],\n [0x1732, 0x1733, 'NSM'],\n [0x1752, 0x1753, 'NSM'],\n [0x1772, 0x1773, 'NSM'],\n [0x17B4, 0x17B5, 'NSM'],\n [0x17B7, 0x17BD, 'NSM'],\n [0x17C6, 0x17C6, 'NSM'],\n [0x17C9, 0x17D3, 'NSM'],\n [0x17DB, 0x17DB, 'ET'],\n [0x17DD, 0x17DD, 'NSM'],\n [0x17F0, 0x17F9, 'ON'],\n [0x1800, 0x180A, 'ON'],\n [0x180B, 0x180D, 'NSM'],\n [0x180E, 0x180E, 'BN'],\n [0x180F, 0x180F, 'NSM'],\n [0x1885, 0x1886, 'NSM'],\n [0x18A9, 0x18A9, 'NSM'],\n [0x1920, 0x1922, 'NSM'],\n [0x1927, 0x1928, 'NSM'],\n [0x1932, 0x1932, 'NSM'],\n [0x1939, 0x193B, 'NSM'],\n [0x1940, 0x1940, 'ON'],\n [0x1944, 0x1945, 'ON'],\n [0x19DE, 0x19FF, 'ON'],\n [0x1A17, 0x1A18, 'NSM'],\n [0x1A1B, 0x1A1B, 'NSM'],\n [0x1A56, 0x1A56, 'NSM'],\n [0x1A58, 0x1A5E, 'NSM'],\n [0x1A60, 0x1A60, 'NSM'],\n [0x1A62, 0x1A62, 'NSM'],\n [0x1A65, 0x1A6C, 'NSM'],\n [0x1A73, 0x1A7C, 'NSM'],\n [0x1A7F, 0x1A7F, 'NSM'],\n [0x1AB0, 0x1ADD, 'NSM'],\n [0x1AE0, 0x1AEB, 'NSM'],\n [0x1B00, 0x1B03, 'NSM'],\n [0x1B34, 0x1B34, 'NSM'],\n [0x1B36, 0x1B3A, 'NSM'],\n [0x1B3C, 0x1B3C, 'NSM'],\n [0x1B42, 0x1B42, 'NSM'],\n [0x1B6B, 0x1B73, 'NSM'],\n [0x1B80, 0x1B81, 'NSM'],\n [0x1BA2, 0x1BA5, 'NSM'],\n [0x1BA8, 0x1BA9, 'NSM'],\n [0x1BAB, 0x1BAD, 'NSM'],\n [0x1BE6, 0x1BE6, 'NSM'],\n [0x1BE8, 0x1BE9, 'NSM'],\n [0x1BED, 0x1BED, 'NSM'],\n [0x1BEF, 0x1BF1, 'NSM'],\n [0x1C2C, 0x1C33, 'NSM'],\n [0x1C36, 0x1C37, 'NSM'],\n [0x1CD0, 0x1CD2, 'NSM'],\n [0x1CD4, 0x1CE0, 'NSM'],\n [0x1CE2, 0x1CE8, 'NSM'],\n [0x1CED, 0x1CED, 'NSM'],\n [0x1CF4, 0x1CF4, 'NSM'],\n [0x1CF8, 0x1CF9, 'NSM'],\n [0x1DC0, 0x1DFF, 'NSM'],\n [0x1FBD, 0x1FBD, 'ON'],\n [0x1FBF, 0x1FC1, 'ON'],\n [0x1FCD, 0x1FCF, 'ON'],\n [0x1FDD, 0x1FDF, 'ON'],\n [0x1FED, 0x1FEF, 'ON'],\n [0x1FFD, 0x1FFE, 'ON'],\n [0x2000, 0x200A, 'WS'],\n [0x200B, 0x200D, 'BN'],\n [0x200F, 0x200F, 'R'],\n [0x2010, 0x2027, 'ON'],\n [0x2028, 0x2028, 'WS'],\n [0x2029, 0x2029, 'B'],\n [0x202A, 0x202E, 'BN'],\n [0x202F, 0x202F, 'CS'],\n [0x2030, 0x2034, 'ET'],\n [0x2035, 0x2043, 'ON'],\n [0x2044, 0x2044, 'CS'],\n [0x2045, 0x205E, 'ON'],\n [0x205F, 0x205F, 'WS'],\n [0x2060, 0x206F, 'BN'],\n [0x2070, 0x2070, 'EN'],\n [0x2074, 0x2079, 'EN'],\n [0x207A, 0x207B, 'ES'],\n [0x207C, 0x207E, 'ON'],\n [0x2080, 0x2089, 'EN'],\n [0x208A, 0x208B, 'ES'],\n [0x208C, 0x208E, 'ON'],\n [0x20A0, 0x20CF, 'ET'],\n [0x20D0, 0x20F0, 'NSM'],\n [0x2100, 0x2101, 'ON'],\n [0x2103, 0x2106, 'ON'],\n [0x2108, 0x2109, 'ON'],\n [0x2114, 0x2114, 'ON'],\n [0x2116, 0x2118, 'ON'],\n [0x211E, 0x2123, 'ON'],\n [0x2125, 0x2125, 'ON'],\n [0x2127, 0x2127, 'ON'],\n [0x2129, 0x2129, 'ON'],\n [0x212E, 0x212E, 'ET'],\n [0x213A, 0x213B, 'ON'],\n [0x2140, 0x2144, 'ON'],\n [0x214A, 0x214D, 'ON'],\n [0x2150, 0x215F, 'ON'],\n [0x2189, 0x218B, 'ON'],\n [0x2190, 0x2211, 'ON'],\n [0x2212, 0x2212, 'ES'],\n [0x2213, 0x2213, 'ET'],\n [0x2214, 0x2335, 'ON'],\n [0x237B, 0x2394, 'ON'],\n [0x2396, 0x2429, 'ON'],\n [0x2440, 0x244A, 'ON'],\n [0x2460, 0x2487, 'ON'],\n [0x2488, 0x249B, 'EN'],\n [0x24EA, 0x26AB, 'ON'],\n [0x26AD, 0x27FF, 'ON'],\n [0x2900, 0x2B73, 'ON'],\n [0x2B76, 0x2BFF, 'ON'],\n [0x2CE5, 0x2CEA, 'ON'],\n [0x2CEF, 0x2CF1, 'NSM'],\n [0x2CF9, 0x2CFF, 'ON'],\n [0x2D7F, 0x2D7F, 'NSM'],\n [0x2DE0, 0x2DFF, 'NSM'],\n [0x2E00, 0x2E5D, 'ON'],\n [0x2E80, 0x2E99, 'ON'],\n [0x2E9B, 0x2EF3, 'ON'],\n [0x2F00, 0x2FD5, 'ON'],\n [0x2FF0, 0x2FFF, 'ON'],\n [0x3000, 0x3000, 'WS'],\n [0x3001, 0x3004, 'ON'],\n [0x3008, 0x3020, 'ON'],\n [0x302A, 0x302D, 'NSM'],\n [0x3030, 0x3030, 'ON'],\n [0x3036, 0x3037, 'ON'],\n [0x303D, 0x303F, 'ON'],\n [0x3099, 0x309A, 'NSM'],\n [0x309B, 0x309C, 'ON'],\n [0x30A0, 0x30A0, 'ON'],\n [0x30FB, 0x30FB, 'ON'],\n [0x31C0, 0x31E5, 'ON'],\n [0x31EF, 0x31EF, 'ON'],\n [0x321D, 0x321E, 'ON'],\n [0x3250, 0x325F, 'ON'],\n [0x327C, 0x327E, 'ON'],\n [0x32B1, 0x32BF, 'ON'],\n [0x32CC, 0x32CF, 'ON'],\n [0x3377, 0x337A, 'ON'],\n [0x33DE, 0x33DF, 'ON'],\n [0x33FF, 0x33FF, 'ON'],\n [0x4DC0, 0x4DFF, 'ON'],\n [0xA490, 0xA4C6, 'ON'],\n [0xA60D, 0xA60F, 'ON'],\n [0xA66F, 0xA672, 'NSM'],\n [0xA673, 0xA673, 'ON'],\n [0xA674, 0xA67D, 'NSM'],\n [0xA67E, 0xA67F, 'ON'],\n [0xA69E, 0xA69F, 'NSM'],\n [0xA6F0, 0xA6F1, 'NSM'],\n [0xA700, 0xA721, 'ON'],\n [0xA788, 0xA788, 'ON'],\n [0xA802, 0xA802, 'NSM'],\n [0xA806, 0xA806, 'NSM'],\n [0xA80B, 0xA80B, 'NSM'],\n [0xA825, 0xA826, 'NSM'],\n [0xA828, 0xA82B, 'ON'],\n [0xA82C, 0xA82C, 'NSM'],\n [0xA838, 0xA839, 'ET'],\n [0xA874, 0xA877, 'ON'],\n [0xA8C4, 0xA8C5, 'NSM'],\n [0xA8E0, 0xA8F1, 'NSM'],\n [0xA8FF, 0xA8FF, 'NSM'],\n [0xA926, 0xA92D, 'NSM'],\n [0xA947, 0xA951, 'NSM'],\n [0xA980, 0xA982, 'NSM'],\n [0xA9B3, 0xA9B3, 'NSM'],\n [0xA9B6, 0xA9B9, 'NSM'],\n [0xA9BC, 0xA9BD, 'NSM'],\n [0xA9E5, 0xA9E5, 'NSM'],\n [0xAA29, 0xAA2E, 'NSM'],\n [0xAA31, 0xAA32, 'NSM'],\n [0xAA35, 0xAA36, 'NSM'],\n [0xAA43, 0xAA43, 'NSM'],\n [0xAA4C, 0xAA4C, 'NSM'],\n [0xAA7C, 0xAA7C, 'NSM'],\n [0xAAB0, 0xAAB0, 'NSM'],\n [0xAAB2, 0xAAB4, 'NSM'],\n [0xAAB7, 0xAAB8, 'NSM'],\n [0xAABE, 0xAABF, 'NSM'],\n [0xAAC1, 0xAAC1, 'NSM'],\n [0xAAEC, 0xAAED, 'NSM'],\n [0xAAF6, 0xAAF6, 'NSM'],\n [0xAB6A, 0xAB6B, 'ON'],\n [0xABE5, 0xABE5, 'NSM'],\n [0xABE8, 0xABE8, 'NSM'],\n [0xABED, 0xABED, 'NSM'],\n [0xFB1D, 0xFB1D, 'R'],\n [0xFB1E, 0xFB1E, 'NSM'],\n [0xFB1F, 0xFB28, 'R'],\n [0xFB29, 0xFB29, 'ES'],\n [0xFB2A, 0xFB4F, 'R'],\n [0xFB50, 0xFBC2, 'AL'],\n [0xFBC3, 0xFBD2, 'ON'],\n [0xFBD3, 0xFD3D, 'AL'],\n [0xFD3E, 0xFD4F, 'ON'],\n [0xFD50, 0xFD8F, 'AL'],\n [0xFD90, 0xFD91, 'ON'],\n [0xFD92, 0xFDC7, 'AL'],\n [0xFDC8, 0xFDCF, 'ON'],\n [0xFDD0, 0xFDEF, 'BN'],\n [0xFDF0, 0xFDFC, 'AL'],\n [0xFDFD, 0xFDFF, 'ON'],\n [0xFE00, 0xFE0F, 'NSM'],\n [0xFE10, 0xFE19, 'ON'],\n [0xFE20, 0xFE2F, 'NSM'],\n [0xFE30, 0xFE4F, 'ON'],\n [0xFE50, 0xFE50, 'CS'],\n [0xFE51, 0xFE51, 'ON'],\n [0xFE52, 0xFE52, 'CS'],\n [0xFE54, 0xFE54, 'ON'],\n [0xFE55, 0xFE55, 'CS'],\n [0xFE56, 0xFE5E, 'ON'],\n [0xFE5F, 0xFE5F, 'ET'],\n [0xFE60, 0xFE61, 'ON'],\n [0xFE62, 0xFE63, 'ES'],\n [0xFE64, 0xFE66, 'ON'],\n [0xFE68, 0xFE68, 'ON'],\n [0xFE69, 0xFE6A, 'ET'],\n [0xFE6B, 0xFE6B, 'ON'],\n [0xFE70, 0xFEFE, 'AL'],\n [0xFEFF, 0xFEFF, 'BN'],\n [0xFF01, 0xFF02, 'ON'],\n [0xFF03, 0xFF05, 'ET'],\n [0xFF06, 0xFF0A, 'ON'],\n [0xFF0B, 0xFF0B, 'ES'],\n [0xFF0C, 0xFF0C, 'CS'],\n [0xFF0D, 0xFF0D, 'ES'],\n [0xFF0E, 0xFF0F, 'CS'],\n [0xFF10, 0xFF19, 'EN'],\n [0xFF1A, 0xFF1A, 'CS'],\n [0xFF1B, 0xFF20, 'ON'],\n [0xFF3B, 0xFF40, 'ON'],\n [0xFF5B, 0xFF65, 'ON'],\n [0xFFE0, 0xFFE1, 'ET'],\n [0xFFE2, 0xFFE4, 'ON'],\n [0xFFE5, 0xFFE6, 'ET'],\n [0xFFE8, 0xFFEE, 'ON'],\n [0xFFF0, 0xFFF8, 'BN'],\n [0xFFF9, 0xFFFD, 'ON'],\n [0xFFFE, 0xFFFF, 'BN'],\n [0x10101, 0x10101, 'ON'],\n [0x10140, 0x1018C, 'ON'],\n [0x10190, 0x1019C, 'ON'],\n [0x101A0, 0x101A0, 'ON'],\n [0x101FD, 0x101FD, 'NSM'],\n [0x102E0, 0x102E0, 'NSM'],\n [0x102E1, 0x102FB, 'EN'],\n [0x10376, 0x1037A, 'NSM'],\n [0x10800, 0x1091E, 'R'],\n [0x1091F, 0x1091F, 'ON'],\n [0x10920, 0x10A00, 'R'],\n [0x10A01, 0x10A03, 'NSM'],\n [0x10A04, 0x10A04, 'R'],\n [0x10A05, 0x10A06, 'NSM'],\n [0x10A07, 0x10A0B, 'R'],\n [0x10A0C, 0x10A0F, 'NSM'],\n [0x10A10, 0x10A37, 'R'],\n [0x10A38, 0x10A3A, 'NSM'],\n [0x10A3B, 0x10A3E, 'R'],\n [0x10A3F, 0x10A3F, 'NSM'],\n [0x10A40, 0x10AE4, 'R'],\n [0x10AE5, 0x10AE6, 'NSM'],\n [0x10AE7, 0x10B38, 'R'],\n [0x10B39, 0x10B3F, 'ON'],\n [0x10B40, 0x10CFF, 'R'],\n [0x10D00, 0x10D23, 'AL'],\n [0x10D24, 0x10D27, 'NSM'],\n [0x10D28, 0x10D2F, 'AL'],\n [0x10D30, 0x10D39, 'AN'],\n [0x10D3A, 0x10D3F, 'AL'],\n [0x10D40, 0x10D49, 'AN'],\n [0x10D4A, 0x10D68, 'R'],\n [0x10D69, 0x10D6D, 'NSM'],\n [0x10D6E, 0x10D6E, 'ON'],\n [0x10D6F, 0x10E5F, 'R'],\n [0x10E60, 0x10E7E, 'AN'],\n [0x10E7F, 0x10EAA, 'R'],\n [0x10EAB, 0x10EAC, 'NSM'],\n [0x10EAD, 0x10EBF, 'R'],\n [0x10EC0, 0x10ECF, 'AL'],\n [0x10ED0, 0x10ED8, 'ON'],\n [0x10ED9, 0x10EF9, 'AL'],\n [0x10EFA, 0x10EFF, 'NSM'],\n [0x10F00, 0x10F2F, 'R'],\n [0x10F30, 0x10F45, 'AL'],\n [0x10F46, 0x10F50, 'NSM'],\n [0x10F51, 0x10F6F, 'AL'],\n [0x10F70, 0x10F81, 'R'],\n [0x10F82, 0x10F85, 'NSM'],\n [0x10F86, 0x10FFF, 'R'],\n [0x11001, 0x11001, 'NSM'],\n [0x11038, 0x11046, 'NSM'],\n [0x11052, 0x11065, 'ON'],\n [0x11070, 0x11070, 'NSM'],\n [0x11073, 0x11074, 'NSM'],\n [0x1107F, 0x11081, 'NSM'],\n [0x110B3, 0x110B6, 'NSM'],\n [0x110B9, 0x110BA, 'NSM'],\n [0x110C2, 0x110C2, 'NSM'],\n [0x11100, 0x11102, 'NSM'],\n [0x11127, 0x1112B, 'NSM'],\n [0x1112D, 0x11134, 'NSM'],\n [0x11173, 0x11173, 'NSM'],\n [0x11180, 0x11181, 'NSM'],\n [0x111B6, 0x111BE, 'NSM'],\n [0x111C9, 0x111CC, 'NSM'],\n [0x111CF, 0x111CF, 'NSM'],\n [0x1122F, 0x11231, 'NSM'],\n [0x11234, 0x11234, 'NSM'],\n [0x11236, 0x11237, 'NSM'],\n [0x1123E, 0x1123E, 'NSM'],\n [0x11241, 0x11241, 'NSM'],\n [0x112DF, 0x112DF, 'NSM'],\n [0x112E3, 0x112EA, 'NSM'],\n [0x11300, 0x11301, 'NSM'],\n [0x1133B, 0x1133C, 'NSM'],\n [0x11340, 0x11340, 'NSM'],\n [0x11366, 0x1136C, 'NSM'],\n [0x11370, 0x11374, 'NSM'],\n [0x113BB, 0x113C0, 'NSM'],\n [0x113CE, 0x113CE, 'NSM'],\n [0x113D0, 0x113D0, 'NSM'],\n [0x113D2, 0x113D2, 'NSM'],\n [0x113E1, 0x113E2, 'NSM'],\n [0x11438, 0x1143F, 'NSM'],\n [0x11442, 0x11444, 'NSM'],\n [0x11446, 0x11446, 'NSM'],\n [0x1145E, 0x1145E, 'NSM'],\n [0x114B3, 0x114B8, 'NSM'],\n [0x114BA, 0x114BA, 'NSM'],\n [0x114BF, 0x114C0, 'NSM'],\n [0x114C2, 0x114C3, 'NSM'],\n [0x115B2, 0x115B5, 'NSM'],\n [0x115BC, 0x115BD, 'NSM'],\n [0x115BF, 0x115C0, 'NSM'],\n [0x115DC, 0x115DD, 'NSM'],\n [0x11633, 0x1163A, 'NSM'],\n [0x1163D, 0x1163D, 'NSM'],\n [0x1163F, 0x11640, 'NSM'],\n [0x11660, 0x1166C, 'ON'],\n [0x116AB, 0x116AB, 'NSM'],\n [0x116AD, 0x116AD, 'NSM'],\n [0x116B0, 0x116B5, 'NSM'],\n [0x116B7, 0x116B7, 'NSM'],\n [0x1171D, 0x1171D, 'NSM'],\n [0x1171F, 0x1171F, 'NSM'],\n [0x11722, 0x11725, 'NSM'],\n [0x11727, 0x1172B, 'NSM'],\n [0x1182F, 0x11837, 'NSM'],\n [0x11839, 0x1183A, 'NSM'],\n [0x1193B, 0x1193C, 'NSM'],\n [0x1193E, 0x1193E, 'NSM'],\n [0x11943, 0x11943, 'NSM'],\n [0x119D4, 0x119D7, 'NSM'],\n [0x119DA, 0x119DB, 'NSM'],\n [0x119E0, 0x119E0, 'NSM'],\n [0x11A01, 0x11A06, 'NSM'],\n [0x11A09, 0x11A0A, 'NSM'],\n [0x11A33, 0x11A38, 'NSM'],\n [0x11A3B, 0x11A3E, 'NSM'],\n [0x11A47, 0x11A47, 'NSM'],\n [0x11A51, 0x11A56, 'NSM'],\n [0x11A59, 0x11A5B, 'NSM'],\n [0x11A8A, 0x11A96, 'NSM'],\n [0x11A98, 0x11A99, 'NSM'],\n [0x11B60, 0x11B60, 'NSM'],\n [0x11B62, 0x11B64, 'NSM'],\n [0x11B66, 0x11B66, 'NSM'],\n [0x11C30, 0x11C36, 'NSM'],\n [0x11C38, 0x11C3D, 'NSM'],\n [0x11C92, 0x11CA7, 'NSM'],\n [0x11CAA, 0x11CB0, 'NSM'],\n [0x11CB2, 0x11CB3, 'NSM'],\n [0x11CB5, 0x11CB6, 'NSM'],\n [0x11D31, 0x11D36, 'NSM'],\n [0x11D3A, 0x11D3A, 'NSM'],\n [0x11D3C, 0x11D3D, 'NSM'],\n [0x11D3F, 0x11D45, 'NSM'],\n [0x11D47, 0x11D47, 'NSM'],\n [0x11D90, 0x11D91, 'NSM'],\n [0x11D95, 0x11D95, 'NSM'],\n [0x11D97, 0x11D97, 'NSM'],\n [0x11EF3, 0x11EF4, 'NSM'],\n [0x11F00, 0x11F01, 'NSM'],\n [0x11F36, 0x11F3A, 'NSM'],\n [0x11F40, 0x11F40, 'NSM'],\n [0x11F42, 0x11F42, 'NSM'],\n [0x11F5A, 0x11F5A, 'NSM'],\n [0x11FD5, 0x11FDC, 'ON'],\n [0x11FDD, 0x11FE0, 'ET'],\n [0x11FE1, 0x11FF1, 'ON'],\n [0x13440, 0x13440, 'NSM'],\n [0x13447, 0x13455, 'NSM'],\n [0x1611E, 0x16129, 'NSM'],\n [0x1612D, 0x1612F, 'NSM'],\n [0x16AF0, 0x16AF4, 'NSM'],\n [0x16B30, 0x16B36, 'NSM'],\n [0x16F4F, 0x16F4F, 'NSM'],\n [0x16F8F, 0x16F92, 'NSM'],\n [0x16FE2, 0x16FE2, 'ON'],\n [0x16FE4, 0x16FE4, 'NSM'],\n [0x1BC9D, 0x1BC9E, 'NSM'],\n [0x1BCA0, 0x1BCA3, 'BN'],\n [0x1CC00, 0x1CCD5, 'ON'],\n [0x1CCF0, 0x1CCF9, 'EN'],\n [0x1CCFA, 0x1CCFC, 'ON'],\n [0x1CD00, 0x1CEB3, 'ON'],\n [0x1CEBA, 0x1CED0, 'ON'],\n [0x1CEE0, 0x1CEF0, 'ON'],\n [0x1CF00, 0x1CF2D, 'NSM'],\n [0x1CF30, 0x1CF46, 'NSM'],\n [0x1D167, 0x1D169, 'NSM'],\n [0x1D173, 0x1D17A, 'BN'],\n [0x1D17B, 0x1D182, 'NSM'],\n [0x1D185, 0x1D18B, 'NSM'],\n [0x1D1AA, 0x1D1AD, 'NSM'],\n [0x1D1E9, 0x1D1EA, 'ON'],\n [0x1D200, 0x1D241, 'ON'],\n [0x1D242, 0x1D244, 'NSM'],\n [0x1D245, 0x1D245, 'ON'],\n [0x1D300, 0x1D356, 'ON'],\n [0x1D6C1, 0x1D6C1, 'ON'],\n [0x1D6DB, 0x1D6DB, 'ON'],\n [0x1D6FB, 0x1D6FB, 'ON'],\n [0x1D715, 0x1D715, 'ON'],\n [0x1D735, 0x1D735, 'ON'],\n [0x1D74F, 0x1D74F, 'ON'],\n [0x1D76F, 0x1D76F, 'ON'],\n [0x1D789, 0x1D789, 'ON'],\n [0x1D7A9, 0x1D7A9, 'ON'],\n [0x1D7C3, 0x1D7C3, 'ON'],\n [0x1D7CE, 0x1D7FF, 'EN'],\n [0x1DA00, 0x1DA36, 'NSM'],\n [0x1DA3B, 0x1DA6C, 'NSM'],\n [0x1DA75, 0x1DA75, 'NSM'],\n [0x1DA84, 0x1DA84, 'NSM'],\n [0x1DA9B, 0x1DA9F, 'NSM'],\n [0x1DAA1, 0x1DAAF, 'NSM'],\n [0x1E000, 0x1E006, 'NSM'],\n [0x1E008, 0x1E018, 'NSM'],\n [0x1E01B, 0x1E021, 'NSM'],\n [0x1E023, 0x1E024, 'NSM'],\n [0x1E026, 0x1E02A, 'NSM'],\n [0x1E08F, 0x1E08F, 'NSM'],\n [0x1E130, 0x1E136, 'NSM'],\n [0x1E2AE, 0x1E2AE, 'NSM'],\n [0x1E2EC, 0x1E2EF, 'NSM'],\n [0x1E2FF, 0x1E2FF, 'ET'],\n [0x1E4EC, 0x1E4EF, 'NSM'],\n [0x1E5EE, 0x1E5EF, 'NSM'],\n [0x1E6E3, 0x1E6E3, 'NSM'],\n [0x1E6E6, 0x1E6E6, 'NSM'],\n [0x1E6EE, 0x1E6EF, 'NSM'],\n [0x1E6F5, 0x1E6F5, 'NSM'],\n [0x1E800, 0x1E8CF, 'R'],\n [0x1E8D0, 0x1E8D6, 'NSM'],\n [0x1E8D7, 0x1E943, 'R'],\n [0x1E944, 0x1E94A, 'NSM'],\n [0x1E94B, 0x1EC6F, 'R'],\n [0x1EC70, 0x1ECBF, 'AL'],\n [0x1ECC0, 0x1ECFF, 'R'],\n [0x1ED00, 0x1ED4F, 'AL'],\n [0x1ED50, 0x1EDFF, 'R'],\n [0x1EE00, 0x1EEEF, 'AL'],\n [0x1EEF0, 0x1EEF1, 'ON'],\n [0x1EEF2, 0x1EEFF, 'AL'],\n [0x1EF00, 0x1EFFF, 'R'],\n [0x1F000, 0x1F02B, 'ON'],\n [0x1F030, 0x1F093, 'ON'],\n [0x1F0A0, 0x1F0AE, 'ON'],\n [0x1F0B1, 0x1F0BF, 'ON'],\n [0x1F0C1, 0x1F0CF, 'ON'],\n [0x1F0D1, 0x1F0F5, 'ON'],\n [0x1F100, 0x1F10A, 'EN'],\n [0x1F10B, 0x1F10F, 'ON'],\n [0x1F12F, 0x1F12F, 'ON'],\n [0x1F16A, 0x1F16F, 'ON'],\n [0x1F1AD, 0x1F1AD, 'ON'],\n [0x1F260, 0x1F265, 'ON'],\n [0x1F300, 0x1F6D8, 'ON'],\n [0x1F6DC, 0x1F6EC, 'ON'],\n [0x1F6F0, 0x1F6FC, 'ON'],\n [0x1F700, 0x1F7D9, 'ON'],\n [0x1F7E0, 0x1F7EB, 'ON'],\n [0x1F7F0, 0x1F7F0, 'ON'],\n [0x1F800, 0x1F80B, 'ON'],\n [0x1F810, 0x1F847, 'ON'],\n [0x1F850, 0x1F859, 'ON'],\n [0x1F860, 0x1F887, 'ON'],\n [0x1F890, 0x1F8AD, 'ON'],\n [0x1F8B0, 0x1F8BB, 'ON'],\n [0x1F8C0, 0x1F8C1, 'ON'],\n [0x1F8D0, 0x1F8D8, 'ON'],\n [0x1F900, 0x1FA57, 'ON'],\n [0x1FA60, 0x1FA6D, 'ON'],\n [0x1FA70, 0x1FA7C, 'ON'],\n [0x1FA80, 0x1FA8A, 'ON'],\n [0x1FA8E, 0x1FAC6, 'ON'],\n [0x1FAC8, 0x1FAC8, 'ON'],\n [0x1FACD, 0x1FADC, 'ON'],\n [0x1FADF, 0x1FAEA, 'ON'],\n [0x1FAEF, 0x1FAF8, 'ON'],\n [0x1FB00, 0x1FB92, 'ON'],\n [0x1FB94, 0x1FBEF, 'ON'],\n [0x1FBF0, 0x1FBF9, 'EN'],\n [0x1FBFA, 0x1FBFA, 'ON'],\n [0x1FFFE, 0x1FFFF, 'BN'],\n [0x2FFFE, 0x2FFFF, 'BN'],\n [0x3FFFE, 0x3FFFF, 'BN'],\n [0x4FFFE, 0x4FFFF, 'BN'],\n [0x5FFFE, 0x5FFFF, 'BN'],\n [0x6FFFE, 0x6FFFF, 'BN'],\n [0x7FFFE, 0x7FFFF, 'BN'],\n [0x8FFFE, 0x8FFFF, 'BN'],\n [0x9FFFE, 0x9FFFF, 'BN'],\n [0xAFFFE, 0xAFFFF, 'BN'],\n [0xBFFFE, 0xBFFFF, 'BN'],\n [0xCFFFE, 0xCFFFF, 'BN'],\n [0xDFFFE, 0xE00FF, 'BN'],\n [0xE0100, 0xE01EF, 'NSM'],\n [0xE01F0, 0xE0FFF, 'BN'],\n [0xEFFFE, 0xEFFFF, 'BN'],\n [0xFFFFE, 0xFFFFF, 'BN'],\n [0x10FFFE, 0x10FFFF, 'BN'],\n];\n", "// Simplified bidi metadata helper for the rich prepareWithSegments() path,\n// forked from pdf.js via Sebastian's text-layout. It classifies characters\n// into bidi types, computes embedding levels, and maps them onto prepared\n// segments for custom rendering. The line-breaking engine does not consume\n// these levels.\nimport { latin1BidiTypes, nonLatin1BidiRanges, } from './generated/bidi-data.js';\nfunction classifyCodePoint(codePoint) {\n if (codePoint <= 0x00FF)\n return latin1BidiTypes[codePoint];\n let lo = 0;\n let hi = nonLatin1BidiRanges.length - 1;\n while (lo <= hi) {\n const mid = (lo + hi) >> 1;\n const range = nonLatin1BidiRanges[mid];\n if (codePoint < range[0]) {\n hi = mid - 1;\n continue;\n }\n if (codePoint > range[1]) {\n lo = mid + 1;\n continue;\n }\n return range[2];\n }\n return 'L';\n}\nfunction computeBidiLevels(str, baseLevel) {\n const len = str.length;\n if (len === 0)\n return null;\n // eslint-disable-next-line unicorn/no-new-array\n const types = new Array(len);\n let sawBidi = false;\n // Keep the resolved bidi classes aligned to UTF-16 code-unit offsets,\n // because the rich prepared segments index back into the normalized string\n // with JavaScript string offsets.\n for (let i = 0; i < len;) {\n const first = str.charCodeAt(i);\n let codePoint = first;\n let codeUnitLength = 1;\n if (first >= 0xD800 && first <= 0xDBFF && i + 1 < len) {\n const second = str.charCodeAt(i + 1);\n if (second >= 0xDC00 && second <= 0xDFFF) {\n codePoint = ((first - 0xD800) << 10) + (second - 0xDC00) + 0x10000;\n codeUnitLength = 2;\n }\n }\n const t = classifyCodePoint(codePoint);\n if (t === 'R' || t === 'AL' || t === 'AN')\n sawBidi = true;\n for (let j = 0; j < codeUnitLength; j++) {\n types[i + j] = t;\n }\n i += codeUnitLength;\n }\n if (!sawBidi)\n return null;\n // Base direction: an explicit override (canvas-word /pretext-patch: Word's\n // w:bidi forces the paragraph base regardless of the first strong char) takes\n // precedence; otherwise use the first strong character (the common UBA P2/P3\n // paragraph rule). Rich-path bidi metadata is only an approximation.\n let startLevel = baseLevel === 0 || baseLevel === 1 ? baseLevel : 0;\n if (baseLevel !== 0 && baseLevel !== 1) {\n for (let i = 0; i < len; i++) {\n const t = types[i];\n if (t === 'L') {\n startLevel = 0;\n break;\n }\n if (t === 'R' || t === 'AL') {\n startLevel = 1;\n break;\n }\n }\n }\n const levels = new Int8Array(len);\n for (let i = 0; i < len; i++)\n levels[i] = startLevel;\n const e = (startLevel & 1) ? 'R' : 'L';\n const sor = e;\n // W1-W7\n let lastType = sor;\n for (let i = 0; i < len; i++) {\n if (types[i] === 'NSM')\n types[i] = lastType;\n else\n lastType = types[i];\n }\n lastType = sor;\n for (let i = 0; i < len; i++) {\n const t = types[i];\n if (t === 'EN')\n types[i] = lastType === 'AL' ? 'AN' : 'EN';\n else if (t === 'R' || t === 'L' || t === 'AL')\n lastType = t;\n }\n for (let i = 0; i < len; i++) {\n if (types[i] === 'AL')\n types[i] = 'R';\n }\n for (let i = 1; i < len - 1; i++) {\n if (types[i] === 'ES' && types[i - 1] === 'EN' && types[i + 1] === 'EN') {\n types[i] = 'EN';\n }\n if (types[i] === 'CS' &&\n (types[i - 1] === 'EN' || types[i - 1] === 'AN') &&\n types[i + 1] === types[i - 1]) {\n types[i] = types[i - 1];\n }\n }\n for (let i = 0; i < len; i++) {\n if (types[i] !== 'EN')\n continue;\n let j;\n for (j = i - 1; j >= 0 && types[j] === 'ET'; j--)\n types[j] = 'EN';\n for (j = i + 1; j < len && types[j] === 'ET'; j++)\n types[j] = 'EN';\n }\n for (let i = 0; i < len; i++) {\n const t = types[i];\n if (t === 'WS' || t === 'ES' || t === 'ET' || t === 'CS')\n types[i] = 'ON';\n }\n lastType = sor;\n for (let i = 0; i < len; i++) {\n const t = types[i];\n if (t === 'EN')\n types[i] = lastType === 'L' ? 'L' : 'EN';\n else if (t === 'R' || t === 'L')\n lastType = t;\n }\n // N1-N2\n for (let i = 0; i < len; i++) {\n if (types[i] !== 'ON')\n continue;\n let end = i + 1;\n while (end < len && types[end] === 'ON')\n end++;\n const before = i > 0 ? types[i - 1] : sor;\n const after = end < len ? types[end] : sor;\n const bDir = before !== 'L' ? 'R' : 'L';\n const aDir = after !== 'L' ? 'R' : 'L';\n if (bDir === aDir) {\n for (let j = i; j < end; j++)\n types[j] = bDir;\n }\n i = end - 1;\n }\n for (let i = 0; i < len; i++) {\n if (types[i] === 'ON')\n types[i] = e;\n }\n // I1-I2\n for (let i = 0; i < len; i++) {\n const t = types[i];\n if ((levels[i] & 1) === 0) {\n if (t === 'R')\n levels[i]++;\n else if (t === 'AN' || t === 'EN')\n levels[i] += 2;\n }\n else if (t === 'L' || t === 'AN' || t === 'EN') {\n levels[i]++;\n }\n }\n return levels;\n}\nexport function computeSegmentLevels(normalized, segStarts, baseLevel) {\n const bidiLevels = computeBidiLevels(normalized, baseLevel);\n if (bidiLevels === null)\n return null;\n const segLevels = new Int8Array(segStarts.length);\n for (let i = 0; i < segStarts.length; i++) {\n segLevels[i] = bidiLevels[segStarts[i]];\n }\n return segLevels;\n}\n", "const collapsibleWhitespaceRunRe = /[ \\t\\n\\r\\f]+/g;\nconst needsWhitespaceNormalizationRe = /[\\t\\n\\r\\f]| {2,}|^ | $/;\nfunction getWhiteSpaceProfile(whiteSpace) {\n const mode = whiteSpace ?? 'normal';\n return mode === 'pre-wrap'\n ? { mode, preserveOrdinarySpaces: true, preserveHardBreaks: true }\n : { mode, preserveOrdinarySpaces: false, preserveHardBreaks: false };\n}\nexport function normalizeWhitespaceNormal(text) {\n if (!needsWhitespaceNormalizationRe.test(text))\n return text;\n let normalized = text.replace(collapsibleWhitespaceRunRe, ' ');\n if (normalized.charCodeAt(0) === 0x20) {\n normalized = normalized.slice(1);\n }\n if (normalized.length > 0 && normalized.charCodeAt(normalized.length - 1) === 0x20) {\n normalized = normalized.slice(0, -1);\n }\n return normalized;\n}\nfunction normalizeWhitespacePreWrap(text) {\n if (!/[\\r\\f]/.test(text))\n return text;\n return text\n .replace(/\\r\\n/g, '\\n')\n .replace(/[\\r\\f]/g, '\\n');\n}\nlet sharedWordSegmenter = null;\nlet segmenterLocale;\nfunction getSharedWordSegmenter() {\n if (sharedWordSegmenter === null) {\n sharedWordSegmenter = new Intl.Segmenter(segmenterLocale, { granularity: 'word' });\n }\n return sharedWordSegmenter;\n}\nexport function clearAnalysisCaches() {\n sharedWordSegmenter = null;\n}\nexport function setAnalysisLocale(locale) {\n const nextLocale = locale && locale.length > 0 ? locale : undefined;\n if (segmenterLocale === nextLocale)\n return;\n segmenterLocale = nextLocale;\n sharedWordSegmenter = null;\n}\nconst arabicScriptRe = /\\p{Script=Arabic}/u;\nconst combiningMarkRe = /\\p{M}/u;\nconst decimalDigitRe = /\\p{Nd}/u;\nfunction containsArabicScript(text) {\n return arabicScriptRe.test(text);\n}\nfunction isCJKCodePoint(codePoint) {\n return ((codePoint >= 0x4E00 && codePoint <= 0x9FFF) ||\n (codePoint >= 0x3400 && codePoint <= 0x4DBF) ||\n (codePoint >= 0x20000 && codePoint <= 0x2A6DF) ||\n (codePoint >= 0x2A700 && codePoint <= 0x2B73F) ||\n (codePoint >= 0x2B740 && codePoint <= 0x2B81F) ||\n (codePoint >= 0x2B820 && codePoint <= 0x2CEAF) ||\n (codePoint >= 0x2CEB0 && codePoint <= 0x2EBEF) ||\n (codePoint >= 0x2EBF0 && codePoint <= 0x2EE5D) ||\n (codePoint >= 0x2F800 && codePoint <= 0x2FA1F) ||\n (codePoint >= 0x30000 && codePoint <= 0x3134F) ||\n (codePoint >= 0x31350 && codePoint <= 0x323AF) ||\n (codePoint >= 0x323B0 && codePoint <= 0x33479) ||\n (codePoint >= 0xF900 && codePoint <= 0xFAFF) ||\n (codePoint >= 0x3000 && codePoint <= 0x303F) ||\n (codePoint >= 0x3040 && codePoint <= 0x309F) ||\n (codePoint >= 0x30A0 && codePoint <= 0x30FF) ||\n (codePoint >= 0x3130 && codePoint <= 0x318F) ||\n (codePoint >= 0xAC00 && codePoint <= 0xD7AF) ||\n (codePoint >= 0xFF00 && codePoint <= 0xFFEF));\n}\nexport function isCJK(s) {\n for (let i = 0; i < s.length; i++) {\n const first = s.charCodeAt(i);\n if (first < 0x3000)\n continue;\n if (first >= 0xD800 && first <= 0xDBFF && i + 1 < s.length) {\n const second = s.charCodeAt(i + 1);\n if (second >= 0xDC00 && second <= 0xDFFF) {\n const codePoint = ((first - 0xD800) << 10) + (second - 0xDC00) + 0x10000;\n if (isCJKCodePoint(codePoint))\n return true;\n i++;\n continue;\n }\n }\n if (isCJKCodePoint(first))\n return true;\n }\n return false;\n}\nfunction endsWithLineStartProhibitedText(text) {\n const last = getLastCodePoint(text);\n return last !== null && (kinsokuStart.has(last) || leftStickyPunctuation.has(last));\n}\nconst keepAllGlueChars = new Set([\n '\\u00A0',\n '\\u202F',\n '\\u2060',\n '\\uFEFF',\n]);\nconst keepAllDashBreakChars = new Set([\n '-',\n '\\u2010',\n '\\u2013',\n '\\u2014',\n]);\nfunction endsWithKeepAllGlueText(text) {\n const last = getLastCodePoint(text);\n return last !== null && keepAllGlueChars.has(last);\n}\nfunction endsWithKeepAllDashBreakText(text) {\n const last = getLastCodePoint(text);\n return last !== null && keepAllDashBreakChars.has(last);\n}\nexport function canContinueKeepAllTextRun(previousText, breakAfterPunctuation) {\n if (endsWithKeepAllGlueText(previousText))\n return false;\n if (!breakAfterPunctuation)\n return true;\n if (endsWithLineStartProhibitedText(previousText))\n return false;\n if (endsWithKeepAllDashBreakText(previousText))\n return false;\n return true;\n}\nexport const kinsokuStart = new Set([\n '\\uFF0C',\n '\\uFF0E',\n '\\uFF01',\n '\\uFF1A',\n '\\uFF1B',\n '\\uFF1F',\n '\\u3001',\n '\\u3002',\n '\\u30FB',\n '\\uFF09',\n '\\u3015',\n '\\u3009',\n '\\u300B',\n '\\u300D',\n '\\u300F',\n '\\u3011',\n '\\u3017',\n '\\u3019',\n '\\u301B',\n '\\u30FC',\n '\\u3005',\n '\\u303B',\n '\\u309D',\n '\\u309E',\n '\\u30FD',\n '\\u30FE',\n]);\nexport const kinsokuEnd = new Set([\n '\"',\n '(', '[', '{',\n '\u00A1', '\u00BF',\n '\u201C', '\u2018', '\u201A', '\u201E', '\u00AB', '\u2039',\n '\\u2E18',\n '\\uFF08',\n '\\u3014',\n '\\u3008',\n '\\u300A',\n '\\u300C',\n '\\u300E',\n '\\u3010',\n '\\u3016',\n '\\u3018',\n '\\u301A',\n]);\nconst forwardStickyGlue = new Set([\n \"'\", '\u2019',\n]);\nexport const leftStickyPunctuation = new Set([\n '.', ',', '!', '?', ':', ';',\n '\\u060C',\n '\\u061B',\n '\\u061F',\n '\\u0964',\n '\\u0965',\n '\\u104A',\n '\\u104B',\n '\\u104C',\n '\\u104D',\n '\\u104F',\n ')', ']', '}',\n '%',\n '\"',\n '\u201D', '\u2019', '\u00BB', '\u203A',\n '\u2026',\n]);\nconst arabicNoSpaceTrailingPunctuation = new Set([\n ':',\n '.',\n '\\u060C',\n '\\u061B',\n]);\nconst myanmarMedialGlue = new Set([\n '\\u104F',\n]);\nconst closingQuoteChars = new Set([\n '\u201D', '\u2019', '\u00BB', '\u203A',\n '\\u300D',\n '\\u300F',\n '\\u3011',\n '\\u300B',\n '\\u3009',\n '\\u3015',\n '\\uFF09',\n]);\nfunction isLeftStickyPunctuationSegment(segment) {\n if (isEscapedQuoteClusterSegment(segment))\n return true;\n let sawPunctuation = false;\n for (const ch of segment) {\n if (leftStickyPunctuation.has(ch) || isLineBreakNumericAffix(ch)) {\n sawPunctuation = true;\n continue;\n }\n if (sawPunctuation && combiningMarkRe.test(ch))\n continue;\n return false;\n }\n return sawPunctuation;\n}\nfunction isCJKLineStartProhibitedSegment(segment) {\n for (const ch of segment) {\n if (!kinsokuStart.has(ch) && !leftStickyPunctuation.has(ch))\n return false;\n }\n return segment.length > 0;\n}\nfunction isForwardStickyClusterSegment(segment) {\n if (isEscapedQuoteClusterSegment(segment))\n return true;\n for (const ch of segment) {\n if (!kinsokuEnd.has(ch) &&\n !forwardStickyGlue.has(ch) &&\n !combiningMarkRe.test(ch) &&\n !isLineBreakNumericAffix(ch)) {\n return false;\n }\n }\n return segment.length > 0;\n}\nfunction isEscapedQuoteClusterSegment(segment) {\n let sawQuote = false;\n for (const ch of segment) {\n if (ch === '\\\\' || combiningMarkRe.test(ch))\n continue;\n if (kinsokuEnd.has(ch) || leftStickyPunctuation.has(ch) || forwardStickyGlue.has(ch)) {\n sawQuote = true;\n continue;\n }\n return false;\n }\n return sawQuote;\n}\nfunction previousCodePointStart(text, end) {\n const last = end - 1;\n if (last <= 0)\n return Math.max(last, 0);\n const lastCodeUnit = text.charCodeAt(last);\n if (lastCodeUnit < 0xDC00 || lastCodeUnit > 0xDFFF)\n return last;\n const maybeHigh = last - 1;\n if (maybeHigh < 0)\n return last;\n const highCodeUnit = text.charCodeAt(maybeHigh);\n return highCodeUnit >= 0xD800 && highCodeUnit <= 0xDBFF ? maybeHigh : last;\n}\nfunction getLastCodePoint(text) {\n if (text.length === 0)\n return null;\n const start = previousCodePointStart(text, text.length);\n return text.slice(start);\n}\nfunction getFirstSignificantCodePoint(text) {\n for (const ch of text) {\n if (!combiningMarkRe.test(ch))\n return ch;\n }\n return null;\n}\nfunction getLastSignificantCodePoint(text) {\n for (let end = text.length; end > 0;) {\n const start = previousCodePointStart(text, end);\n const ch = text.slice(start, end);\n if (!combiningMarkRe.test(ch))\n return ch;\n end = start;\n }\n return null;\n}\n// Unicode line-break PR/PO classes from UAX #14, stored as start/end pairs.\nconst lineBreakNumericAffixRanges = [\n 0x0024, 0x0025, 0x002B, 0x002B, 0x005C, 0x005C, 0x00A2, 0x00A5, 0x00B0, 0x00B1,\n 0x058F, 0x058F, 0x0609, 0x060B, 0x066A, 0x066A, 0x07FE, 0x07FF, 0x09F2, 0x09F3,\n 0x09F9, 0x09FB, 0x0AF1, 0x0AF1, 0x0BF9, 0x0BF9, 0x0D79, 0x0D79, 0x0E3F, 0x0E3F,\n 0x17DB, 0x17DB, 0x2030, 0x2037, 0x2057, 0x2057, 0x20A0, 0x20CF, 0x2103, 0x2103,\n 0x2109, 0x2109, 0x2116, 0x2116, 0x2212, 0x2213, 0xA838, 0xA838, 0xFDFC, 0xFDFC,\n 0xFE69, 0xFE6A, 0xFF04, 0xFF05, 0xFFE0, 0xFFE1, 0xFFE5, 0xFFE6,\n 0x11FDD, 0x11FE0, 0x1E2FF, 0x1E2FF, 0x1ECAC, 0x1ECAC, 0x1ECB0, 0x1ECB0,\n];\nfunction isCodePointInRanges(codePoint, ranges) {\n for (let i = 0; i < ranges.length; i += 2) {\n if (codePoint >= ranges[i] && codePoint <= ranges[i + 1])\n return true;\n }\n return false;\n}\nfunction isLineBreakNumericAffix(ch) {\n const codePoint = ch.codePointAt(0);\n return codePoint !== undefined && isCodePointInRanges(codePoint, lineBreakNumericAffixRanges);\n}\nfunction endsWithLineBreakNumericAffix(text) {\n const last = getLastSignificantCodePoint(text);\n return last !== null && isLineBreakNumericAffix(last);\n}\nfunction startsWithDecimalDigit(text) {\n const first = getFirstSignificantCodePoint(text);\n return first !== null && decimalDigitRe.test(first);\n}\nfunction splitTrailingForwardStickyCluster(text) {\n const chars = Array.from(text);\n let splitIndex = chars.length;\n while (splitIndex > 0) {\n const ch = chars[splitIndex - 1];\n if (combiningMarkRe.test(ch)) {\n splitIndex--;\n continue;\n }\n if (kinsokuEnd.has(ch) || forwardStickyGlue.has(ch)) {\n splitIndex--;\n continue;\n }\n break;\n }\n if (splitIndex <= 0 || splitIndex === chars.length)\n return null;\n return {\n head: chars.slice(0, splitIndex).join(''),\n tail: chars.slice(splitIndex).join(''),\n };\n}\nfunction getRepeatableSingleCharRunChar(text, isWordLike, kind) {\n return kind === 'text' && !isWordLike && text.length === 1 && text !== '-' && text !== '\u2014'\n ? text\n : null;\n}\nfunction materializeDeferredSingleCharRun(texts, chars, lengths, index) {\n const ch = chars[index];\n const text = texts[index];\n if (ch == null)\n return text;\n const length = lengths[index];\n if (text.length === length)\n return text;\n const materialized = ch.repeat(length);\n texts[index] = materialized;\n return materialized;\n}\nfunction hasArabicNoSpacePunctuation(containsArabic, lastCodePoint) {\n return containsArabic && lastCodePoint !== null && arabicNoSpaceTrailingPunctuation.has(lastCodePoint);\n}\nfunction endsWithMyanmarMedialGlue(segment) {\n const lastCodePoint = getLastCodePoint(segment);\n return lastCodePoint !== null && myanmarMedialGlue.has(lastCodePoint);\n}\nfunction splitLeadingSpaceAndMarks(segment) {\n if (segment.length < 2 || segment[0] !== ' ')\n return null;\n const marks = segment.slice(1);\n if (/^\\p{M}+$/u.test(marks)) {\n return { space: ' ', marks };\n }\n return null;\n}\nexport function endsWithClosingQuote(text) {\n let end = text.length;\n while (end > 0) {\n const start = previousCodePointStart(text, end);\n const ch = text.slice(start, end);\n if (closingQuoteChars.has(ch))\n return true;\n if (!leftStickyPunctuation.has(ch))\n return false;\n end = start;\n }\n return false;\n}\nfunction classifySegmentBreakChar(ch, whiteSpaceProfile) {\n if (whiteSpaceProfile.preserveOrdinarySpaces || whiteSpaceProfile.preserveHardBreaks) {\n if (ch === ' ')\n return 'preserved-space';\n if (ch === '\\t')\n return 'tab';\n if (whiteSpaceProfile.preserveHardBreaks && ch === '\\n')\n return 'hard-break';\n }\n if (ch === ' ')\n return 'space';\n if (ch === '\\u00A0' || ch === '\\u202F' || ch === '\\u2060' || ch === '\\uFEFF') {\n return 'glue';\n }\n if (ch === '\\u200B')\n return 'zero-width-break';\n if (ch === '\\u00AD')\n return 'soft-hyphen';\n return 'text';\n}\n// All characters that classifySegmentBreakChar maps to a non-'text' kind.\nconst breakCharRe = /[\\x20\\t\\n\\xA0\\xAD\\u200B\\u202F\\u2060\\uFEFF]/;\nfunction joinTextParts(parts) {\n return parts.length === 1 ? parts[0] : parts.join('');\n}\nfunction joinReversedPrefixParts(prefixParts, tail) {\n const parts = [];\n for (let i = prefixParts.length - 1; i >= 0; i--) {\n parts.push(prefixParts[i]);\n }\n parts.push(tail);\n return joinTextParts(parts);\n}\nfunction splitSegmentByBreakKind(segment, isWordLike, start, whiteSpaceProfile) {\n if (!breakCharRe.test(segment)) {\n return [{ text: segment, isWordLike, kind: 'text', start }];\n }\n const pieces = [];\n let currentKind = null;\n let currentTextParts = [];\n let currentStart = start;\n let currentWordLike = false;\n let offset = 0;\n for (const ch of segment) {\n const kind = classifySegmentBreakChar(ch, whiteSpaceProfile);\n const wordLike = kind === 'text' && isWordLike;\n if (currentKind !== null && kind === currentKind && wordLike === currentWordLike) {\n currentTextParts.push(ch);\n offset += ch.length;\n continue;\n }\n if (currentKind !== null) {\n pieces.push({\n text: joinTextParts(currentTextParts),\n isWordLike: currentWordLike,\n kind: currentKind,\n start: currentStart,\n });\n }\n currentKind = kind;\n currentTextParts = [ch];\n currentStart = start + offset;\n currentWordLike = wordLike;\n offset += ch.length;\n }\n if (currentKind !== null) {\n pieces.push({\n text: joinTextParts(currentTextParts),\n isWordLike: currentWordLike,\n kind: currentKind,\n start: currentStart,\n });\n }\n return pieces;\n}\nfunction isTextRunBoundary(kind) {\n return (kind === 'space' ||\n kind === 'preserved-space' ||\n kind === 'zero-width-break' ||\n kind === 'hard-break');\n}\nconst urlSchemeSegmentRe = /^[A-Za-z][A-Za-z0-9+.-]*:$/;\nfunction isUrlLikeRunStart(segmentation, index) {\n const text = segmentation.texts[index];\n if (text.startsWith('www.'))\n return true;\n return (urlSchemeSegmentRe.test(text) &&\n index + 1 < segmentation.len &&\n segmentation.kinds[index + 1] === 'text' &&\n segmentation.texts[index + 1] === '//');\n}\nfunction isUrlQueryBoundarySegment(text) {\n return text.includes('?') && (text.includes('://') || text.startsWith('www.'));\n}\nfunction mergeUrlLikeRuns(segmentation) {\n const texts = segmentation.texts.slice();\n const isWordLike = segmentation.isWordLike.slice();\n const kinds = segmentation.kinds.slice();\n const starts = segmentation.starts.slice();\n for (let i = 0; i < segmentation.len; i++) {\n if (kinds[i] !== 'text' || !isUrlLikeRunStart(segmentation, i))\n continue;\n const mergedParts = [texts[i]];\n let j = i + 1;\n while (j < segmentation.len && !isTextRunBoundary(kinds[j])) {\n mergedParts.push(texts[j]);\n isWordLike[i] = true;\n const endsQueryPrefix = texts[j].includes('?');\n kinds[j] = 'text';\n texts[j] = '';\n j++;\n if (endsQueryPrefix)\n break;\n }\n texts[i] = joinTextParts(mergedParts);\n }\n let compactLen = 0;\n for (let read = 0; read < texts.length; read++) {\n const text = texts[read];\n if (text.length === 0)\n continue;\n if (compactLen !== read) {\n texts[compactLen] = text;\n isWordLike[compactLen] = isWordLike[read];\n kinds[compactLen] = kinds[read];\n starts[compactLen] = starts[read];\n }\n compactLen++;\n }\n texts.length = compactLen;\n isWordLike.length = compactLen;\n kinds.length = compactLen;\n starts.length = compactLen;\n return {\n len: compactLen,\n texts,\n isWordLike,\n kinds,\n starts,\n };\n}\nfunction mergeUrlQueryRuns(segmentation) {\n const texts = [];\n const isWordLike = [];\n const kinds = [];\n const starts = [];\n for (let i = 0; i < segmentation.len; i++) {\n const text = segmentation.texts[i];\n texts.push(text);\n isWordLike.push(segmentation.isWordLike[i]);\n kinds.push(segmentation.kinds[i]);\n starts.push(segmentation.starts[i]);\n if (!isUrlQueryBoundarySegment(text))\n continue;\n const nextIndex = i + 1;\n if (nextIndex >= segmentation.len ||\n isTextRunBoundary(segmentation.kinds[nextIndex])) {\n continue;\n }\n const queryParts = [];\n const queryStart = segmentation.starts[nextIndex];\n let j = nextIndex;\n while (j < segmentation.len && !isTextRunBoundary(segmentation.kinds[j])) {\n queryParts.push(segmentation.texts[j]);\n j++;\n }\n if (queryParts.length > 0) {\n texts.push(joinTextParts(queryParts));\n isWordLike.push(true);\n kinds.push('text');\n starts.push(queryStart);\n i = j - 1;\n }\n }\n return {\n len: texts.length,\n texts,\n isWordLike,\n kinds,\n starts,\n };\n}\nconst numericJoinerChars = new Set([\n ':', '-', '/', '\u00D7', ',', '.', '+',\n '\\u2013',\n '\\u2014',\n]);\nconst noSpacePunctuationChainJoiners = new Set(['.', ',', ':', ';']);\nfunction endsWithNoSpacePunctuationChainJoiner(text) {\n for (let end = text.length; end > 0;) {\n const start = previousCodePointStart(text, end);\n const ch = text.slice(start, end);\n if (combiningMarkRe.test(ch)) {\n end = start;\n continue;\n }\n return noSpacePunctuationChainJoiners.has(ch) || isLineBreakNumericAffix(ch);\n }\n return false;\n}\nfunction isNoSpacePunctuationChainSegment(text, wordLike) {\n return wordLike && !isCJK(text);\n}\nfunction segmentContainsDecimalDigit(text) {\n for (const ch of text) {\n if (decimalDigitRe.test(ch))\n return true;\n }\n return false;\n}\nexport function isNumericRunSegment(text) {\n if (text.length === 0)\n return false;\n for (const ch of text) {\n if (decimalDigitRe.test(ch) || numericJoinerChars.has(ch))\n continue;\n return false;\n }\n return true;\n}\nfunction mergeNumericRuns(segmentation) {\n const texts = [];\n const isWordLike = [];\n const kinds = [];\n const starts = [];\n for (let i = 0; i < segmentation.len; i++) {\n const text = segmentation.texts[i];\n const kind = segmentation.kinds[i];\n if (kind === 'text' && isNumericRunSegment(text) && segmentContainsDecimalDigit(text)) {\n const mergedParts = [text];\n let j = i + 1;\n while (j < segmentation.len &&\n segmentation.kinds[j] === 'text' &&\n isNumericRunSegment(segmentation.texts[j])) {\n mergedParts.push(segmentation.texts[j]);\n j++;\n }\n texts.push(joinTextParts(mergedParts));\n isWordLike.push(true);\n kinds.push('text');\n starts.push(segmentation.starts[i]);\n i = j - 1;\n continue;\n }\n texts.push(text);\n isWordLike.push(segmentation.isWordLike[i]);\n kinds.push(kind);\n starts.push(segmentation.starts[i]);\n }\n return {\n len: texts.length,\n texts,\n isWordLike,\n kinds,\n starts,\n };\n}\nfunction mergeNoSpacePunctuationChains(segmentation) {\n const texts = [];\n const isWordLike = [];\n const kinds = [];\n const starts = [];\n for (let i = 0; i < segmentation.len; i++) {\n const text = segmentation.texts[i];\n const kind = segmentation.kinds[i];\n const wordLike = segmentation.isWordLike[i];\n if (kind === 'text' &&\n endsWithNoSpacePunctuationChainJoiner(text) &&\n (wordLike || endsWithLineBreakNumericAffix(text)) &&\n !isCJK(text)) {\n const mergedParts = [text];\n let endsWithJoiners = true;\n let j = i + 1;\n while (endsWithJoiners &&\n j < segmentation.len &&\n segmentation.kinds[j] === 'text' &&\n isNoSpacePunctuationChainSegment(segmentation.texts[j], segmentation.isWordLike[j])) {\n const nextText = segmentation.texts[j];\n mergedParts.push(nextText);\n endsWithJoiners = endsWithNoSpacePunctuationChainJoiner(nextText);\n j++;\n }\n texts.push(joinTextParts(mergedParts));\n isWordLike.push(true);\n kinds.push('text');\n starts.push(segmentation.starts[i]);\n i = j - 1;\n continue;\n }\n texts.push(text);\n isWordLike.push(wordLike);\n kinds.push(kind);\n starts.push(segmentation.starts[i]);\n }\n return {\n len: texts.length,\n texts,\n isWordLike,\n kinds,\n starts,\n };\n}\nfunction splitHyphenatedNumericRuns(segmentation) {\n const texts = [];\n const isWordLike = [];\n const kinds = [];\n const starts = [];\n for (let i = 0; i < segmentation.len; i++) {\n const text = segmentation.texts[i];\n if (segmentation.kinds[i] === 'text' && text.includes('-')) {\n const parts = text.split('-');\n let shouldSplit = parts.length > 1;\n for (let j = 0; j < parts.length; j++) {\n const part = parts[j];\n if (!shouldSplit)\n break;\n if (part.length === 0 ||\n !segmentContainsDecimalDigit(part) ||\n !isNumericRunSegment(part)) {\n shouldSplit = false;\n }\n }\n if (shouldSplit) {\n let offset = 0;\n for (let j = 0; j < parts.length; j++) {\n const part = parts[j];\n const splitText = j < parts.length - 1 ? `${part}-` : part;\n texts.push(splitText);\n isWordLike.push(true);\n kinds.push('text');\n starts.push(segmentation.starts[i] + offset);\n offset += splitText.length;\n }\n continue;\n }\n }\n texts.push(text);\n isWordLike.push(segmentation.isWordLike[i]);\n kinds.push(segmentation.kinds[i]);\n starts.push(segmentation.starts[i]);\n }\n return {\n len: texts.length,\n texts,\n isWordLike,\n kinds,\n starts,\n };\n}\nfunction mergeGlueConnectedTextRuns(segmentation) {\n const texts = [];\n const isWordLike = [];\n const kinds = [];\n const starts = [];\n let read = 0;\n while (read < segmentation.len) {\n const textParts = [segmentation.texts[read]];\n let wordLike = segmentation.isWordLike[read];\n let kind = segmentation.kinds[read];\n let start = segmentation.starts[read];\n if (kind === 'glue') {\n const glueParts = [textParts[0]];\n const glueStart = start;\n read++;\n while (read < segmentation.len && segmentation.kinds[read] === 'glue') {\n glueParts.push(segmentation.texts[read]);\n read++;\n }\n const glueText = joinTextParts(glueParts);\n if (read < segmentation.len && segmentation.kinds[read] === 'text') {\n textParts[0] = glueText;\n textParts.push(segmentation.texts[read]);\n wordLike = segmentation.isWordLike[read];\n kind = 'text';\n start = glueStart;\n read++;\n }\n else {\n texts.push(glueText);\n isWordLike.push(false);\n kinds.push('glue');\n starts.push(glueStart);\n continue;\n }\n }\n else {\n read++;\n }\n if (kind === 'text') {\n while (read < segmentation.len && segmentation.kinds[read] === 'glue') {\n const glueParts = [];\n while (read < segmentation.len && segmentation.kinds[read] === 'glue') {\n glueParts.push(segmentation.texts[read]);\n read++;\n }\n const glueText = joinTextParts(glueParts);\n if (read < segmentation.len && segmentation.kinds[read] === 'text') {\n textParts.push(glueText, segmentation.texts[read]);\n wordLike = wordLike || segmentation.isWordLike[read];\n read++;\n continue;\n }\n textParts.push(glueText);\n }\n }\n texts.push(joinTextParts(textParts));\n isWordLike.push(wordLike);\n kinds.push(kind);\n starts.push(start);\n }\n return {\n len: texts.length,\n texts,\n isWordLike,\n kinds,\n starts,\n };\n}\nfunction carryTrailingForwardStickyAcrossCJKBoundary(segmentation) {\n const texts = segmentation.texts.slice();\n const isWordLike = segmentation.isWordLike.slice();\n const kinds = segmentation.kinds.slice();\n const starts = segmentation.starts.slice();\n for (let i = 0; i < texts.length - 1; i++) {\n if (kinds[i] !== 'text' || kinds[i + 1] !== 'text')\n continue;\n if (!isCJK(texts[i]) || !isCJK(texts[i + 1]))\n continue;\n const split = splitTrailingForwardStickyCluster(texts[i]);\n if (split === null)\n continue;\n texts[i] = split.head;\n texts[i + 1] = split.tail + texts[i + 1];\n starts[i + 1] = starts[i] + split.head.length;\n }\n return {\n len: texts.length,\n texts,\n isWordLike,\n kinds,\n starts,\n };\n}\nfunction buildMergedSegmentation(normalized, profile, whiteSpaceProfile) {\n const wordSegmenter = getSharedWordSegmenter();\n let mergedLen = 0;\n const mergedTexts = [];\n const mergedTextParts = [];\n const mergedWordLike = [];\n const mergedKinds = [];\n const mergedStarts = [];\n // Track repeatable single-char punctuation runs structurally so identical\n // merges stay O(1) instead of re-scanning the accumulated segment each time.\n const mergedSingleCharRunChars = [];\n const mergedSingleCharRunLengths = [];\n const mergedContainsCJK = [];\n const mergedContainsArabicScript = [];\n const mergedEndsWithClosingQuote = [];\n const mergedEndsWithMyanmarMedialGlue = [];\n const mergedHasArabicNoSpacePunctuation = [];\n for (const s of wordSegmenter.segment(normalized)) {\n for (const piece of splitSegmentByBreakKind(s.segment, s.isWordLike ?? false, s.index, whiteSpaceProfile)) {\n const isText = piece.kind === 'text';\n const repeatableSingleCharRunChar = getRepeatableSingleCharRunChar(piece.text, piece.isWordLike, piece.kind);\n const pieceContainsCJK = isCJK(piece.text);\n const pieceContainsArabicScript = containsArabicScript(piece.text);\n const pieceLastCodePoint = getLastCodePoint(piece.text);\n const pieceEndsWithClosingQuote = endsWithClosingQuote(piece.text);\n const pieceEndsWithMyanmarMedialGlue = endsWithMyanmarMedialGlue(piece.text);\n const prevIndex = mergedLen - 1;\n function appendPieceToPrevious() {\n if (mergedSingleCharRunChars[prevIndex] !== null) {\n mergedTextParts[prevIndex] = [\n materializeDeferredSingleCharRun(mergedTexts, mergedSingleCharRunChars, mergedSingleCharRunLengths, prevIndex),\n ];\n mergedSingleCharRunChars[prevIndex] = null;\n }\n mergedTextParts[prevIndex].push(piece.text);\n mergedWordLike[prevIndex] = mergedWordLike[prevIndex] || piece.isWordLike;\n mergedContainsCJK[prevIndex] = mergedContainsCJK[prevIndex] || pieceContainsCJK;\n mergedContainsArabicScript[prevIndex] =\n mergedContainsArabicScript[prevIndex] || pieceContainsArabicScript;\n mergedEndsWithClosingQuote[prevIndex] = pieceEndsWithClosingQuote;\n mergedEndsWithMyanmarMedialGlue[prevIndex] = pieceEndsWithMyanmarMedialGlue;\n mergedHasArabicNoSpacePunctuation[prevIndex] = hasArabicNoSpacePunctuation(mergedContainsArabicScript[prevIndex], pieceLastCodePoint);\n }\n // First-pass keeps: no-space script-specific joins and punctuation glue\n // that depend on the immediately preceding text run.\n if (profile.carryCJKAfterClosingQuote &&\n isText &&\n mergedLen > 0 &&\n mergedKinds[prevIndex] === 'text' &&\n pieceContainsCJK &&\n mergedContainsCJK[prevIndex] &&\n mergedEndsWithClosingQuote[prevIndex]) {\n appendPieceToPrevious();\n }\n else if (isText &&\n mergedLen > 0 &&\n mergedKinds[prevIndex] === 'text' &&\n isCJKLineStartProhibitedSegment(piece.text) &&\n mergedContainsCJK[prevIndex]) {\n appendPieceToPrevious();\n }\n else if (isText &&\n mergedLen > 0 &&\n mergedKinds[prevIndex] === 'text' &&\n mergedEndsWithMyanmarMedialGlue[prevIndex]) {\n appendPieceToPrevious();\n }\n else if (isText &&\n mergedLen > 0 &&\n mergedKinds[prevIndex] === 'text' &&\n piece.isWordLike &&\n pieceContainsArabicScript &&\n mergedHasArabicNoSpacePunctuation[prevIndex]) {\n appendPieceToPrevious();\n mergedWordLike[prevIndex] = true;\n }\n else if (repeatableSingleCharRunChar !== null &&\n mergedLen > 0 &&\n mergedKinds[prevIndex] === 'text' &&\n mergedSingleCharRunChars[prevIndex] === repeatableSingleCharRunChar) {\n mergedSingleCharRunLengths[prevIndex] = (mergedSingleCharRunLengths[prevIndex] ?? 1) + 1;\n }\n else if (isText &&\n !piece.isWordLike &&\n mergedLen > 0 &&\n mergedKinds[prevIndex] === 'text' &&\n !mergedContainsCJK[prevIndex] &&\n (isLeftStickyPunctuationSegment(piece.text) ||\n (piece.text === '-' && mergedWordLike[prevIndex]))) {\n appendPieceToPrevious();\n }\n else {\n mergedTexts[mergedLen] = piece.text;\n mergedTextParts[mergedLen] = [piece.text];\n mergedWordLike[mergedLen] = piece.isWordLike;\n mergedKinds[mergedLen] = piece.kind;\n mergedStarts[mergedLen] = piece.start;\n mergedSingleCharRunChars[mergedLen] = repeatableSingleCharRunChar;\n mergedSingleCharRunLengths[mergedLen] = repeatableSingleCharRunChar === null ? 0 : 1;\n mergedContainsCJK[mergedLen] = pieceContainsCJK;\n mergedContainsArabicScript[mergedLen] = pieceContainsArabicScript;\n mergedEndsWithClosingQuote[mergedLen] = pieceEndsWithClosingQuote;\n mergedEndsWithMyanmarMedialGlue[mergedLen] = pieceEndsWithMyanmarMedialGlue;\n mergedHasArabicNoSpacePunctuation[mergedLen] = hasArabicNoSpacePunctuation(pieceContainsArabicScript, pieceLastCodePoint);\n mergedLen++;\n }\n }\n }\n for (let i = 0; i < mergedLen; i++) {\n if (mergedSingleCharRunChars[i] !== null) {\n mergedTexts[i] = materializeDeferredSingleCharRun(mergedTexts, mergedSingleCharRunChars, mergedSingleCharRunLengths, i);\n continue;\n }\n mergedTexts[i] = joinTextParts(mergedTextParts[i]);\n }\n // Later passes operate on the merged text stream itself: contextual escaped\n // quote glue, forward-sticky carry, compaction, then the broader URL/numeric\n // and Arabic-leading-mark fixes.\n for (let i = 1; i < mergedLen; i++) {\n if (mergedKinds[i] === 'text' &&\n !mergedWordLike[i] &&\n isEscapedQuoteClusterSegment(mergedTexts[i]) &&\n mergedKinds[i - 1] === 'text' &&\n !mergedContainsCJK[i - 1]) {\n mergedTexts[i - 1] += mergedTexts[i];\n mergedWordLike[i - 1] = mergedWordLike[i - 1] || mergedWordLike[i];\n mergedTexts[i] = '';\n }\n }\n const forwardStickyPrefixParts = Array.from({ length: mergedLen }, () => null);\n let nextLiveIndex = -1;\n for (let i = mergedLen - 1; i >= 0; i--) {\n const text = mergedTexts[i];\n if (text.length === 0)\n continue;\n if (mergedKinds[i] === 'text' &&\n !mergedWordLike[i] &&\n nextLiveIndex >= 0 &&\n mergedKinds[nextLiveIndex] === 'text' &&\n (isForwardStickyClusterSegment(text) ||\n (text === '-' && startsWithDecimalDigit(mergedTexts[nextLiveIndex])))) {\n const prefixParts = forwardStickyPrefixParts[nextLiveIndex] ?? [];\n prefixParts.push(text);\n forwardStickyPrefixParts[nextLiveIndex] = prefixParts;\n mergedStarts[nextLiveIndex] = mergedStarts[i];\n mergedTexts[i] = '';\n continue;\n }\n nextLiveIndex = i;\n }\n for (let i = 0; i < mergedLen; i++) {\n const prefixParts = forwardStickyPrefixParts[i];\n if (prefixParts == null)\n continue;\n mergedTexts[i] = joinReversedPrefixParts(prefixParts, mergedTexts[i]);\n }\n let compactLen = 0;\n for (let read = 0; read < mergedLen; read++) {\n const text = mergedTexts[read];\n if (text.length === 0)\n continue;\n if (compactLen !== read) {\n mergedTexts[compactLen] = text;\n mergedWordLike[compactLen] = mergedWordLike[read];\n mergedKinds[compactLen] = mergedKinds[read];\n mergedStarts[compactLen] = mergedStarts[read];\n }\n compactLen++;\n }\n mergedTexts.length = compactLen;\n mergedWordLike.length = compactLen;\n mergedKinds.length = compactLen;\n mergedStarts.length = compactLen;\n const compacted = mergeGlueConnectedTextRuns({\n len: compactLen,\n texts: mergedTexts,\n isWordLike: mergedWordLike,\n kinds: mergedKinds,\n starts: mergedStarts,\n });\n const withMergedUrls = carryTrailingForwardStickyAcrossCJKBoundary(mergeNoSpacePunctuationChains(splitHyphenatedNumericRuns(mergeNumericRuns(mergeUrlQueryRuns(mergeUrlLikeRuns(compacted))))));\n for (let i = 0; i < withMergedUrls.len - 1; i++) {\n const split = splitLeadingSpaceAndMarks(withMergedUrls.texts[i]);\n if (split === null)\n continue;\n if ((withMergedUrls.kinds[i] !== 'space' && withMergedUrls.kinds[i] !== 'preserved-space') ||\n withMergedUrls.kinds[i + 1] !== 'text' ||\n !containsArabicScript(withMergedUrls.texts[i + 1])) {\n continue;\n }\n withMergedUrls.texts[i] = split.space;\n withMergedUrls.isWordLike[i] = false;\n withMergedUrls.kinds[i] = withMergedUrls.kinds[i] === 'preserved-space' ? 'preserved-space' : 'space';\n withMergedUrls.texts[i + 1] = split.marks + withMergedUrls.texts[i + 1];\n withMergedUrls.starts[i + 1] = withMergedUrls.starts[i] + split.space.length;\n }\n return withMergedUrls;\n}\nfunction compileAnalysisChunks(segmentation, whiteSpaceProfile) {\n if (segmentation.len === 0)\n return [];\n if (!whiteSpaceProfile.preserveHardBreaks) {\n return [{\n startSegmentIndex: 0,\n endSegmentIndex: segmentation.len,\n consumedEndSegmentIndex: segmentation.len,\n }];\n }\n const chunks = [];\n let startSegmentIndex = 0;\n for (let i = 0; i < segmentation.len; i++) {\n if (segmentation.kinds[i] !== 'hard-break')\n continue;\n chunks.push({\n startSegmentIndex,\n endSegmentIndex: i,\n consumedEndSegmentIndex: i + 1,\n });\n startSegmentIndex = i + 1;\n }\n if (startSegmentIndex < segmentation.len) {\n chunks.push({\n startSegmentIndex,\n endSegmentIndex: segmentation.len,\n consumedEndSegmentIndex: segmentation.len,\n });\n }\n return chunks;\n}\nfunction mergeKeepAllTextSegments(normalized, segmentation, breakAfterPunctuation) {\n if (segmentation.len <= 1)\n return segmentation;\n const texts = [];\n const isWordLike = [];\n const kinds = [];\n const starts = [];\n let groupStart = -1;\n let groupContainsCJK = false;\n function pushOriginalText(index) {\n texts.push(segmentation.texts[index]);\n isWordLike.push(segmentation.isWordLike[index]);\n kinds.push('text');\n starts.push(segmentation.starts[index]);\n }\n function pushMergedText(start, end) {\n let wordLike = false;\n for (let i = start; i < end; i++) {\n wordLike = wordLike || segmentation.isWordLike[i];\n }\n const sourceStart = segmentation.starts[start];\n const sourceEnd = end < segmentation.len ? segmentation.starts[end] : normalized.length;\n texts.push(normalized.slice(sourceStart, sourceEnd));\n isWordLike.push(wordLike);\n kinds.push('text');\n starts.push(sourceStart);\n }\n function flushGroup(end) {\n if (groupStart < 0)\n return;\n if (groupContainsCJK) {\n if (groupStart + 1 === end) {\n pushOriginalText(groupStart);\n }\n else {\n pushMergedText(groupStart, end);\n }\n }\n else {\n for (let i = groupStart; i < end; i++)\n pushOriginalText(i);\n }\n groupStart = -1;\n groupContainsCJK = false;\n }\n for (let i = 0; i < segmentation.len; i++) {\n const text = segmentation.texts[i];\n const kind = segmentation.kinds[i];\n if (kind === 'text') {\n if (groupStart >= 0 &&\n !canContinueKeepAllTextRun(segmentation.texts[i - 1], breakAfterPunctuation)) {\n flushGroup(i);\n }\n if (groupStart < 0)\n groupStart = i;\n groupContainsCJK = groupContainsCJK || isCJK(text);\n continue;\n }\n flushGroup(i);\n texts.push(text);\n isWordLike.push(segmentation.isWordLike[i]);\n kinds.push(kind);\n starts.push(segmentation.starts[i]);\n }\n flushGroup(segmentation.len);\n return {\n len: texts.length,\n texts,\n isWordLike,\n kinds,\n starts,\n };\n}\nexport function analyzeText(text, profile, whiteSpace = 'normal', wordBreak = 'normal') {\n const whiteSpaceProfile = getWhiteSpaceProfile(whiteSpace);\n const normalized = whiteSpaceProfile.mode === 'pre-wrap'\n ? normalizeWhitespacePreWrap(text)\n : normalizeWhitespaceNormal(text);\n if (normalized.length === 0) {\n return {\n normalized,\n chunks: [],\n len: 0,\n texts: [],\n isWordLike: [],\n kinds: [],\n starts: [],\n };\n }\n const mergedSegmentation = buildMergedSegmentation(normalized, profile, whiteSpaceProfile);\n const segmentation = wordBreak === 'keep-all'\n ? mergeKeepAllTextSegments(normalized, mergedSegmentation, profile.breakKeepAllAfterPunctuation)\n : mergedSegmentation;\n return {\n normalized,\n chunks: compileAnalysisChunks(segmentation, whiteSpaceProfile),\n ...segmentation,\n };\n}\n", "import { isCJK } from './analysis.js';\nlet measureContext = null;\nconst segmentMetricCaches = new Map();\nlet cachedEngineProfile = null;\n// Safari's prefix-fit policy is useful for ordinary word-sized runs, but letting\n// it measure every growing prefix of a giant segment recreates a pathological\n// superlinear prepare-time path. Past this size, switch to the cheaper\n// pair-context model and keep the public behavior linear.\nconst MAX_PREFIX_FIT_GRAPHEMES = 96;\nconst emojiPresentationRe = /\\p{Emoji_Presentation}/u;\nconst maybeEmojiRe = /[\\p{Emoji_Presentation}\\p{Extended_Pictographic}\\p{Regional_Indicator}\\uFE0F\\u20E3]/u;\nlet sharedGraphemeSegmenter = null;\nconst emojiCorrectionCache = new Map();\nexport function getMeasureContext() {\n if (measureContext !== null)\n return measureContext;\n if (typeof OffscreenCanvas !== 'undefined') {\n measureContext = new OffscreenCanvas(1, 1).getContext('2d');\n return measureContext;\n }\n if (typeof document !== 'undefined') {\n measureContext = document.createElement('canvas').getContext('2d');\n return measureContext;\n }\n throw new Error('Text measurement requires OffscreenCanvas or a DOM canvas context.');\n}\nexport function getSegmentMetricCache(font) {\n let cache = segmentMetricCaches.get(font);\n if (!cache) {\n cache = new Map();\n segmentMetricCaches.set(font, cache);\n }\n return cache;\n}\nexport function getSegmentMetrics(seg, cache) {\n let metrics = cache.get(seg);\n if (metrics === undefined) {\n const ctx = getMeasureContext();\n metrics = {\n width: ctx.measureText(seg).width,\n containsCJK: isCJK(seg),\n };\n cache.set(seg, metrics);\n }\n return metrics;\n}\nexport function getEngineProfile() {\n if (cachedEngineProfile !== null)\n return cachedEngineProfile;\n if (typeof navigator === 'undefined') {\n cachedEngineProfile = {\n lineFitEpsilon: 0.005,\n carryCJKAfterClosingQuote: false,\n breakKeepAllAfterPunctuation: true,\n preferPrefixWidthsForBreakableRuns: false,\n preferEarlySoftHyphenBreak: false,\n };\n return cachedEngineProfile;\n }\n const ua = navigator.userAgent;\n const vendor = navigator.vendor;\n const isSafari = vendor === 'Apple Computer, Inc.' &&\n ua.includes('Safari/') &&\n !ua.includes('Chrome/') &&\n !ua.includes('Chromium/') &&\n !ua.includes('CriOS/') &&\n !ua.includes('FxiOS/') &&\n !ua.includes('EdgiOS/');\n const isChromium = ua.includes('Chrome/') ||\n ua.includes('Chromium/') ||\n ua.includes('CriOS/') ||\n ua.includes('Edg/');\n cachedEngineProfile = {\n lineFitEpsilon: isSafari ? 1 / 64 : 0.005,\n carryCJKAfterClosingQuote: isChromium,\n breakKeepAllAfterPunctuation: !isSafari,\n preferPrefixWidthsForBreakableRuns: isSafari,\n preferEarlySoftHyphenBreak: isSafari,\n };\n return cachedEngineProfile;\n}\nexport function parseFontSize(font) {\n const m = font.match(/(\\d+(?:\\.\\d+)?)\\s*px/);\n return m ? parseFloat(m[1]) : 16;\n}\nfunction getSharedGraphemeSegmenter() {\n if (sharedGraphemeSegmenter === null) {\n sharedGraphemeSegmenter = new Intl.Segmenter(undefined, { granularity: 'grapheme' });\n }\n return sharedGraphemeSegmenter;\n}\nfunction isEmojiGrapheme(g) {\n return emojiPresentationRe.test(g) || g.includes('\\uFE0F');\n}\nexport function textMayContainEmoji(text) {\n return maybeEmojiRe.test(text);\n}\nfunction getEmojiCorrection(font, fontSize) {\n let correction = emojiCorrectionCache.get(font);\n if (correction !== undefined)\n return correction;\n const ctx = getMeasureContext();\n ctx.font = font;\n const canvasW = ctx.measureText('\\u{1F600}').width;\n correction = 0;\n if (canvasW > fontSize + 0.5 &&\n typeof document !== 'undefined' &&\n document.body !== null) {\n const span = document.createElement('span');\n span.style.font = font;\n span.style.display = 'inline-block';\n span.style.visibility = 'hidden';\n span.style.position = 'absolute';\n span.textContent = '\\u{1F600}';\n document.body.appendChild(span);\n const domW = span.getBoundingClientRect().width;\n document.body.removeChild(span);\n if (canvasW - domW > 0.5) {\n correction = canvasW - domW;\n }\n }\n emojiCorrectionCache.set(font, correction);\n return correction;\n}\nfunction countEmojiGraphemes(text) {\n let count = 0;\n const graphemeSegmenter = getSharedGraphemeSegmenter();\n for (const g of graphemeSegmenter.segment(text)) {\n if (isEmojiGrapheme(g.segment))\n count++;\n }\n return count;\n}\nfunction getEmojiCount(seg, metrics) {\n if (metrics.emojiCount === undefined) {\n metrics.emojiCount = countEmojiGraphemes(seg);\n }\n return metrics.emojiCount;\n}\nexport function getCorrectedSegmentWidth(seg, metrics, emojiCorrection) {\n if (emojiCorrection === 0)\n return metrics.width;\n return metrics.width - getEmojiCount(seg, metrics) * emojiCorrection;\n}\nexport function getSegmentGraphemeWidths(seg, cache, emojiCorrection) {\n const widths = [];\n const graphemeSegmenter = getSharedGraphemeSegmenter();\n for (const gs of graphemeSegmenter.segment(seg)) {\n const graphemeMetrics = getSegmentMetrics(gs.segment, cache);\n widths.push(getCorrectedSegmentWidth(gs.segment, graphemeMetrics, emojiCorrection));\n }\n return widths.length > 1 ? widths : null;\n}\nexport function getSegmentBreakableFitAdvances(seg, metrics, cache, emojiCorrection, mode) {\n if (metrics.breakableFitAdvances !== undefined && metrics.breakableFitMode === mode) {\n return metrics.breakableFitAdvances;\n }\n metrics.breakableFitMode = mode;\n const graphemeSegmenter = getSharedGraphemeSegmenter();\n const graphemes = [];\n for (const gs of graphemeSegmenter.segment(seg)) {\n graphemes.push(gs.segment);\n }\n if (graphemes.length <= 1) {\n metrics.breakableFitAdvances = null;\n return metrics.breakableFitAdvances;\n }\n if (mode === 'sum-graphemes') {\n const advances = [];\n for (const grapheme of graphemes) {\n const graphemeMetrics = getSegmentMetrics(grapheme, cache);\n advances.push(getCorrectedSegmentWidth(grapheme, graphemeMetrics, emojiCorrection));\n }\n metrics.breakableFitAdvances = advances;\n return metrics.breakableFitAdvances;\n }\n if (mode === 'pair-context' || graphemes.length > MAX_PREFIX_FIT_GRAPHEMES) {\n const advances = [];\n let previousGrapheme = null;\n let previousWidth = 0;\n for (const grapheme of graphemes) {\n const graphemeMetrics = getSegmentMetrics(grapheme, cache);\n const currentWidth = getCorrectedSegmentWidth(grapheme, graphemeMetrics, emojiCorrection);\n if (previousGrapheme === null) {\n advances.push(currentWidth);\n }\n else {\n const pair = previousGrapheme + grapheme;\n const pairMetrics = getSegmentMetrics(pair, cache);\n advances.push(getCorrectedSegmentWidth(pair, pairMetrics, emojiCorrection) - previousWidth);\n }\n previousGrapheme = grapheme;\n previousWidth = currentWidth;\n }\n metrics.breakableFitAdvances = advances;\n return metrics.breakableFitAdvances;\n }\n const advances = [];\n let prefix = '';\n let prefixWidth = 0;\n for (const grapheme of graphemes) {\n prefix += grapheme;\n const prefixMetrics = getSegmentMetrics(prefix, cache);\n const nextPrefixWidth = getCorrectedSegmentWidth(prefix, prefixMetrics, emojiCorrection);\n advances.push(nextPrefixWidth - prefixWidth);\n prefixWidth = nextPrefixWidth;\n }\n metrics.breakableFitAdvances = advances;\n return metrics.breakableFitAdvances;\n}\nexport function getFontMeasurementState(font, needsEmojiCorrection) {\n const ctx = getMeasureContext();\n ctx.font = font;\n const cache = getSegmentMetricCache(font);\n const fontSize = parseFontSize(font);\n const emojiCorrection = needsEmojiCorrection ? getEmojiCorrection(font, fontSize) : 0;\n return { cache, fontSize, emojiCorrection };\n}\nexport function clearMeasurementCaches() {\n segmentMetricCaches.clear();\n emojiCorrectionCache.clear();\n sharedGraphemeSegmenter = null;\n}\n", "import { getEngineProfile } from './measurement.js';\nfunction consumesAtLineStart(kind) {\n return kind === 'space' || kind === 'zero-width-break' || kind === 'soft-hyphen';\n}\nfunction breaksAfter(kind) {\n return (kind === 'space' ||\n kind === 'preserved-space' ||\n kind === 'tab' ||\n kind === 'zero-width-break' ||\n kind === 'soft-hyphen');\n}\nfunction normalizeLineStartSegmentIndex(prepared, segmentIndex, endSegmentIndex = prepared.widths.length) {\n while (segmentIndex < endSegmentIndex) {\n const kind = prepared.kinds[segmentIndex];\n if (!consumesAtLineStart(kind))\n break;\n segmentIndex++;\n }\n return segmentIndex;\n}\nfunction getTabAdvance(lineWidth, tabStopAdvance) {\n if (tabStopAdvance <= 0)\n return 0;\n const remainder = lineWidth % tabStopAdvance;\n if (Math.abs(remainder) <= 1e-6)\n return tabStopAdvance;\n return tabStopAdvance - remainder;\n}\nfunction getLeadingLetterSpacing(prepared, hasContent, segmentIndex) {\n return (prepared.letterSpacing !== 0 &&\n hasContent &&\n prepared.spacingGraphemeCounts[segmentIndex] > 0)\n ? prepared.letterSpacing\n : 0;\n}\nfunction getLineEndContribution(leadingSpacing, segmentContribution) {\n return segmentContribution === 0 ? 0 : leadingSpacing + segmentContribution;\n}\nfunction getTabTrailingLetterSpacing(prepared, segmentIndex) {\n return (prepared.letterSpacing !== 0 &&\n prepared.spacingGraphemeCounts[segmentIndex] > 0)\n ? prepared.letterSpacing\n : 0;\n}\nfunction getWholeSegmentFitContribution(prepared, kind, segmentIndex, leadingSpacing, segmentWidth) {\n const segmentContribution = kind === 'tab'\n ? segmentWidth + getTabTrailingLetterSpacing(prepared, segmentIndex)\n : prepared.lineEndFitAdvances[segmentIndex];\n return getLineEndContribution(leadingSpacing, segmentContribution);\n}\nfunction getBreakOpportunityFitContribution(prepared, kind, segmentIndex, leadingSpacing) {\n const segmentContribution = kind === 'tab' ? 0 : prepared.lineEndFitAdvances[segmentIndex];\n return getLineEndContribution(leadingSpacing, segmentContribution);\n}\nfunction getLineEndPaintContribution(prepared, kind, segmentIndex, leadingSpacing, segmentWidth) {\n const segmentContribution = kind === 'tab' ? segmentWidth : prepared.lineEndPaintAdvances[segmentIndex];\n return getLineEndContribution(leadingSpacing, segmentContribution);\n}\nfunction getBreakableGraphemeAdvance(prepared, hasContent, baseAdvance) {\n return prepared.letterSpacing !== 0 && hasContent\n ? baseAdvance + prepared.letterSpacing\n : baseAdvance;\n}\nfunction getBreakableCandidateFitWidth(prepared, candidatePaintWidth) {\n return prepared.letterSpacing === 0\n ? candidatePaintWidth\n : candidatePaintWidth + prepared.letterSpacing;\n}\nfunction getTerminalLetterSpacing(prepared, startSegmentIndex, startGraphemeIndex, endSegmentIndex, endGraphemeIndex) {\n if (prepared.letterSpacing === 0)\n return 0;\n if (endGraphemeIndex > 0) {\n return prepared.spacingGraphemeCounts[endSegmentIndex] > 0\n ? prepared.letterSpacing\n : 0;\n }\n for (let i = endSegmentIndex - 1; i >= startSegmentIndex; i--) {\n const kind = prepared.kinds[i];\n if (kind === 'space' || kind === 'zero-width-break' || kind === 'hard-break')\n continue;\n if (kind === 'soft-hyphen') {\n if (i === endSegmentIndex - 1)\n return 0;\n continue;\n }\n if (i === startSegmentIndex && startGraphemeIndex > 0) {\n return prepared.letterSpacing;\n }\n return prepared.spacingGraphemeCounts[i] > 0\n ? prepared.letterSpacing\n : 0;\n }\n return 0;\n}\nfunction finalizeLinePaintWidth(prepared, width, startSegmentIndex, startGraphemeIndex, endSegmentIndex, endGraphemeIndex) {\n return width + getTerminalLetterSpacing(prepared, startSegmentIndex, startGraphemeIndex, endSegmentIndex, endGraphemeIndex);\n}\nfunction findChunkIndexForStart(prepared, segmentIndex) {\n let lo = 0;\n let hi = prepared.chunks.length;\n while (lo < hi) {\n const mid = Math.floor((lo + hi) / 2);\n if (segmentIndex < prepared.chunks[mid].consumedEndSegmentIndex) {\n hi = mid;\n }\n else {\n lo = mid + 1;\n }\n }\n return lo < prepared.chunks.length ? lo : -1;\n}\nfunction normalizeLineStartInChunk(prepared, chunkIndex, cursor) {\n let segmentIndex = cursor.segmentIndex;\n if (cursor.graphemeIndex > 0)\n return chunkIndex;\n const chunk = prepared.chunks[chunkIndex];\n if (chunk.startSegmentIndex === chunk.endSegmentIndex && segmentIndex === chunk.startSegmentIndex) {\n cursor.segmentIndex = segmentIndex;\n cursor.graphemeIndex = 0;\n return chunkIndex;\n }\n if (segmentIndex < chunk.startSegmentIndex)\n segmentIndex = chunk.startSegmentIndex;\n segmentIndex = normalizeLineStartSegmentIndex(prepared, segmentIndex, chunk.endSegmentIndex);\n if (segmentIndex < chunk.endSegmentIndex) {\n cursor.segmentIndex = segmentIndex;\n cursor.graphemeIndex = 0;\n return chunkIndex;\n }\n if (chunk.consumedEndSegmentIndex >= prepared.widths.length)\n return -1;\n cursor.segmentIndex = chunk.consumedEndSegmentIndex;\n cursor.graphemeIndex = 0;\n return chunkIndex + 1;\n}\n// Mutates `cursor` to the next renderable line start and returns its chunk index.\nexport function normalizePreparedLineStart(prepared, cursor) {\n if (cursor.segmentIndex >= prepared.widths.length)\n return -1;\n const chunkIndex = findChunkIndexForStart(prepared, cursor.segmentIndex);\n if (chunkIndex < 0)\n return -1;\n return normalizeLineStartInChunk(prepared, chunkIndex, cursor);\n}\nfunction normalizeLineStartChunkIndexFromHint(prepared, chunkIndex, cursor) {\n if (cursor.segmentIndex >= prepared.widths.length)\n return -1;\n let nextChunkIndex = chunkIndex;\n while (nextChunkIndex < prepared.chunks.length &&\n cursor.segmentIndex >= prepared.chunks[nextChunkIndex].consumedEndSegmentIndex) {\n nextChunkIndex++;\n }\n if (nextChunkIndex >= prepared.chunks.length)\n return -1;\n return normalizeLineStartInChunk(prepared, nextChunkIndex, cursor);\n}\nexport function countPreparedLines(prepared, maxWidth) {\n return walkPreparedLinesRaw(prepared, maxWidth);\n}\nfunction walkPreparedLinesSimple(prepared, maxWidth, onLine) {\n const { widths, kinds, breakableFitAdvances } = prepared;\n if (widths.length === 0)\n return 0;\n const engineProfile = getEngineProfile();\n const lineFitEpsilon = engineProfile.lineFitEpsilon;\n const fitLimit = maxWidth + lineFitEpsilon;\n let lineCount = 0;\n let lineW = 0;\n let hasContent = false;\n let lineStartSegmentIndex = 0;\n let lineStartGraphemeIndex = 0;\n let lineEndSegmentIndex = 0;\n let lineEndGraphemeIndex = 0;\n let pendingBreakSegmentIndex = -1;\n let pendingBreakPaintWidth = 0;\n function clearPendingBreak() {\n pendingBreakSegmentIndex = -1;\n pendingBreakPaintWidth = 0;\n }\n function emitCurrentLine(endSegmentIndex = lineEndSegmentIndex, endGraphemeIndex = lineEndGraphemeIndex, width = lineW) {\n lineCount++;\n onLine?.(width, lineStartSegmentIndex, lineStartGraphemeIndex, endSegmentIndex, endGraphemeIndex);\n lineW = 0;\n hasContent = false;\n clearPendingBreak();\n }\n function startLineAtSegment(segmentIndex, width) {\n hasContent = true;\n lineStartSegmentIndex = segmentIndex;\n lineStartGraphemeIndex = 0;\n lineEndSegmentIndex = segmentIndex + 1;\n lineEndGraphemeIndex = 0;\n lineW = width;\n }\n function startLineAtGrapheme(segmentIndex, graphemeIndex, width) {\n hasContent = true;\n lineStartSegmentIndex = segmentIndex;\n lineStartGraphemeIndex = graphemeIndex;\n lineEndSegmentIndex = segmentIndex;\n lineEndGraphemeIndex = graphemeIndex + 1;\n lineW = width;\n }\n function appendWholeSegment(segmentIndex, width) {\n if (!hasContent) {\n startLineAtSegment(segmentIndex, width);\n return;\n }\n lineW += width;\n lineEndSegmentIndex = segmentIndex + 1;\n lineEndGraphemeIndex = 0;\n }\n function appendBreakableSegmentFrom(segmentIndex, startGraphemeIndex) {\n const fitAdvances = breakableFitAdvances[segmentIndex];\n for (let g = startGraphemeIndex; g < fitAdvances.length; g++) {\n const gw = fitAdvances[g];\n if (!hasContent) {\n startLineAtGrapheme(segmentIndex, g, gw);\n }\n else if (lineW + gw > fitLimit) {\n emitCurrentLine();\n startLineAtGrapheme(segmentIndex, g, gw);\n }\n else {\n lineW += gw;\n lineEndSegmentIndex = segmentIndex;\n lineEndGraphemeIndex = g + 1;\n }\n }\n if (hasContent && lineEndSegmentIndex === segmentIndex && lineEndGraphemeIndex === fitAdvances.length) {\n lineEndSegmentIndex = segmentIndex + 1;\n lineEndGraphemeIndex = 0;\n }\n }\n let i = 0;\n while (i < widths.length) {\n if (!hasContent) {\n i = normalizeLineStartSegmentIndex(prepared, i);\n if (i >= widths.length)\n break;\n }\n const w = widths[i];\n const kind = kinds[i];\n const breakAfter = breaksAfter(kind);\n if (!hasContent) {\n if (w > fitLimit && breakableFitAdvances[i] !== null) {\n appendBreakableSegmentFrom(i, 0);\n }\n else {\n startLineAtSegment(i, w);\n }\n if (breakAfter) {\n pendingBreakSegmentIndex = i + 1;\n pendingBreakPaintWidth = lineW - w;\n }\n i++;\n continue;\n }\n const newW = lineW + w;\n if (newW > fitLimit) {\n if (breakAfter) {\n appendWholeSegment(i, w);\n emitCurrentLine(i + 1, 0, lineW - w);\n i++;\n continue;\n }\n if (pendingBreakSegmentIndex >= 0) {\n if (lineEndSegmentIndex > pendingBreakSegmentIndex ||\n (lineEndSegmentIndex === pendingBreakSegmentIndex && lineEndGraphemeIndex > 0)) {\n emitCurrentLine();\n continue;\n }\n emitCurrentLine(pendingBreakSegmentIndex, 0, pendingBreakPaintWidth);\n continue;\n }\n if (w > fitLimit && breakableFitAdvances[i] !== null) {\n emitCurrentLine();\n appendBreakableSegmentFrom(i, 0);\n i++;\n continue;\n }\n emitCurrentLine();\n continue;\n }\n appendWholeSegment(i, w);\n if (breakAfter) {\n pendingBreakSegmentIndex = i + 1;\n pendingBreakPaintWidth = lineW - w;\n }\n i++;\n }\n if (hasContent)\n emitCurrentLine();\n return lineCount;\n}\nexport function walkPreparedLinesRaw(prepared, maxWidth, onLine) {\n if (prepared.simpleLineWalkFastPath) {\n return walkPreparedLinesSimple(prepared, maxWidth, onLine);\n }\n const { widths, kinds, breakableFitAdvances, discretionaryHyphenWidth, chunks, } = prepared;\n if (widths.length === 0 || chunks.length === 0)\n return 0;\n const engineProfile = getEngineProfile();\n const lineFitEpsilon = engineProfile.lineFitEpsilon;\n const fitLimit = maxWidth + lineFitEpsilon;\n let lineCount = 0;\n let lineW = 0;\n let hasContent = false;\n let lineStartSegmentIndex = 0;\n let lineStartGraphemeIndex = 0;\n let lineEndSegmentIndex = 0;\n let lineEndGraphemeIndex = 0;\n let pendingBreakSegmentIndex = -1;\n let pendingBreakFitWidth = 0;\n let pendingBreakPaintWidth = 0;\n let pendingBreakKind = null;\n function clearPendingBreak() {\n pendingBreakSegmentIndex = -1;\n pendingBreakFitWidth = 0;\n pendingBreakPaintWidth = 0;\n pendingBreakKind = null;\n }\n function getCurrentLinePaintWidth() {\n return (pendingBreakKind === 'soft-hyphen' &&\n pendingBreakSegmentIndex === lineEndSegmentIndex &&\n lineEndGraphemeIndex === 0)\n ? pendingBreakPaintWidth\n : lineW;\n }\n function emitCurrentLine(endSegmentIndex = lineEndSegmentIndex, endGraphemeIndex = lineEndGraphemeIndex, width) {\n lineCount++;\n if (onLine !== undefined) {\n onLine(finalizeLinePaintWidth(prepared, width ?? getCurrentLinePaintWidth(), lineStartSegmentIndex, lineStartGraphemeIndex, endSegmentIndex, endGraphemeIndex), lineStartSegmentIndex, lineStartGraphemeIndex, endSegmentIndex, endGraphemeIndex);\n }\n lineW = 0;\n hasContent = false;\n clearPendingBreak();\n }\n function startLineAtSegment(segmentIndex, width) {\n hasContent = true;\n lineStartSegmentIndex = segmentIndex;\n lineStartGraphemeIndex = 0;\n lineEndSegmentIndex = segmentIndex + 1;\n lineEndGraphemeIndex = 0;\n lineW = width;\n }\n function startLineAtGrapheme(segmentIndex, graphemeIndex, width) {\n hasContent = true;\n lineStartSegmentIndex = segmentIndex;\n lineStartGraphemeIndex = graphemeIndex;\n lineEndSegmentIndex = segmentIndex;\n lineEndGraphemeIndex = graphemeIndex + 1;\n lineW = width;\n }\n function appendWholeSegment(segmentIndex, advance) {\n if (!hasContent) {\n startLineAtSegment(segmentIndex, advance);\n return;\n }\n lineW += advance;\n lineEndSegmentIndex = segmentIndex + 1;\n lineEndGraphemeIndex = 0;\n }\n function updatePendingBreakForWholeSegment(kind, breakAfter, segmentIndex, segmentWidth, leadingSpacing, advance) {\n if (!breakAfter)\n return;\n const fitAdvance = getBreakOpportunityFitContribution(prepared, kind, segmentIndex, leadingSpacing);\n const paintAdvance = getLineEndPaintContribution(prepared, kind, segmentIndex, leadingSpacing, segmentWidth);\n pendingBreakSegmentIndex = segmentIndex + 1;\n pendingBreakFitWidth = lineW - advance + fitAdvance;\n pendingBreakPaintWidth = lineW - advance + paintAdvance;\n pendingBreakKind = kind;\n }\n function appendBreakableSegmentFrom(segmentIndex, startGraphemeIndex) {\n const fitAdvances = breakableFitAdvances[segmentIndex];\n for (let g = startGraphemeIndex; g < fitAdvances.length; g++) {\n const baseGw = fitAdvances[g];\n if (!hasContent) {\n startLineAtGrapheme(segmentIndex, g, baseGw);\n }\n else {\n const gw = getBreakableGraphemeAdvance(prepared, true, baseGw);\n const candidatePaintWidth = lineW + gw;\n if (getBreakableCandidateFitWidth(prepared, candidatePaintWidth) > fitLimit) {\n emitCurrentLine();\n startLineAtGrapheme(segmentIndex, g, baseGw);\n }\n else {\n lineW = candidatePaintWidth;\n lineEndSegmentIndex = segmentIndex;\n lineEndGraphemeIndex = g + 1;\n }\n }\n }\n if (hasContent && lineEndSegmentIndex === segmentIndex && lineEndGraphemeIndex === fitAdvances.length) {\n lineEndSegmentIndex = segmentIndex + 1;\n lineEndGraphemeIndex = 0;\n }\n }\n function emitEmptyChunk(chunk) {\n lineCount++;\n onLine?.(0, chunk.startSegmentIndex, 0, chunk.consumedEndSegmentIndex, 0);\n clearPendingBreak();\n }\n for (let chunkIndex = 0; chunkIndex < chunks.length; chunkIndex++) {\n const chunk = chunks[chunkIndex];\n if (chunk.startSegmentIndex === chunk.endSegmentIndex) {\n emitEmptyChunk(chunk);\n continue;\n }\n hasContent = false;\n lineW = 0;\n lineStartSegmentIndex = chunk.startSegmentIndex;\n lineStartGraphemeIndex = 0;\n lineEndSegmentIndex = chunk.startSegmentIndex;\n lineEndGraphemeIndex = 0;\n clearPendingBreak();\n let i = chunk.startSegmentIndex;\n while (i < chunk.endSegmentIndex) {\n if (!hasContent) {\n i = normalizeLineStartSegmentIndex(prepared, i, chunk.endSegmentIndex);\n if (i >= chunk.endSegmentIndex)\n break;\n }\n const kind = kinds[i];\n const breakAfter = breaksAfter(kind);\n const leadingSpacing = getLeadingLetterSpacing(prepared, hasContent, i);\n const w = kind === 'tab'\n ? getTabAdvance(lineW + leadingSpacing, prepared.tabStopAdvance)\n : widths[i];\n const advance = leadingSpacing + w;\n const fitAdvance = getWholeSegmentFitContribution(prepared, kind, i, leadingSpacing, w);\n if (kind === 'soft-hyphen') {\n if (hasContent) {\n lineEndSegmentIndex = i + 1;\n lineEndGraphemeIndex = 0;\n pendingBreakSegmentIndex = i + 1;\n pendingBreakFitWidth = lineW + discretionaryHyphenWidth;\n pendingBreakPaintWidth = lineW + discretionaryHyphenWidth;\n pendingBreakKind = kind;\n }\n i++;\n continue;\n }\n if (!hasContent) {\n if (fitAdvance > fitLimit && breakableFitAdvances[i] !== null) {\n appendBreakableSegmentFrom(i, 0);\n }\n else {\n startLineAtSegment(i, w);\n }\n updatePendingBreakForWholeSegment(kind, breakAfter, i, w, leadingSpacing, advance);\n i++;\n continue;\n }\n const newFitW = lineW + fitAdvance;\n if (newFitW > fitLimit) {\n const currentBreakFitWidth = lineW + getBreakOpportunityFitContribution(prepared, kind, i, leadingSpacing);\n const currentBreakPaintWidth = lineW + getLineEndPaintContribution(prepared, kind, i, leadingSpacing, w);\n if (pendingBreakKind === 'soft-hyphen' &&\n engineProfile.preferEarlySoftHyphenBreak &&\n pendingBreakFitWidth <= fitLimit) {\n emitCurrentLine(pendingBreakSegmentIndex, 0, pendingBreakPaintWidth);\n continue;\n }\n if (breakAfter && currentBreakFitWidth <= fitLimit) {\n appendWholeSegment(i, advance);\n emitCurrentLine(i + 1, 0, currentBreakPaintWidth);\n i++;\n continue;\n }\n if (pendingBreakSegmentIndex >= 0 && pendingBreakFitWidth <= fitLimit) {\n if (lineEndSegmentIndex > pendingBreakSegmentIndex ||\n (lineEndSegmentIndex === pendingBreakSegmentIndex && lineEndGraphemeIndex > 0)) {\n emitCurrentLine();\n continue;\n }\n const nextSegmentIndex = pendingBreakSegmentIndex;\n emitCurrentLine(nextSegmentIndex, 0, pendingBreakPaintWidth);\n i = nextSegmentIndex;\n continue;\n }\n if (fitAdvance > fitLimit && breakableFitAdvances[i] !== null) {\n emitCurrentLine();\n appendBreakableSegmentFrom(i, 0);\n i++;\n continue;\n }\n emitCurrentLine();\n continue;\n }\n appendWholeSegment(i, advance);\n updatePendingBreakForWholeSegment(kind, breakAfter, i, w, leadingSpacing, advance);\n i++;\n }\n if (hasContent) {\n const finalPaintWidth = pendingBreakSegmentIndex === chunk.consumedEndSegmentIndex\n ? pendingBreakPaintWidth\n : lineW;\n emitCurrentLine(chunk.consumedEndSegmentIndex, 0, finalPaintWidth);\n }\n }\n return lineCount;\n}\nexport function walkPreparedLines(prepared, maxWidth, onLine) {\n if (onLine === undefined)\n return walkPreparedLinesRaw(prepared, maxWidth);\n return walkPreparedLinesRaw(prepared, maxWidth, (width, startSegmentIndex, startGraphemeIndex, endSegmentIndex, endGraphemeIndex) => {\n onLine({\n startSegmentIndex,\n startGraphemeIndex,\n endSegmentIndex,\n endGraphemeIndex,\n width,\n });\n });\n}\nfunction stepPreparedChunkLineGeometry(prepared, cursor, chunkIndex, maxWidth) {\n const chunk = prepared.chunks[chunkIndex];\n if (chunk.startSegmentIndex === chunk.endSegmentIndex) {\n cursor.segmentIndex = chunk.consumedEndSegmentIndex;\n cursor.graphemeIndex = 0;\n return 0;\n }\n const { widths, kinds, breakableFitAdvances, discretionaryHyphenWidth, } = prepared;\n const engineProfile = getEngineProfile();\n const lineFitEpsilon = engineProfile.lineFitEpsilon;\n const fitLimit = maxWidth + lineFitEpsilon;\n const lineStartSegmentIndex = cursor.segmentIndex;\n const lineStartGraphemeIndex = cursor.graphemeIndex;\n let lineW = 0;\n let hasContent = false;\n let lineEndSegmentIndex = cursor.segmentIndex;\n let lineEndGraphemeIndex = cursor.graphemeIndex;\n let pendingBreakSegmentIndex = -1;\n let pendingBreakFitWidth = 0;\n let pendingBreakPaintWidth = 0;\n let pendingBreakKind = null;\n function getCurrentLinePaintWidth() {\n return (pendingBreakKind === 'soft-hyphen' &&\n pendingBreakSegmentIndex === lineEndSegmentIndex &&\n lineEndGraphemeIndex === 0)\n ? pendingBreakPaintWidth\n : lineW;\n }\n function finishLine(endSegmentIndex = lineEndSegmentIndex, endGraphemeIndex = lineEndGraphemeIndex, width = getCurrentLinePaintWidth()) {\n if (!hasContent)\n return null;\n cursor.segmentIndex = endSegmentIndex;\n cursor.graphemeIndex = endGraphemeIndex;\n return finalizeLinePaintWidth(prepared, width, lineStartSegmentIndex, lineStartGraphemeIndex, endSegmentIndex, endGraphemeIndex);\n }\n function startLineAtSegment(segmentIndex, width) {\n hasContent = true;\n lineEndSegmentIndex = segmentIndex + 1;\n lineEndGraphemeIndex = 0;\n lineW = width;\n }\n function startLineAtGrapheme(segmentIndex, graphemeIndex, width) {\n hasContent = true;\n lineEndSegmentIndex = segmentIndex;\n lineEndGraphemeIndex = graphemeIndex + 1;\n lineW = width;\n }\n function appendWholeSegment(segmentIndex, advance) {\n if (!hasContent) {\n startLineAtSegment(segmentIndex, advance);\n return;\n }\n lineW += advance;\n lineEndSegmentIndex = segmentIndex + 1;\n lineEndGraphemeIndex = 0;\n }\n function updatePendingBreakForWholeSegment(kind, breakAfter, segmentIndex, segmentWidth, leadingSpacing, advance) {\n if (!breakAfter)\n return;\n const fitAdvance = getBreakOpportunityFitContribution(prepared, kind, segmentIndex, leadingSpacing);\n const paintAdvance = getLineEndPaintContribution(prepared, kind, segmentIndex, leadingSpacing, segmentWidth);\n pendingBreakSegmentIndex = segmentIndex + 1;\n pendingBreakFitWidth = lineW - advance + fitAdvance;\n pendingBreakPaintWidth = lineW - advance + paintAdvance;\n pendingBreakKind = kind;\n }\n function appendBreakableSegmentFrom(segmentIndex, startGraphemeIndex) {\n const fitAdvances = breakableFitAdvances[segmentIndex];\n for (let g = startGraphemeIndex; g < fitAdvances.length; g++) {\n const baseGw = fitAdvances[g];\n if (!hasContent) {\n startLineAtGrapheme(segmentIndex, g, baseGw);\n }\n else {\n const gw = getBreakableGraphemeAdvance(prepared, true, baseGw);\n const candidatePaintWidth = lineW + gw;\n if (getBreakableCandidateFitWidth(prepared, candidatePaintWidth) > fitLimit) {\n return finishLine();\n }\n lineW = candidatePaintWidth;\n lineEndSegmentIndex = segmentIndex;\n lineEndGraphemeIndex = g + 1;\n }\n }\n if (hasContent && lineEndSegmentIndex === segmentIndex && lineEndGraphemeIndex === fitAdvances.length) {\n lineEndSegmentIndex = segmentIndex + 1;\n lineEndGraphemeIndex = 0;\n }\n return null;\n }\n function maybeFinishAtSoftHyphen() {\n if (pendingBreakKind !== 'soft-hyphen' || pendingBreakSegmentIndex < 0)\n return null;\n if (pendingBreakFitWidth <= fitLimit) {\n return finishLine(pendingBreakSegmentIndex, 0, pendingBreakPaintWidth);\n }\n return null;\n }\n for (let i = cursor.segmentIndex; i < chunk.endSegmentIndex; i++) {\n const kind = kinds[i];\n const breakAfter = breaksAfter(kind);\n const startGraphemeIndex = i === cursor.segmentIndex ? cursor.graphemeIndex : 0;\n const leadingSpacing = getLeadingLetterSpacing(prepared, hasContent, i);\n const w = kind === 'tab'\n ? getTabAdvance(lineW + leadingSpacing, prepared.tabStopAdvance)\n : widths[i];\n const advance = leadingSpacing + w;\n const fitAdvance = getWholeSegmentFitContribution(prepared, kind, i, leadingSpacing, w);\n if (kind === 'soft-hyphen' && startGraphemeIndex === 0) {\n if (hasContent) {\n lineEndSegmentIndex = i + 1;\n lineEndGraphemeIndex = 0;\n pendingBreakSegmentIndex = i + 1;\n pendingBreakFitWidth = lineW + discretionaryHyphenWidth;\n pendingBreakPaintWidth = lineW + discretionaryHyphenWidth;\n pendingBreakKind = kind;\n }\n continue;\n }\n if (!hasContent) {\n if (startGraphemeIndex > 0) {\n const line = appendBreakableSegmentFrom(i, startGraphemeIndex);\n if (line !== null)\n return line;\n }\n else if (fitAdvance > fitLimit && breakableFitAdvances[i] !== null) {\n const line = appendBreakableSegmentFrom(i, 0);\n if (line !== null)\n return line;\n }\n else {\n startLineAtSegment(i, w);\n }\n updatePendingBreakForWholeSegment(kind, breakAfter, i, w, leadingSpacing, advance);\n continue;\n }\n const newFitW = lineW + fitAdvance;\n if (newFitW > fitLimit) {\n const currentBreakFitWidth = lineW + getBreakOpportunityFitContribution(prepared, kind, i, leadingSpacing);\n const currentBreakPaintWidth = lineW + getLineEndPaintContribution(prepared, kind, i, leadingSpacing, w);\n if (pendingBreakKind === 'soft-hyphen' &&\n engineProfile.preferEarlySoftHyphenBreak &&\n pendingBreakFitWidth <= fitLimit) {\n return finishLine(pendingBreakSegmentIndex, 0, pendingBreakPaintWidth);\n }\n const softBreakLine = maybeFinishAtSoftHyphen();\n if (softBreakLine !== null)\n return softBreakLine;\n if (breakAfter && currentBreakFitWidth <= fitLimit) {\n appendWholeSegment(i, advance);\n return finishLine(i + 1, 0, currentBreakPaintWidth);\n }\n if (pendingBreakSegmentIndex >= 0 && pendingBreakFitWidth <= fitLimit) {\n if (lineEndSegmentIndex > pendingBreakSegmentIndex ||\n (lineEndSegmentIndex === pendingBreakSegmentIndex && lineEndGraphemeIndex > 0)) {\n return finishLine();\n }\n return finishLine(pendingBreakSegmentIndex, 0, pendingBreakPaintWidth);\n }\n if (fitAdvance > fitLimit && breakableFitAdvances[i] !== null) {\n const currentLine = finishLine();\n if (currentLine !== null)\n return currentLine;\n const line = appendBreakableSegmentFrom(i, 0);\n if (line !== null)\n return line;\n }\n return finishLine();\n }\n appendWholeSegment(i, advance);\n updatePendingBreakForWholeSegment(kind, breakAfter, i, w, leadingSpacing, advance);\n }\n if (pendingBreakSegmentIndex === chunk.consumedEndSegmentIndex && lineEndGraphemeIndex === 0) {\n return finishLine(chunk.consumedEndSegmentIndex, 0, pendingBreakPaintWidth);\n }\n return finishLine(chunk.consumedEndSegmentIndex, 0, lineW);\n}\nfunction stepPreparedSimpleLineGeometry(prepared, cursor, maxWidth) {\n const { widths, kinds, breakableFitAdvances } = prepared;\n const engineProfile = getEngineProfile();\n const lineFitEpsilon = engineProfile.lineFitEpsilon;\n const fitLimit = maxWidth + lineFitEpsilon;\n let lineW = 0;\n let hasContent = false;\n let lineEndSegmentIndex = cursor.segmentIndex;\n let lineEndGraphemeIndex = cursor.graphemeIndex;\n let pendingBreakSegmentIndex = -1;\n let pendingBreakPaintWidth = 0;\n for (let i = cursor.segmentIndex; i < widths.length; i++) {\n const kind = kinds[i];\n const breakAfter = breaksAfter(kind);\n const startGraphemeIndex = i === cursor.segmentIndex ? cursor.graphemeIndex : 0;\n const breakableFitAdvance = breakableFitAdvances[i];\n const w = widths[i];\n if (!hasContent) {\n if (startGraphemeIndex > 0 || (w > fitLimit && breakableFitAdvance !== null)) {\n const fitAdvances = breakableFitAdvance;\n const firstGraphemeWidth = fitAdvances[startGraphemeIndex];\n hasContent = true;\n lineW = firstGraphemeWidth;\n lineEndSegmentIndex = i;\n lineEndGraphemeIndex = startGraphemeIndex + 1;\n for (let g = startGraphemeIndex + 1; g < fitAdvances.length; g++) {\n const gw = fitAdvances[g];\n if (lineW + gw > fitLimit) {\n cursor.segmentIndex = lineEndSegmentIndex;\n cursor.graphemeIndex = lineEndGraphemeIndex;\n return lineW;\n }\n lineW += gw;\n lineEndSegmentIndex = i;\n lineEndGraphemeIndex = g + 1;\n }\n if (lineEndSegmentIndex === i && lineEndGraphemeIndex === fitAdvances.length) {\n lineEndSegmentIndex = i + 1;\n lineEndGraphemeIndex = 0;\n }\n }\n else {\n hasContent = true;\n lineW = w;\n lineEndSegmentIndex = i + 1;\n lineEndGraphemeIndex = 0;\n }\n if (breakAfter) {\n pendingBreakSegmentIndex = i + 1;\n pendingBreakPaintWidth = lineW - w;\n }\n continue;\n }\n if (lineW + w > fitLimit) {\n if (breakAfter) {\n cursor.segmentIndex = i + 1;\n cursor.graphemeIndex = 0;\n return lineW;\n }\n if (pendingBreakSegmentIndex >= 0) {\n if (lineEndSegmentIndex > pendingBreakSegmentIndex ||\n (lineEndSegmentIndex === pendingBreakSegmentIndex && lineEndGraphemeIndex > 0)) {\n cursor.segmentIndex = lineEndSegmentIndex;\n cursor.graphemeIndex = lineEndGraphemeIndex;\n return lineW;\n }\n cursor.segmentIndex = pendingBreakSegmentIndex;\n cursor.graphemeIndex = 0;\n return pendingBreakPaintWidth;\n }\n cursor.segmentIndex = lineEndSegmentIndex;\n cursor.graphemeIndex = lineEndGraphemeIndex;\n return lineW;\n }\n lineW += w;\n lineEndSegmentIndex = i + 1;\n lineEndGraphemeIndex = 0;\n if (breakAfter) {\n pendingBreakSegmentIndex = i + 1;\n pendingBreakPaintWidth = lineW - w;\n }\n }\n if (!hasContent)\n return null;\n cursor.segmentIndex = lineEndSegmentIndex;\n cursor.graphemeIndex = lineEndGraphemeIndex;\n return lineW;\n}\nexport function stepPreparedLineGeometryFromChunk(prepared, cursor, chunkIndex, maxWidth) {\n if (prepared.simpleLineWalkFastPath) {\n return stepPreparedSimpleLineGeometry(prepared, cursor, maxWidth);\n }\n return stepPreparedChunkLineGeometry(prepared, cursor, chunkIndex, maxWidth);\n}\nexport function stepPreparedLineGeometry(prepared, cursor, maxWidth) {\n const chunkIndex = normalizePreparedLineStart(prepared, cursor);\n if (chunkIndex < 0)\n return null;\n return stepPreparedLineGeometryFromChunk(prepared, cursor, chunkIndex, maxWidth);\n}\nexport function measurePreparedLineGeometry(prepared, maxWidth) {\n if (prepared.widths.length === 0) {\n return {\n lineCount: 0,\n maxLineWidth: 0,\n };\n }\n const cursor = {\n segmentIndex: 0,\n graphemeIndex: 0,\n };\n let lineCount = 0;\n let maxLineWidth = 0;\n if (!prepared.simpleLineWalkFastPath) {\n let chunkIndex = normalizePreparedLineStart(prepared, cursor);\n while (chunkIndex >= 0) {\n const lineWidth = stepPreparedChunkLineGeometry(prepared, cursor, chunkIndex, maxWidth);\n if (lineWidth === null) {\n return {\n lineCount,\n maxLineWidth,\n };\n }\n lineCount++;\n if (lineWidth > maxLineWidth)\n maxLineWidth = lineWidth;\n chunkIndex = normalizeLineStartChunkIndexFromHint(prepared, chunkIndex, cursor);\n }\n return {\n lineCount,\n maxLineWidth,\n };\n }\n while (true) {\n const lineWidth = stepPreparedLineGeometry(prepared, cursor, maxWidth);\n if (lineWidth === null) {\n return {\n lineCount,\n maxLineWidth,\n };\n }\n lineCount++;\n if (lineWidth > maxLineWidth)\n maxLineWidth = lineWidth;\n }\n}\n", "let sharedGraphemeSegmenter = null;\nlet sharedLineTextCaches = new WeakMap();\nfunction getSharedGraphemeSegmenter() {\n if (sharedGraphemeSegmenter === null) {\n sharedGraphemeSegmenter = new Intl.Segmenter(undefined, { granularity: 'grapheme' });\n }\n return sharedGraphemeSegmenter;\n}\nfunction getSegmentGraphemes(segmentIndex, segments, cache) {\n let graphemes = cache.get(segmentIndex);\n if (graphemes !== undefined)\n return graphemes;\n graphemes = [];\n const graphemeSegmenter = getSharedGraphemeSegmenter();\n for (const gs of graphemeSegmenter.segment(segments[segmentIndex])) {\n graphemes.push(gs.segment);\n }\n cache.set(segmentIndex, graphemes);\n return graphemes;\n}\nfunction lineHasDiscretionaryHyphen(kinds, startSegmentIndex, endSegmentIndex) {\n return (endSegmentIndex > startSegmentIndex &&\n kinds[endSegmentIndex - 1] === 'soft-hyphen');\n}\nfunction appendSegmentGraphemeRange(text, graphemes, startGraphemeIndex, endGraphemeIndex) {\n for (let i = startGraphemeIndex; i < endGraphemeIndex; i++) {\n text += graphemes[i];\n }\n return text;\n}\nexport function getLineTextCache(prepared) {\n let cache = sharedLineTextCaches.get(prepared);\n if (cache !== undefined)\n return cache;\n cache = new Map();\n sharedLineTextCaches.set(prepared, cache);\n return cache;\n}\nexport function buildLineTextFromRange(prepared, cache, startSegmentIndex, startGraphemeIndex, endSegmentIndex, endGraphemeIndex) {\n let text = '';\n const endsWithDiscretionaryHyphen = lineHasDiscretionaryHyphen(prepared.kinds, startSegmentIndex, endSegmentIndex);\n for (let i = startSegmentIndex; i < endSegmentIndex; i++) {\n if (prepared.kinds[i] === 'soft-hyphen' || prepared.kinds[i] === 'hard-break')\n continue;\n if (i === startSegmentIndex && startGraphemeIndex > 0) {\n const graphemes = getSegmentGraphemes(i, prepared.segments, cache);\n text = appendSegmentGraphemeRange(text, graphemes, startGraphemeIndex, graphemes.length);\n }\n else {\n text += prepared.segments[i];\n }\n }\n if (endGraphemeIndex > 0) {\n if (endsWithDiscretionaryHyphen)\n text += '-';\n const graphemes = getSegmentGraphemes(endSegmentIndex, prepared.segments, cache);\n text = appendSegmentGraphemeRange(text, graphemes, startSegmentIndex === endSegmentIndex ? startGraphemeIndex : 0, endGraphemeIndex);\n }\n else if (endsWithDiscretionaryHyphen) {\n text += '-';\n }\n return text;\n}\nexport function clearLineTextCaches() {\n sharedGraphemeSegmenter = null;\n sharedLineTextCaches = new WeakMap();\n}\n", "// Text measurement for browser environments using canvas measureText.\n//\n// Problem: DOM-based text measurement (getBoundingClientRect, offsetHeight)\n// forces synchronous layout reflow. When components independently measure text,\n// each measurement triggers a reflow of the entire document. This creates\n// read/write interleaving that can cost 30ms+ per frame for 500 text blocks.\n//\n// Solution: two-phase measurement centered around canvas measureText.\n// prepare(text, font) \u2014 segments text via Intl.Segmenter, measures each word\n// via canvas, caches widths, and does one cached DOM calibration read per\n// font when emoji correction is needed. Call once when text first appears.\n// layout(prepared, maxWidth, lineHeight) \u2014 walks cached word widths with pure\n// arithmetic to count lines and compute height. Call on every resize.\n// ~0.0002ms per text.\n//\n// i18n: Intl.Segmenter handles CJK (per-character breaking), Thai, Arabic, etc.\n// Bidi: simplified rich-path metadata for mixed LTR/RTL custom rendering.\n// Punctuation merging: \"better.\" measured as one unit (matches CSS behavior).\n// Trailing whitespace: hangs past line edge without triggering breaks (CSS behavior).\n// overflow-wrap: pre-measured grapheme widths enable character-level word breaking.\n//\n// Emoji correction: Chrome/Firefox canvas measures emoji wider than DOM at font\n// sizes <24px on macOS (Apple Color Emoji). The inflation is constant per emoji\n// grapheme at a given size, font-independent. Auto-detected by comparing canvas\n// vs actual DOM emoji width (one cached DOM read per font). Safari canvas and\n// DOM agree (both wider than fontSize), so correction = 0 there.\n//\n// Limitations:\n// - system-ui font: canvas resolves to different optical variants than DOM on macOS.\n// Use named fonts (Helvetica, Inter, etc.) for guaranteed accuracy.\n// See RESEARCH.md \"Discovery: system-ui font resolution mismatch\".\n//\n// Based on Sebastian Markbage's text-layout research (github.com/chenglou/text-layout).\nimport { computeSegmentLevels } from './bidi.js';\nimport { analyzeText, canContinueKeepAllTextRun, clearAnalysisCaches, endsWithClosingQuote, isCJK, isNumericRunSegment, kinsokuEnd, kinsokuStart, leftStickyPunctuation, setAnalysisLocale, } from './analysis.js';\nimport { clearMeasurementCaches, getCorrectedSegmentWidth, getSegmentBreakableFitAdvances, getEngineProfile, getFontMeasurementState, getSegmentMetrics, textMayContainEmoji, } from './measurement.js';\nimport { countPreparedLines, measurePreparedLineGeometry, normalizePreparedLineStart, stepPreparedLineGeometryFromChunk, walkPreparedLinesRaw, } from './line-break.js';\nimport { buildLineTextFromRange, clearLineTextCaches, getLineTextCache, } from './line-text.js';\nlet sharedGraphemeSegmenter = null;\nfunction getSharedGraphemeSegmenter() {\n if (sharedGraphemeSegmenter === null) {\n sharedGraphemeSegmenter = new Intl.Segmenter(undefined, { granularity: 'grapheme' });\n }\n return sharedGraphemeSegmenter;\n}\n// --- Public API ---\nfunction createEmptyPrepared(includeSegments) {\n if (includeSegments) {\n return {\n widths: [],\n lineEndFitAdvances: [],\n lineEndPaintAdvances: [],\n kinds: [],\n simpleLineWalkFastPath: true,\n segLevels: null,\n breakableFitAdvances: [],\n letterSpacing: 0,\n spacingGraphemeCounts: [],\n discretionaryHyphenWidth: 0,\n tabStopAdvance: 0,\n chunks: [],\n segments: [],\n };\n }\n return {\n widths: [],\n lineEndFitAdvances: [],\n lineEndPaintAdvances: [],\n kinds: [],\n simpleLineWalkFastPath: true,\n segLevels: null,\n breakableFitAdvances: [],\n letterSpacing: 0,\n spacingGraphemeCounts: [],\n discretionaryHyphenWidth: 0,\n tabStopAdvance: 0,\n chunks: [],\n };\n}\nfunction buildBaseCjkUnits(segText, engineProfile) {\n const units = [];\n let unitParts = [];\n let unitStart = 0;\n let unitContainsCJK = false;\n let unitEndsWithClosingQuote = false;\n let unitIsSingleKinsokuEnd = false;\n function pushUnit() {\n if (unitParts.length === 0)\n return;\n units.push({\n text: unitParts.length === 1 ? unitParts[0] : unitParts.join(''),\n start: unitStart,\n });\n unitParts = [];\n unitContainsCJK = false;\n unitEndsWithClosingQuote = false;\n unitIsSingleKinsokuEnd = false;\n }\n function startUnit(grapheme, start, graphemeContainsCJK) {\n unitParts = [grapheme];\n unitStart = start;\n unitContainsCJK = graphemeContainsCJK;\n unitEndsWithClosingQuote = endsWithClosingQuote(grapheme);\n unitIsSingleKinsokuEnd = kinsokuEnd.has(grapheme);\n }\n function appendToUnit(grapheme, graphemeContainsCJK) {\n unitParts.push(grapheme);\n unitContainsCJK = unitContainsCJK || graphemeContainsCJK;\n const graphemeEndsWithClosingQuote = endsWithClosingQuote(grapheme);\n if (grapheme.length === 1 && leftStickyPunctuation.has(grapheme)) {\n unitEndsWithClosingQuote = unitEndsWithClosingQuote || graphemeEndsWithClosingQuote;\n }\n else {\n unitEndsWithClosingQuote = graphemeEndsWithClosingQuote;\n }\n unitIsSingleKinsokuEnd = false;\n }\n for (const gs of getSharedGraphemeSegmenter().segment(segText)) {\n const grapheme = gs.segment;\n const graphemeContainsCJK = isCJK(grapheme);\n if (unitParts.length === 0) {\n startUnit(grapheme, gs.index, graphemeContainsCJK);\n continue;\n }\n if (unitIsSingleKinsokuEnd ||\n kinsokuStart.has(grapheme) ||\n leftStickyPunctuation.has(grapheme) ||\n (engineProfile.carryCJKAfterClosingQuote &&\n graphemeContainsCJK &&\n unitEndsWithClosingQuote)) {\n appendToUnit(grapheme, graphemeContainsCJK);\n continue;\n }\n if (!unitContainsCJK && !graphemeContainsCJK) {\n appendToUnit(grapheme, graphemeContainsCJK);\n continue;\n }\n pushUnit();\n startUnit(grapheme, gs.index, graphemeContainsCJK);\n }\n pushUnit();\n return units;\n}\nfunction mergeKeepAllTextUnits(segText, units, breakAfterPunctuation) {\n if (units.length <= 1)\n return units;\n const merged = [];\n let groupStart = -1;\n let groupContainsCJK = false;\n function pushMergedUnit(start, end) {\n const sourceStart = units[start].start;\n const sourceEnd = end < units.length ? units[end].start : segText.length;\n merged.push({\n text: segText.slice(sourceStart, sourceEnd),\n start: sourceStart,\n });\n }\n function flushGroup(end) {\n if (groupStart < 0)\n return;\n if (groupContainsCJK) {\n if (groupStart + 1 === end) {\n merged.push(units[groupStart]);\n }\n else {\n pushMergedUnit(groupStart, end);\n }\n }\n else {\n for (let i = groupStart; i < end; i++)\n merged.push(units[i]);\n }\n groupStart = -1;\n groupContainsCJK = false;\n }\n for (let i = 0; i < units.length; i++) {\n const unit = units[i];\n if (groupStart >= 0 &&\n !canContinueKeepAllTextRun(units[i - 1].text, breakAfterPunctuation)) {\n flushGroup(i);\n }\n if (groupStart < 0)\n groupStart = i;\n groupContainsCJK = groupContainsCJK || isCJK(unit.text);\n }\n flushGroup(units.length);\n return merged;\n}\nfunction countRenderedSpacingGraphemes(text, kind) {\n if (kind === 'zero-width-break' ||\n kind === 'soft-hyphen' ||\n kind === 'hard-break') {\n return 0;\n }\n if (kind === 'tab')\n return 1;\n let count = 0;\n const graphemeSegmenter = getSharedGraphemeSegmenter();\n for (const _ of graphemeSegmenter.segment(text))\n count++;\n return count;\n}\nfunction addInternalLetterSpacing(width, graphemeCount, letterSpacing) {\n return graphemeCount > 1 ? width + (graphemeCount - 1) * letterSpacing : width;\n}\nfunction measureAnalysis(analysis, font, includeSegments, wordBreak, letterSpacing) {\n const engineProfile = getEngineProfile();\n const { cache, emojiCorrection } = getFontMeasurementState(font, textMayContainEmoji(analysis.normalized));\n const discretionaryHyphenWidth = getCorrectedSegmentWidth('-', getSegmentMetrics('-', cache), emojiCorrection) +\n (letterSpacing === 0 ? 0 : letterSpacing * 2);\n const spaceWidth = getCorrectedSegmentWidth(' ', getSegmentMetrics(' ', cache), emojiCorrection);\n const tabStopAdvance = spaceWidth * 8;\n const hasLetterSpacing = letterSpacing !== 0;\n if (analysis.len === 0)\n return createEmptyPrepared(includeSegments);\n const widths = [];\n const lineEndFitAdvances = [];\n const lineEndPaintAdvances = [];\n const kinds = [];\n let simpleLineWalkFastPath = analysis.chunks.length <= 1 && !hasLetterSpacing;\n const segStarts = includeSegments ? [] : null;\n const breakableFitAdvances = [];\n const spacingGraphemeCounts = [];\n const segments = includeSegments ? [] : null;\n const preparedStartByAnalysisIndex = Array.from({ length: analysis.len });\n function pushMeasuredSegment(text, width, lineEndFitAdvance, lineEndPaintAdvance, kind, start, breakableFitAdvance, spacingGraphemeCount) {\n if (kind !== 'text' && kind !== 'space' && kind !== 'zero-width-break') {\n simpleLineWalkFastPath = false;\n }\n widths.push(width);\n lineEndFitAdvances.push(lineEndFitAdvance);\n lineEndPaintAdvances.push(lineEndPaintAdvance);\n kinds.push(kind);\n segStarts?.push(start);\n breakableFitAdvances.push(breakableFitAdvance);\n if (hasLetterSpacing)\n spacingGraphemeCounts.push(spacingGraphemeCount);\n if (segments !== null)\n segments.push(text);\n }\n function pushMeasuredTextSegment(text, kind, start, wordLike, allowOverflowBreaks) {\n const textMetrics = getSegmentMetrics(text, cache);\n const spacingGraphemeCount = hasLetterSpacing\n ? countRenderedSpacingGraphemes(text, kind)\n : 0;\n const width = addInternalLetterSpacing(getCorrectedSegmentWidth(text, textMetrics, emojiCorrection), spacingGraphemeCount, letterSpacing);\n const baseLineEndFitAdvance = kind === 'space' || kind === 'preserved-space' || kind === 'zero-width-break'\n ? 0\n : width;\n const lineEndFitAdvance = baseLineEndFitAdvance === 0\n ? 0\n : baseLineEndFitAdvance + (spacingGraphemeCount > 0 ? letterSpacing : 0);\n const lineEndPaintAdvance = kind === 'space' || kind === 'zero-width-break'\n ? 0\n : width;\n if (allowOverflowBreaks && wordLike && text.length > 1) {\n let fitMode = 'sum-graphemes';\n if (letterSpacing !== 0) {\n fitMode = 'segment-prefixes';\n }\n else if (isNumericRunSegment(text)) {\n fitMode = 'pair-context';\n }\n else if (engineProfile.preferPrefixWidthsForBreakableRuns) {\n fitMode = 'segment-prefixes';\n }\n const fitAdvances = getSegmentBreakableFitAdvances(text, textMetrics, cache, emojiCorrection, fitMode);\n pushMeasuredSegment(text, width, lineEndFitAdvance, lineEndPaintAdvance, kind, start, fitAdvances, spacingGraphemeCount);\n return;\n }\n pushMeasuredSegment(text, width, lineEndFitAdvance, lineEndPaintAdvance, kind, start, null, spacingGraphemeCount);\n }\n for (let mi = 0; mi < analysis.len; mi++) {\n preparedStartByAnalysisIndex[mi] = widths.length;\n const segText = analysis.texts[mi];\n const segWordLike = analysis.isWordLike[mi];\n const segKind = analysis.kinds[mi];\n const segStart = analysis.starts[mi];\n if (segKind === 'soft-hyphen') {\n pushMeasuredSegment(segText, 0, discretionaryHyphenWidth, discretionaryHyphenWidth, segKind, segStart, null, 0);\n continue;\n }\n if (segKind === 'hard-break') {\n pushMeasuredSegment(segText, 0, 0, 0, segKind, segStart, null, 0);\n continue;\n }\n if (segKind === 'tab') {\n pushMeasuredSegment(segText, 0, 0, 0, segKind, segStart, null, hasLetterSpacing ? countRenderedSpacingGraphemes(segText, segKind) : 0);\n continue;\n }\n const segMetrics = getSegmentMetrics(segText, cache);\n if (segKind === 'text' && segMetrics.containsCJK) {\n const baseUnits = buildBaseCjkUnits(segText, engineProfile);\n const measuredUnits = wordBreak === 'keep-all'\n ? mergeKeepAllTextUnits(segText, baseUnits, engineProfile.breakKeepAllAfterPunctuation)\n : baseUnits;\n for (let i = 0; i < measuredUnits.length; i++) {\n const unit = measuredUnits[i];\n pushMeasuredTextSegment(unit.text, 'text', segStart + unit.start, segWordLike, wordBreak === 'keep-all' || !isCJK(unit.text));\n }\n continue;\n }\n pushMeasuredTextSegment(segText, segKind, segStart, segWordLike, true);\n }\n const chunks = mapAnalysisChunksToPreparedChunks(analysis.chunks, preparedStartByAnalysisIndex, widths.length);\n const segLevels = segStarts === null ? null : computeSegmentLevels(analysis.normalized, segStarts);\n if (segments !== null) {\n return {\n widths,\n lineEndFitAdvances,\n lineEndPaintAdvances,\n kinds,\n simpleLineWalkFastPath,\n segLevels,\n breakableFitAdvances,\n letterSpacing,\n spacingGraphemeCounts,\n discretionaryHyphenWidth,\n tabStopAdvance,\n chunks,\n segments,\n };\n }\n return {\n widths,\n lineEndFitAdvances,\n lineEndPaintAdvances,\n kinds,\n simpleLineWalkFastPath,\n segLevels,\n breakableFitAdvances,\n letterSpacing,\n spacingGraphemeCounts,\n discretionaryHyphenWidth,\n tabStopAdvance,\n chunks,\n };\n}\nfunction mapAnalysisChunksToPreparedChunks(chunks, preparedStartByAnalysisIndex, preparedEndSegmentIndex) {\n const preparedChunks = [];\n for (let i = 0; i < chunks.length; i++) {\n const chunk = chunks[i];\n const startSegmentIndex = chunk.startSegmentIndex < preparedStartByAnalysisIndex.length\n ? preparedStartByAnalysisIndex[chunk.startSegmentIndex]\n : preparedEndSegmentIndex;\n const endSegmentIndex = chunk.endSegmentIndex < preparedStartByAnalysisIndex.length\n ? preparedStartByAnalysisIndex[chunk.endSegmentIndex]\n : preparedEndSegmentIndex;\n const consumedEndSegmentIndex = chunk.consumedEndSegmentIndex < preparedStartByAnalysisIndex.length\n ? preparedStartByAnalysisIndex[chunk.consumedEndSegmentIndex]\n : preparedEndSegmentIndex;\n preparedChunks.push({\n startSegmentIndex,\n endSegmentIndex,\n consumedEndSegmentIndex,\n });\n }\n return preparedChunks;\n}\nfunction prepareInternal(text, font, includeSegments, options) {\n const wordBreak = options?.wordBreak ?? 'normal';\n const letterSpacing = options?.letterSpacing ?? 0;\n const analysis = analyzeText(text, getEngineProfile(), options?.whiteSpace, wordBreak);\n return measureAnalysis(analysis, font, includeSegments, wordBreak, letterSpacing);\n}\n// Prepare text for layout. Segments the text, measures each segment via canvas,\n// and stores the widths for fast relayout at any width. Call once per text block\n// (e.g. when a comment first appears). The result is width-independent \u2014 the\n// same PreparedText can be laid out at any maxWidth and lineHeight via layout().\n//\n// Steps:\n// 1. Normalize collapsible whitespace (CSS white-space: normal behavior)\n// 2. Segment via Intl.Segmenter (handles CJK, Thai, etc.)\n// 3. Merge punctuation into preceding word (\"better.\" as one unit)\n// 4. Split CJK words into individual graphemes (per-character line breaks)\n// 5. Measure each segment via canvas measureText, cache by (segment, font)\n// 6. Pre-measure graphemes of long words (for overflow-wrap: break-word)\n// 7. Correct emoji canvas inflation (auto-detected per font size)\n// 8. Optionally compute rich-path bidi metadata for custom renderers\nexport function prepare(text, font, options) {\n return prepareInternal(text, font, false, options);\n}\n// Rich variant used by callers that need enough information to render the\n// laid-out lines themselves.\nexport function prepareWithSegments(text, font, options) {\n return prepareInternal(text, font, true, options);\n}\nfunction getInternalPrepared(prepared) {\n return prepared;\n}\n// Layout prepared text at a given max width and caller-provided lineHeight.\n// Pure arithmetic on cached widths \u2014 no canvas calls, no DOM reads, no string\n// operations, no allocations.\n// ~0.0002ms per text block. Call on every resize.\n//\n// Line breaking rules (matching CSS white-space: normal + overflow-wrap: break-word):\n// - Break before any non-space segment that would overflow the line\n// - Trailing whitespace hangs past the line edge (doesn't trigger breaks)\n// - Segments wider than maxWidth are broken at grapheme boundaries\nexport function layout(prepared, maxWidth, lineHeight) {\n // Keep the resize hot path specialized. `layoutWithLines()` shares the same\n // break semantics but also tracks line ranges; the extra bookkeeping is too\n // expensive to pay on every hot-path `layout()` call.\n const lineCount = countPreparedLines(getInternalPrepared(prepared), maxWidth);\n return { lineCount, height: lineCount * lineHeight };\n}\nfunction createLayoutLine(prepared, cache, width, startSegmentIndex, startGraphemeIndex, endSegmentIndex, endGraphemeIndex) {\n return {\n text: buildLineTextFromRange(prepared, cache, startSegmentIndex, startGraphemeIndex, endSegmentIndex, endGraphemeIndex),\n width,\n start: {\n segmentIndex: startSegmentIndex,\n graphemeIndex: startGraphemeIndex,\n },\n end: {\n segmentIndex: endSegmentIndex,\n graphemeIndex: endGraphemeIndex,\n },\n };\n}\nfunction createLayoutLineRange(width, startSegmentIndex, startGraphemeIndex, endSegmentIndex, endGraphemeIndex) {\n return {\n width,\n start: {\n segmentIndex: startSegmentIndex,\n graphemeIndex: startGraphemeIndex,\n },\n end: {\n segmentIndex: endSegmentIndex,\n graphemeIndex: endGraphemeIndex,\n },\n };\n}\nexport function materializeLineRange(prepared, line) {\n return createLayoutLine(prepared, getLineTextCache(prepared), line.width, line.start.segmentIndex, line.start.graphemeIndex, line.end.segmentIndex, line.end.graphemeIndex);\n}\n// Batch low-level line-range pass. This is the non-materializing counterpart\n// to layoutWithLines(), useful for shrinkwrap and other aggregate stats work.\nexport function walkLineRanges(prepared, maxWidth, onLine) {\n if (prepared.widths.length === 0)\n return 0;\n return walkPreparedLinesRaw(getInternalPrepared(prepared), maxWidth, (width, startSegmentIndex, startGraphemeIndex, endSegmentIndex, endGraphemeIndex) => {\n onLine(createLayoutLineRange(width, startSegmentIndex, startGraphemeIndex, endSegmentIndex, endGraphemeIndex));\n });\n}\nexport function measureLineStats(prepared, maxWidth) {\n return measurePreparedLineGeometry(getInternalPrepared(prepared), maxWidth);\n}\n// Intrinsic-width helper for rich/userland layout work. This asks \"how wide is\n// the prepared text when container width is not the thing forcing wraps?\".\n// Explicit hard breaks still count, so this returns the widest forced line.\nexport function measureNaturalWidth(prepared) {\n let maxWidth = 0;\n walkPreparedLinesRaw(getInternalPrepared(prepared), Number.POSITIVE_INFINITY, width => {\n if (width > maxWidth)\n maxWidth = width;\n });\n return maxWidth;\n}\nexport function layoutNextLine(prepared, start, maxWidth) {\n const internal = getInternalPrepared(prepared);\n const end = {\n segmentIndex: start.segmentIndex,\n graphemeIndex: start.graphemeIndex,\n };\n const chunkIndex = normalizePreparedLineStart(internal, end);\n if (chunkIndex < 0)\n return null;\n const lineStartSegmentIndex = end.segmentIndex;\n const lineStartGraphemeIndex = end.graphemeIndex;\n const width = stepPreparedLineGeometryFromChunk(internal, end, chunkIndex, maxWidth);\n if (width === null)\n return null;\n return createLayoutLine(prepared, getLineTextCache(prepared), width, lineStartSegmentIndex, lineStartGraphemeIndex, end.segmentIndex, end.graphemeIndex);\n}\nexport function layoutNextLineRange(prepared, start, maxWidth) {\n const internal = getInternalPrepared(prepared);\n const end = {\n segmentIndex: start.segmentIndex,\n graphemeIndex: start.graphemeIndex,\n };\n const chunkIndex = normalizePreparedLineStart(internal, end);\n if (chunkIndex < 0)\n return null;\n const lineStartSegmentIndex = end.segmentIndex;\n const lineStartGraphemeIndex = end.graphemeIndex;\n const width = stepPreparedLineGeometryFromChunk(internal, end, chunkIndex, maxWidth);\n if (width === null)\n return null;\n return createLayoutLineRange(width, lineStartSegmentIndex, lineStartGraphemeIndex, end.segmentIndex, end.graphemeIndex);\n}\n// Rich layout API for callers that want the actual line contents and widths.\n// Caller still supplies lineHeight at layout time. Mirrors layout()'s break\n// decisions, but keeps extra per-line bookkeeping so it should stay off the\n// resize hot path.\nexport function layoutWithLines(prepared, maxWidth, lineHeight) {\n const lines = [];\n if (prepared.widths.length === 0)\n return { lineCount: 0, height: 0, lines };\n const graphemeCache = getLineTextCache(prepared);\n const lineCount = walkPreparedLinesRaw(getInternalPrepared(prepared), maxWidth, (width, startSegmentIndex, startGraphemeIndex, endSegmentIndex, endGraphemeIndex) => {\n lines.push(createLayoutLine(prepared, graphemeCache, width, startSegmentIndex, startGraphemeIndex, endSegmentIndex, endGraphemeIndex));\n });\n return { lineCount, height: lineCount * lineHeight, lines };\n}\nexport function clearCache() {\n clearAnalysisCaches();\n sharedGraphemeSegmenter = null;\n clearLineTextCaches();\n clearMeasurementCaches();\n}\nexport function setLocale(locale) {\n setAnalysisLocale(locale);\n clearCache();\n}\n", "import { measureNaturalWidth, prepareWithSegments, } from './layout.js';\nimport { buildLineTextFromRange, getLineTextCache, } from './line-text.js';\nimport { stepPreparedLineGeometry, } from './line-break.js';\nconst COLLAPSIBLE_BOUNDARY_RE = /[ \\t\\n\\f\\r]+/;\nconst LEADING_COLLAPSIBLE_BOUNDARY_RE = /^[ \\t\\n\\f\\r]+/;\nconst TRAILING_COLLAPSIBLE_BOUNDARY_RE = /[ \\t\\n\\f\\r]+$/;\nconst EMPTY_LAYOUT_CURSOR = { segmentIndex: 0, graphemeIndex: 0 };\nconst RICH_INLINE_START_CURSOR = {\n itemIndex: 0,\n segmentIndex: 0,\n graphemeIndex: 0,\n};\nfunction getInternalPreparedRichInline(prepared) {\n return prepared;\n}\nfunction cloneCursor(cursor) {\n return {\n segmentIndex: cursor.segmentIndex,\n graphemeIndex: cursor.graphemeIndex,\n };\n}\nfunction isLineStartCursor(cursor) {\n return cursor.segmentIndex === 0 && cursor.graphemeIndex === 0;\n}\nfunction getCollapsedSpaceWidth(font, letterSpacing, cache) {\n const cacheKey = `${font}\\u0000${letterSpacing}`;\n const cached = cache.get(cacheKey);\n if (cached !== undefined)\n return cached;\n const options = letterSpacing === 0 ? undefined : { letterSpacing };\n const joinedWidth = measureNaturalWidth(prepareWithSegments('A A', font, options));\n const compactWidth = measureNaturalWidth(prepareWithSegments('AA', font, options));\n const collapsedWidth = Math.max(0, joinedWidth - compactWidth);\n cache.set(cacheKey, collapsedWidth);\n return collapsedWidth;\n}\nfunction prepareWholeItemLine(prepared) {\n const end = { segmentIndex: 0, graphemeIndex: 0 };\n const width = stepPreparedLineGeometry(prepared, end, Number.POSITIVE_INFINITY);\n if (width === null)\n return null;\n return {\n endGraphemeIndex: end.graphemeIndex,\n endSegmentIndex: end.segmentIndex,\n width,\n };\n}\nfunction endsInsideFirstSegment(segmentIndex, graphemeIndex) {\n return segmentIndex === 0 && graphemeIndex > 0;\n}\nexport function prepareRichInline(items) {\n const preparedItems = [];\n const itemsBySourceItemIndex = Array.from({ length: items.length });\n const collapsedSpaceWidthCache = new Map();\n let pendingGapWidth = 0;\n for (let index = 0; index < items.length; index++) {\n const item = items[index];\n const letterSpacing = item.letterSpacing ?? 0;\n const hasLeadingWhitespace = LEADING_COLLAPSIBLE_BOUNDARY_RE.test(item.text);\n const hasTrailingWhitespace = TRAILING_COLLAPSIBLE_BOUNDARY_RE.test(item.text);\n const trimmedText = item.text\n .replace(LEADING_COLLAPSIBLE_BOUNDARY_RE, '')\n .replace(TRAILING_COLLAPSIBLE_BOUNDARY_RE, '');\n if (trimmedText.length === 0) {\n if (COLLAPSIBLE_BOUNDARY_RE.test(item.text) && pendingGapWidth === 0) {\n pendingGapWidth = getCollapsedSpaceWidth(item.font, letterSpacing, collapsedSpaceWidthCache);\n }\n continue;\n }\n const gapBefore = pendingGapWidth > 0\n ? pendingGapWidth\n : hasLeadingWhitespace\n ? getCollapsedSpaceWidth(item.font, letterSpacing, collapsedSpaceWidthCache)\n : 0;\n const prepared = prepareWithSegments(trimmedText, item.font, letterSpacing === 0 ? undefined : { letterSpacing });\n const wholeLine = prepareWholeItemLine(prepared);\n if (wholeLine === null) {\n pendingGapWidth = hasTrailingWhitespace\n ? getCollapsedSpaceWidth(item.font, letterSpacing, collapsedSpaceWidthCache)\n : 0;\n continue;\n }\n const preparedItem = {\n break: item.break ?? 'normal',\n endGraphemeIndex: wholeLine.endGraphemeIndex,\n endSegmentIndex: wholeLine.endSegmentIndex,\n extraWidth: item.extraWidth ?? 0,\n gapBefore,\n naturalWidth: wholeLine.width,\n prepared,\n sourceItemIndex: index,\n };\n preparedItems.push(preparedItem);\n itemsBySourceItemIndex[index] = preparedItem;\n pendingGapWidth = hasTrailingWhitespace\n ? getCollapsedSpaceWidth(item.font, letterSpacing, collapsedSpaceWidthCache)\n : 0;\n }\n return {\n items: preparedItems,\n itemsBySourceItemIndex,\n };\n}\nfunction stepRichInlineLine(flow, maxWidth, cursor, collectFragment) {\n if (flow.items.length === 0 || cursor.itemIndex >= flow.items.length)\n return null;\n const safeWidth = Math.max(1, maxWidth);\n let lineWidth = 0;\n let remainingWidth = safeWidth;\n let itemIndex = cursor.itemIndex;\n lineLoop: while (itemIndex < flow.items.length) {\n const item = flow.items[itemIndex];\n if (!isLineStartCursor(cursor) &&\n cursor.segmentIndex === item.endSegmentIndex &&\n cursor.graphemeIndex === item.endGraphemeIndex) {\n itemIndex++;\n cursor.segmentIndex = 0;\n cursor.graphemeIndex = 0;\n continue;\n }\n const gapBefore = lineWidth === 0 ? 0 : item.gapBefore;\n const atItemStart = isLineStartCursor(cursor);\n if (item.break === 'never') {\n if (!atItemStart) {\n itemIndex++;\n cursor.segmentIndex = 0;\n cursor.graphemeIndex = 0;\n continue;\n }\n const occupiedWidth = item.naturalWidth + item.extraWidth;\n const totalWidth = gapBefore + occupiedWidth;\n if (lineWidth > 0 && totalWidth > remainingWidth)\n break lineLoop;\n collectFragment?.(item, gapBefore, occupiedWidth, cloneCursor(EMPTY_LAYOUT_CURSOR), {\n segmentIndex: item.endSegmentIndex,\n graphemeIndex: item.endGraphemeIndex,\n });\n lineWidth += totalWidth;\n remainingWidth = Math.max(0, safeWidth - lineWidth);\n itemIndex++;\n cursor.segmentIndex = 0;\n cursor.graphemeIndex = 0;\n continue;\n }\n const reservedWidth = gapBefore + item.extraWidth;\n if (lineWidth > 0 && reservedWidth >= remainingWidth)\n break lineLoop;\n if (atItemStart) {\n const totalWidth = reservedWidth + item.naturalWidth;\n if (totalWidth <= remainingWidth) {\n collectFragment?.(item, gapBefore, item.naturalWidth + item.extraWidth, cloneCursor(EMPTY_LAYOUT_CURSOR), {\n segmentIndex: item.endSegmentIndex,\n graphemeIndex: item.endGraphemeIndex,\n });\n lineWidth += totalWidth;\n remainingWidth = Math.max(0, safeWidth - lineWidth);\n itemIndex++;\n cursor.segmentIndex = 0;\n cursor.graphemeIndex = 0;\n continue;\n }\n }\n const availableWidth = Math.max(1, remainingWidth - reservedWidth);\n const lineEnd = {\n segmentIndex: cursor.segmentIndex,\n graphemeIndex: cursor.graphemeIndex,\n };\n const lineWidthForItem = stepPreparedLineGeometry(item.prepared, lineEnd, availableWidth);\n if (lineWidthForItem === null) {\n itemIndex++;\n cursor.segmentIndex = 0;\n cursor.graphemeIndex = 0;\n continue;\n }\n if (cursor.segmentIndex === lineEnd.segmentIndex &&\n cursor.graphemeIndex === lineEnd.graphemeIndex) {\n itemIndex++;\n cursor.segmentIndex = 0;\n cursor.graphemeIndex = 0;\n continue;\n }\n const itemOccupiedWidth = lineWidthForItem + item.extraWidth;\n const lineWidthContribution = gapBefore + itemOccupiedWidth;\n // The lower-level walker may force one unit to make progress. If that unit\n // only fits on a fresh line, wrap before this rich item instead.\n if (lineWidth > 0 && atItemStart && lineWidthContribution > remainingWidth)\n break lineLoop;\n // If the only thing we can fit after paying the boundary gap is a partial\n // slice of the item's first segment, prefer wrapping before the item so we\n // keep whole-word-style boundaries when they exist. But once the current\n // line can consume a real breakable unit from the item, stay greedy and\n // keep filling the line.\n if (lineWidth > 0 &&\n atItemStart &&\n gapBefore > 0 &&\n endsInsideFirstSegment(lineEnd.segmentIndex, lineEnd.graphemeIndex)) {\n const freshLineEnd = { segmentIndex: 0, graphemeIndex: 0 };\n const freshLineWidth = stepPreparedLineGeometry(item.prepared, freshLineEnd, Math.max(1, safeWidth - item.extraWidth));\n if (freshLineWidth !== null &&\n (freshLineEnd.segmentIndex > lineEnd.segmentIndex ||\n (freshLineEnd.segmentIndex === lineEnd.segmentIndex &&\n freshLineEnd.graphemeIndex > lineEnd.graphemeIndex))) {\n break lineLoop;\n }\n }\n collectFragment?.(item, gapBefore, itemOccupiedWidth, cloneCursor(cursor), {\n segmentIndex: lineEnd.segmentIndex,\n graphemeIndex: lineEnd.graphemeIndex,\n });\n lineWidth += lineWidthContribution;\n remainingWidth = Math.max(0, safeWidth - lineWidth);\n if (lineEnd.segmentIndex === item.endSegmentIndex &&\n lineEnd.graphemeIndex === item.endGraphemeIndex) {\n itemIndex++;\n cursor.segmentIndex = 0;\n cursor.graphemeIndex = 0;\n continue;\n }\n cursor.segmentIndex = lineEnd.segmentIndex;\n cursor.graphemeIndex = lineEnd.graphemeIndex;\n break;\n }\n if (lineWidth === 0)\n return null;\n cursor.itemIndex = itemIndex;\n return lineWidth;\n}\nexport function layoutNextRichInlineLineRange(prepared, maxWidth, start = RICH_INLINE_START_CURSOR) {\n const flow = getInternalPreparedRichInline(prepared);\n const end = {\n itemIndex: start.itemIndex,\n segmentIndex: start.segmentIndex,\n graphemeIndex: start.graphemeIndex,\n };\n const fragments = [];\n const width = stepRichInlineLine(flow, maxWidth, end, (item, gapBefore, occupiedWidth, fragmentStart, fragmentEnd) => {\n fragments.push({\n itemIndex: item.sourceItemIndex,\n gapBefore,\n occupiedWidth,\n start: fragmentStart,\n end: fragmentEnd,\n });\n });\n if (width === null)\n return null;\n return {\n fragments,\n width,\n end,\n };\n}\nfunction materializeFragmentText(item, fragment) {\n return buildLineTextFromRange(item.prepared, getLineTextCache(item.prepared), fragment.start.segmentIndex, fragment.start.graphemeIndex, fragment.end.segmentIndex, fragment.end.graphemeIndex);\n}\n// Bridge from cheap range walking to full fragment text. Lets callers do\n// shrinkwrap/virtualization/probing work first, then only pay for text on the\n// lines they actually render.\nexport function materializeRichInlineLineRange(prepared, line) {\n const flow = getInternalPreparedRichInline(prepared);\n const fragments = [];\n for (let i = 0; i < line.fragments.length; i++) {\n const fragment = line.fragments[i];\n const item = flow.itemsBySourceItemIndex[fragment.itemIndex];\n if (item === undefined)\n throw new Error('Missing rich-text inline item for fragment');\n fragments.push({\n itemIndex: fragment.itemIndex,\n text: materializeFragmentText(item, fragment),\n gapBefore: fragment.gapBefore,\n occupiedWidth: fragment.occupiedWidth,\n start: fragment.start,\n end: fragment.end,\n });\n }\n return {\n fragments,\n width: line.width,\n end: line.end,\n };\n}\nexport function walkRichInlineLineRanges(prepared, maxWidth, onLine) {\n let lineCount = 0;\n let cursor = RICH_INLINE_START_CURSOR;\n while (true) {\n const line = layoutNextRichInlineLineRange(prepared, maxWidth, cursor);\n if (line === null)\n return lineCount;\n onLine(line);\n lineCount++;\n cursor = line.end;\n }\n}\nexport function measureRichInlineStats(prepared, maxWidth) {\n const flow = getInternalPreparedRichInline(prepared);\n let lineCount = 0;\n let maxLineWidth = 0;\n const cursor = {\n itemIndex: 0,\n segmentIndex: 0,\n graphemeIndex: 0,\n };\n while (true) {\n const lineWidth = stepRichInlineLine(flow, maxWidth, cursor);\n if (lineWidth === null) {\n return {\n lineCount,\n maxLineWidth,\n };\n }\n lineCount++;\n if (lineWidth > maxLineWidth)\n maxLineWidth = lineWidth;\n }\n}\n", "// The math typesetter's output: a MathBox \u2014 a flattened, absolutely-positioned\r\n// set of glyphs and rules (filled rectangles: fraction bars, radical lines) in\r\n// box-local coordinates. Flattening as we compose means the painters (canvas +\r\n// PDF) consume one glyph list and one rule list with no recursion.\r\n//\r\n// Coordinate convention (matches canvas): x grows right, y grows DOWN, the\r\n// box BASELINE is y = 0. `ascent` is the distance above the baseline (a positive\r\n// number), `descent` the distance below. Total height = ascent + descent.\r\n\r\n/** A single glyph to paint at its baseline origin. */\r\nexport interface PlacedGlyph {\r\n x: number;\r\n /** Baseline y (text is drawn from the baseline). */\r\n y: number;\r\n text: string;\r\n sizePx: number;\r\n italic: boolean;\r\n bold: boolean;\r\n}\r\n\r\n/** A filled rectangle (fraction/radical rule, bar). */\r\nexport interface PlacedRule {\r\n x: number;\r\n y: number;\r\n w: number;\r\n h: number;\r\n}\r\n\r\nexport interface MathBox {\r\n width: number;\r\n ascent: number;\r\n descent: number;\r\n glyphs: PlacedGlyph[];\r\n rules: PlacedRule[];\r\n /** Italic correction of the box's last glyph \u2014 used when attaching a\r\n * superscript so it clears a slanted base (e.g. f'). 0 for upright content. */\r\n italicCorrection: number;\r\n}\r\n\r\nexport const emptyBox = (): MathBox => ({\r\n width: 0,\r\n ascent: 0,\r\n descent: 0,\r\n glyphs: [],\r\n rules: [],\r\n italicCorrection: 0,\r\n});\r\n\r\n/** Translate a box by (dx, dy); dy>0 moves content DOWN. Returns a new box. */\r\nexport function shiftBox(b: MathBox, dx: number, dy: number): MathBox {\r\n return {\r\n width: b.width,\r\n ascent: b.ascent - dy,\r\n descent: b.descent + dy,\r\n italicCorrection: b.italicCorrection,\r\n glyphs: b.glyphs.map((g) => ({ ...g, x: g.x + dx, y: g.y + dy })),\r\n rules: b.rules.map((r) => ({ ...r, x: r.x + dx, y: r.y + dy })),\r\n };\r\n}\r\n\r\n/** Place boxes left-to-right on a shared baseline, inserting `gaps[i]` of\r\n * horizontal space BEFORE box i (gaps default 0). */\r\nexport function hbox(boxes: MathBox[], gaps: number[] = []): MathBox {\r\n let x = 0;\r\n let ascent = 0;\r\n let descent = 0;\r\n const glyphs: PlacedGlyph[] = [];\r\n const rules: PlacedRule[] = [];\r\n for (let i = 0; i < boxes.length; i++) {\r\n x += gaps[i] ?? 0;\r\n const b = boxes[i]!;\r\n for (const g of b.glyphs) glyphs.push({ ...g, x: g.x + x });\r\n for (const r of b.rules) rules.push({ ...r, x: r.x + x });\r\n ascent = Math.max(ascent, b.ascent);\r\n descent = Math.max(descent, b.descent);\r\n x += b.width;\r\n }\r\n const last = boxes[boxes.length - 1];\r\n return { width: x, ascent, descent, glyphs, rules, italicCorrection: last?.italicCorrection ?? 0 };\r\n}\r\n\r\n/** Overlay already-positioned boxes at a shared origin (no horizontal advance):\r\n * used to merge the vertically-shifted parts of a fraction / script / radical\r\n * into one box. Metrics are the union; width is the max (callers set the final\r\n * width explicitly when it differs). `align` is reserved for future use. */\r\nexport function overlayCentered(boxes: MathBox[], _align: \"left\" | \"center\" = \"left\"): MathBox {\r\n const glyphs: PlacedGlyph[] = [];\r\n const rules: PlacedRule[] = [];\r\n let ascent = 0;\r\n let descent = 0;\r\n let width = 0;\r\n let italicCorrection = 0;\r\n for (const b of boxes) {\r\n glyphs.push(...b.glyphs);\r\n rules.push(...b.rules);\r\n ascent = Math.max(ascent, b.ascent);\r\n descent = Math.max(descent, b.descent);\r\n width = Math.max(width, b.width);\r\n italicCorrection = b.italicCorrection;\r\n }\r\n return { width, ascent, descent, glyphs, rules, italicCorrection };\r\n}\r\n\r\n/** A bare horizontal rule (e.g. fraction bar). `topAboveBaseline` is the distance\r\n * from the baseline to the rule's BOTTOM edge (positive = up); the rule occupies\r\n * `[-topAboveBaseline - thickness, -topAboveBaseline]`. ascent/descent are kept\r\n * non-negative per the box contract (a rule entirely above the baseline has 0\r\n * descent), so it never reports a negative extent into `overlayCentered`. */\r\nexport function ruleBox(width: number, thickness: number, topAboveBaseline: number): MathBox {\r\n const ruleTop = -topAboveBaseline - thickness;\r\n const ruleBottom = -topAboveBaseline;\r\n return {\r\n width,\r\n ascent: Math.max(0, -ruleTop),\r\n descent: Math.max(0, ruleBottom),\r\n italicCorrection: 0,\r\n glyphs: [],\r\n rules: [{ x: 0, y: ruleTop, w: width, h: thickness }],\r\n };\r\n}\r\n\r\n/** Horizontal padding box (no ink). */\r\nexport const spaceBox = (width: number): MathBox => ({\r\n width,\r\n ascent: 0,\r\n descent: 0,\r\n glyphs: [],\r\n rules: [],\r\n italicCorrection: 0,\r\n});\r\n\r\n/** Overall pixel bounds of a laid-out equation (for the inline/replaced box). */\r\nexport const boxHeight = (b: MathBox): number => b.ascent + b.descent;\r\n", "// Map a math identifier character to its styled Unicode code point in the\r\n// Mathematical Alphanumeric Symbols block, so a single upright math font (STIX\r\n// Two Math) renders TRUE italic/bold/blackboard/script glyphs \u2014 no faux-slanting.\r\n// MathML <mi> defaults to italic; <mi mathvariant=\"\u2026\"> selects the others.\r\n//\r\n// The block is contiguous EXCEPT for letters that already existed in the\r\n// Letterlike Symbols block (Unicode left \"holes\" and points there instead); those\r\n// exceptions are tabled below. Greek follows the same scheme.\r\n\r\nimport type { MathVariant } from \"@cw/shared\";\r\n\r\nconst A = 0x41, Z = 0x5a, a = 0x61, z = 0x7a;\r\nconst isAsciiUpper = (c: number): boolean => c >= A && c <= Z;\r\nconst isAsciiLower = (c: number): boolean => c >= a && c <= z;\r\n\r\n// Base code points for 'A' of each variant (lower base = upper base + 26).\r\nconst BASE: Partial<Record<MathVariant, number>> = {\r\n bold: 0x1d400,\r\n italic: 0x1d434,\r\n \"bold-italic\": 0x1d468,\r\n script: 0x1d49c,\r\n \"bold-script\": 0x1d4d0,\r\n fraktur: 0x1d504,\r\n \"double-struck\": 0x1d538,\r\n \"bold-fraktur\": 0x1d56c,\r\n \"sans-serif\": 0x1d5a0,\r\n \"bold-sans-serif\": 0x1d5d4,\r\n \"sans-serif-italic\": 0x1d608,\r\n \"sans-serif-bold-italic\": 0x1d63c,\r\n monospace: 0x1d670,\r\n};\r\n\r\n// Letters that live in the Letterlike Symbols block instead of the contiguous run.\r\nconst HOLES: Partial<Record<MathVariant, Record<string, number>>> = {\r\n italic: { h: 0x210e },\r\n script: {\r\n B: 0x212c, E: 0x2130, F: 0x2131, H: 0x210b, I: 0x2110, L: 0x2112, M: 0x2133, R: 0x211b,\r\n e: 0x212f, g: 0x210a, o: 0x2134,\r\n },\r\n fraktur: { C: 0x212d, H: 0x210c, I: 0x2111, R: 0x211c, Z: 0x2128 },\r\n \"double-struck\": { C: 0x2102, H: 0x210d, N: 0x2115, P: 0x2119, Q: 0x211a, R: 0x211d, Z: 0x2124 },\r\n};\r\n\r\n// Greek math blocks. The uppercase math block reserves a slot (the theta-symbol\r\n// variant) exactly where Unicode Greek reserves U+03A2 between \u03A1 and \u03A3, so the\r\n// straight `cp - GREEK_UPPER` offset stays aligned across the whole range\r\n// (\u0391 0x391\u21920x1D6E2 \u2026 \u03A9 0x3A9\u21920x1D6FA). Italic is the default; bold-italic Greek\r\n// has its own block, so don't fold it into italic.\r\nconst GREEK_UPPER = 0x391, GREEK_LOWER = 0x3b1, GREEK_LAST_LOWER = 0x3c9;\r\nconst GREEK_BASE: Partial<Record<MathVariant, { upper: number; lower: number }>> = {\r\n italic: { upper: 0x1d6e2, lower: 0x1d6fc },\r\n \"bold-italic\": { upper: 0x1d71c, lower: 0x1d736 },\r\n bold: { upper: 0x1d6a8, lower: 0x1d6c2 },\r\n};\r\n\r\n/** The code point STIX should render for an identifier char under `variant`\r\n * (default = italic). Non-letters and unmapped chars return their own code point. */\r\nexport function styledMathCodePoint(ch: string, variant: MathVariant | undefined): number {\r\n const cp = ch.codePointAt(0) ?? 0;\r\n const v: MathVariant = variant ?? \"italic\";\r\n if (v === \"normal\") return cp;\r\n\r\n // ASCII letters.\r\n if (isAsciiUpper(cp) || isAsciiLower(cp)) {\r\n const hole = HOLES[v]?.[ch];\r\n if (hole) return hole;\r\n const base = BASE[v];\r\n if (base === undefined) return cp;\r\n return isAsciiUpper(cp) ? base + (cp - A) : base + 26 + (cp - a);\r\n }\r\n\r\n // Greek letters \u2014 italic / bold-italic / bold (other variants fall back to the\r\n // literal char, which still renders upright in STIX).\r\n const gb = GREEK_BASE[v];\r\n if (gb) {\r\n if (cp >= GREEK_UPPER && cp <= GREEK_UPPER + 24) return gb.upper + (cp - GREEK_UPPER);\r\n if (cp >= GREEK_LOWER && cp <= GREEK_LAST_LOWER) return gb.lower + (cp - GREEK_LOWER);\r\n }\r\n return cp;\r\n}\r\n\r\n/** Styled string for a SINGLE-character identifier (the common case). Multi-char\r\n * identifiers (function names like \"sin\"/\"log\") render upright unchanged. */\r\nexport function styledMathText(text: string, variant: MathVariant | undefined): string {\r\n if ([...text].length !== 1) return text;\r\n return String.fromCodePoint(styledMathCodePoint(text, variant));\r\n}\r\n", "// The math typesetter: a MathML AST node -> a positioned MathBox. Pure (depends\r\n// only on the injected MathFont provider), so it runs in the editor, the PDF\r\n// exporter, and unit tests alike. Geometry follows classic TeX rules; the\r\n// constants come from the provider (TeX defaults today, STIX MATH table later).\r\n\r\nimport type { MathNode } from \"@cw/shared\";\r\nimport { boxHeight, emptyBox, hbox, type MathBox, overlayCentered, ruleBox, shiftBox, spaceBox } from \"./mathBox\";\r\nimport type { MathFont } from \"./mathFont\";\r\nimport { styledMathText } from \"./mathAlpha\";\r\n\r\nconst UPRIGHT: Face = { italic: false, bold: false };\r\n\r\nexport interface MathStyle {\r\n sizePx: number;\r\n /** Cramped style (denominators, under-radicals) suppresses superscript raise. */\r\n cramped: boolean;\r\n /** Display style (block equations): big operators enlarge and take over/under\r\n * limits. Inline (text) style keeps them small with scripts. Default false. */\r\n display?: boolean;\r\n}\r\n\r\nexport interface MathLayoutCtx {\r\n font: MathFont;\r\n style: MathStyle;\r\n}\r\n\r\n/** Lay out an equation root's children as a single horizontal box. */\r\nexport function layoutMathRow(children: MathNode[], ctx: MathLayoutCtx): MathBox {\r\n return rowBox(children, ctx);\r\n}\r\n\r\n/** Lay out one node. */\r\nexport function layoutMathNode(n: MathNode, ctx: MathLayoutCtx): MathBox {\r\n switch (n.type) {\r\n case \"row\":\r\n return rowBox(n.children, ctx);\r\n case \"ident\":\r\n // Remap to the Mathematical Alphanumeric block so STIX renders true\r\n // italic/bold/blackboard glyphs (upright face \u2014 the codepoint carries style).\r\n return atom(styledMathText(n.text, n.variant), UPRIGHT, ctx);\r\n case \"number\":\r\n return atom(n.text, UPRIGHT, ctx);\r\n case \"op\":\r\n return opAtom(n.text, ctx);\r\n case \"text\":\r\n return atom(n.text, UPRIGHT, ctx);\r\n case \"space\":\r\n return spaceBox((n.widthEm ?? 0) * ctx.style.sizePx);\r\n case \"frac\":\r\n return fracBox(n.num, n.den, ctx, n.thickness === \"0\", n.bevelled === true);\r\n case \"script\":\r\n // Scripts on a limit-style operator in display style sit UNDER/OVER\r\n // (\u2211_{i=1}^{n}); integrals keep sub/superscripts (LIMITS_OPS, not BIG_OPS \u2014\r\n // matching naryBox), everywhere else they're true sub/superscripts.\r\n if (ctx.style.display && n.base.type === \"op\" && LIMITS_OPS.has(n.base.text)) {\r\n return layoutMathNode(\r\n { type: \"limit\", base: n.base, ...(n.sub ? { under: n.sub } : {}), ...(n.sup ? { over: n.sup } : {}) },\r\n ctx,\r\n );\r\n }\r\n return scriptBox(n.base, n.sub, n.sup, ctx);\r\n case \"radical\":\r\n return radicalBox(n.radicand, n.index, ctx);\r\n case \"fenced\":\r\n return fencedBox(n.open, n.close, n.child, ctx);\r\n case \"limit\":\r\n return limitBox(n.base, n.under, n.over, ctx);\r\n case \"nary\":\r\n return naryBox(n, ctx);\r\n case \"matrix\":\r\n return matrixBox(n.rows, ctx);\r\n case \"phantom\": {\r\n const b = layoutMathNode(n.child, ctx);\r\n return { ...emptyBox(), width: b.width, ascent: b.ascent, descent: b.descent };\r\n }\r\n case \"unknown\":\r\n return atom(\"\u25AF\", { italic: false, bold: false }, ctx); // \u25AF placeholder\r\n }\r\n}\r\n\r\n// \u2500\u2500 Atoms \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n\r\ninterface Face {\r\n italic: boolean;\r\n bold: boolean;\r\n}\r\n\r\nfunction atom(text: string, face: Face, ctx: MathLayoutCtx): MathBox {\r\n if (text === \"\") return emptyBox();\r\n const m = ctx.font.measure(text, ctx.style.sizePx, face.italic, face.bold);\r\n return {\r\n width: m.width,\r\n ascent: m.ascent,\r\n descent: m.descent,\r\n italicCorrection: m.italicCorrection,\r\n glyphs: [{ x: 0, y: 0, text, sizePx: ctx.style.sizePx, italic: face.italic, bold: face.bold }],\r\n rules: [],\r\n };\r\n}\r\n\r\n// \u2500\u2500 Rows + spacing \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n\r\ntype AtomClass = \"ord\" | \"op\" | \"bin\" | \"rel\" | \"punct\" | \"open\" | \"close\";\r\n\r\nconst REL = new Set(\"=\u2260<>\u2264\u2265\u2248\u2261\u2208\u2209\u2282\u2286\u2283\u2287\u2192\u2190\u2194\u21D2\u21D0\u21D4\u223C\u2245\u221D\".split(\"\"));\r\nconst BIN = new Set(\"+\u2212-\u00B1\u2213\u00D7\u00F7\u00B7\u2217\u22C5\u222A\u2229\u2228\u2227\u2295\u2297\u2216\".split(\"\"));\r\nconst PUNCT = new Set(\",;\".split(\"\"));\r\nconst OPEN = new Set(\"([{\u27E8\".split(\"\"));\r\nconst CLOSE = new Set(\")]}\u27E9\".split(\"\"));\r\n\r\nfunction classOf(n: MathNode): AtomClass {\r\n if (n.type === \"op\") {\r\n const t = n.text;\r\n if (REL.has(t)) return \"rel\";\r\n if (BIN.has(t)) return \"bin\";\r\n if (PUNCT.has(t)) return \"punct\";\r\n if (OPEN.has(t)) return \"open\";\r\n if (CLOSE.has(t)) return \"close\";\r\n }\r\n if (n.type === \"fenced\") return \"close\"; // already self-delimited\r\n return \"ord\";\r\n}\r\n\r\n/** Inter-atom space (px). A binary operator next to a non-operand acts unary. */\r\nfunction gapBetween(prev: MathNode, cur: MathNode, c: ReturnType<MathFont[\"constants\"]>): number {\r\n let a = classOf(prev);\r\n const b = classOf(cur);\r\n // Unary context: a leading/operator-preceded bin/rel collapses to ordinary.\r\n const operandBefore = a === \"ord\" || a === \"close\" || a === \"punct\";\r\n const bb: AtomClass = (b === \"bin\" && !operandBefore) ? \"ord\" : b;\r\n if (a === \"bin\" && ![\"ord\", \"close\"].includes(b)) a = \"ord\";\r\n if (a === \"rel\" || bb === \"rel\") return c.thickSpace;\r\n if (a === \"bin\" || bb === \"bin\") return c.medSpace;\r\n if (a === \"op\" || bb === \"op\") return c.thinSpace;\r\n if (a === \"punct\") return c.thinSpace;\r\n return 0;\r\n}\r\n\r\nfunction rowBox(children: MathNode[], ctx: MathLayoutCtx): MathBox {\r\n if (children.length === 0) return placeholderSlot(ctx);\r\n const c = ctx.font.constants(ctx.style.sizePx);\r\n const boxes = children.map((ch) => layoutMathNode(ch, ctx));\r\n const gaps: number[] = [0];\r\n for (let i = 1; i < children.length; i++) gaps.push(gapBetween(children[i - 1]!, children[i]!, c));\r\n return hbox(boxes, gaps);\r\n}\r\n\r\n/** An empty editable slot renders as a faint dotted box at x-height. */\r\nfunction placeholderSlot(ctx: MathLayoutCtx): MathBox {\r\n const s = ctx.style.sizePx;\r\n // Reserve an em-ish empty box; the painter draws the dotted slot outline from\r\n // the (zero-child) row in the model, so no ink is emitted here.\r\n return { width: 0.5 * s, ascent: 0.7 * s, descent: 0, italicCorrection: 0, glyphs: [], rules: [] };\r\n}\r\n\r\n// \u2500\u2500 Scripts (sub / sup / subsup) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n\r\nfunction scriptCtx(ctx: MathLayoutCtx, cramped?: boolean): MathLayoutCtx {\r\n const c = ctx.font.constants(ctx.style.sizePx);\r\n return {\r\n font: ctx.font,\r\n style: {\r\n sizePx: Math.max(6, ctx.style.sizePx * c.scriptPercent),\r\n cramped: cramped ?? ctx.style.cramped,\r\n display: false, // scripts are never display style\r\n },\r\n };\r\n}\r\n\r\n// Big operators: \u2211 \u220F \u2026 take over/under limits in display; \u222B \u222E keep sub/sup bounds.\r\nconst LIMITS_OPS = new Set(\"\u2211\u220F\u2210\u22C0\u22C1\u22C2\u22C3\u2A00\u2A01\u2A02\u2A04\u2A06\u2A05\".split(\"\"));\r\nconst BIG_OPS = new Set([...LIMITS_OPS, ...\"\u222B\u222C\u222D\u222E\u222F\u2230\u2231\u2232\u2233\u2A0B\u2A0D\u2A0E\u2A0F\"]);\r\n\r\n/** A glyph rendered at `size` and vertically centered on the math axis (for\r\n * enlarged big operators and stretched delimiters). */\r\nfunction axisCenteredGlyph(chr: string, size: number, ctx: MathLayoutCtx, c: ReturnType<MathFont[\"constants\"]>): MathBox {\r\n const m = ctx.font.measure(chr, size, false, false);\r\n const dy = (m.ascent - m.descent) / 2 - c.axisHeight;\r\n return {\r\n width: m.width,\r\n ascent: m.ascent - dy,\r\n descent: m.descent + dy,\r\n italicCorrection: 0,\r\n glyphs: [{ x: 0, y: dy, text: chr, sizePx: size, italic: false, bold: false }],\r\n rules: [],\r\n };\r\n}\r\n\r\n/** Operator atom \u2014 enlarges a big operator (centered on the axis) in display style. */\r\nfunction opAtom(text: string, ctx: MathLayoutCtx): MathBox {\r\n if (ctx.style.display && BIG_OPS.has(text)) {\r\n const c = ctx.font.constants(ctx.style.sizePx);\r\n return axisCenteredGlyph(text, c.displayOperatorMinHeight / 0.62, ctx, c);\r\n }\r\n return atom(text, UPRIGHT, ctx);\r\n}\r\n\r\nfunction scriptBox(base: MathNode, sub: MathNode | undefined, sup: MathNode | undefined, ctx: MathLayoutCtx): MathBox {\r\n const c = ctx.font.constants(ctx.style.sizePx);\r\n const baseBox = layoutMathNode(base, ctx);\r\n const sctx = scriptCtx(ctx);\r\n const supBox = sup ? layoutMathNode(sup, scriptCtx(ctx, true)) : undefined;\r\n const subBox = sub ? layoutMathNode(sub, sctx) : undefined;\r\n\r\n const parts: MathBox[] = [baseBox];\r\n let scriptWidth = 0;\r\n\r\n if (supBox) {\r\n const raise = Math.max(c.supShiftUp, baseBox.ascent - 0.25 * sctx.style.sizePx);\r\n parts.push(shiftBox(slideX(supBox, baseBox.width + baseBox.italicCorrection), 0, -raise));\r\n scriptWidth = Math.max(scriptWidth, baseBox.italicCorrection + supBox.width);\r\n }\r\n if (subBox) {\r\n let drop = Math.max(c.subShiftDown, baseBox.descent + 0.2 * sctx.style.sizePx);\r\n if (supBox) {\r\n // Keep a minimum gap between the two scripts.\r\n const supBottom = -(Math.max(c.supShiftUp, baseBox.ascent - 0.25 * sctx.style.sizePx)) + supBox.descent;\r\n const subTop = drop - subBox.ascent;\r\n if (subTop - supBottom < c.supSubGapMin) drop = supBottom + c.supSubGapMin + subBox.ascent;\r\n }\r\n parts.push(shiftBox(slideX(subBox, baseBox.width), 0, drop));\r\n scriptWidth = Math.max(scriptWidth, subBox.width);\r\n }\r\n\r\n const merged = overlayCentered(parts, \"left\");\r\n return { ...merged, width: baseBox.width + scriptWidth + c.spaceAfterScript };\r\n}\r\n\r\n/** Translate a box right by dx without changing its metrics' baseline. */\r\nfunction slideX(b: MathBox, dx: number): MathBox {\r\n return {\r\n ...b,\r\n glyphs: b.glyphs.map((g) => ({ ...g, x: g.x + dx })),\r\n rules: b.rules.map((r) => ({ ...r, x: r.x + dx })),\r\n };\r\n}\r\n\r\n// \u2500\u2500 Fractions \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n\r\nfunction fracBox(\r\n numN: MathNode,\r\n denN: MathNode,\r\n ctx: MathLayoutCtx,\r\n noBar: boolean,\r\n bevelled: boolean,\r\n): MathBox {\r\n const c = ctx.font.constants(ctx.style.sizePx);\r\n const num = layoutMathNode(numN, ctx);\r\n const den = layoutMathNode(denN, { font: ctx.font, style: { ...ctx.style, cramped: true } });\r\n if (bevelled) {\r\n // Diagonal fraction a\u2044b: lay out inline with a slash (approximation).\r\n return hbox([num, atom(\"/\", { italic: false, bold: false }, ctx), den]);\r\n }\r\n const t = noBar ? 0 : c.ruleThickness;\r\n const axis = c.axisHeight;\r\n const W = Math.max(num.width, den.width) + 2 * c.thinSpace;\r\n\r\n const numBaseline = Math.min(\r\n -c.fracNumShiftUp,\r\n -(axis + t / 2) - c.fracNumGapMin - num.descent,\r\n );\r\n const denBaseline = Math.max(\r\n c.fracDenShiftDown,\r\n -(axis - t / 2) + c.fracDenGapMin + den.ascent,\r\n );\r\n\r\n const numPlaced = shiftBox(center(num, W), 0, numBaseline);\r\n const denPlaced = shiftBox(center(den, W), 0, denBaseline);\r\n const parts = [numPlaced, denPlaced];\r\n if (t > 0) parts.push(ruleBox(W, t, axis - t / 2));\r\n const merged = overlayCentered(parts, \"left\");\r\n return { ...merged, width: W, italicCorrection: 0 };\r\n}\r\n\r\nfunction center(b: MathBox, W: number): MathBox {\r\n return slideX(b, (W - b.width) / 2);\r\n}\r\n\r\n// \u2500\u2500 Radicals \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n\r\nfunction radicalBox(radicandN: MathNode, indexN: MathNode | undefined, ctx: MathLayoutCtx): MathBox {\r\n const c = ctx.font.constants(ctx.style.sizePx);\r\n const rad = layoutMathNode(radicandN, { font: ctx.font, style: { ...ctx.style, cramped: true } });\r\n const t = c.radicalRuleThickness;\r\n const gap = c.radicalVerticalGap;\r\n const extra = c.radicalExtraAscender;\r\n\r\n // Surd glyph sized to the radicand height (approximation until stretchy glyphs).\r\n const surdHeight = rad.ascent + rad.descent + gap + t;\r\n const surd = ctx.font.measure(\"\u221A\", Math.max(ctx.style.sizePx, surdHeight * 0.9), false, false);\r\n const surdBox: MathBox = {\r\n width: surd.width,\r\n ascent: rad.ascent + gap + t + extra,\r\n descent: rad.descent,\r\n italicCorrection: 0,\r\n glyphs: [{ x: 0, y: 0, text: \"\u221A\", sizePx: Math.max(ctx.style.sizePx, surdHeight * 0.9), italic: false, bold: false }],\r\n rules: [],\r\n };\r\n\r\n const radShift = slideX(rad, surd.width);\r\n const vinculum = slideX(ruleBox(rad.width, t, rad.ascent + gap), surd.width);\r\n const body = overlayCentered([surdBox, radShift, vinculum], \"left\");\r\n const bodyBox: MathBox = { ...body, width: surd.width + rad.width };\r\n\r\n if (!indexN) return bodyBox;\r\n // Degree (nth root): a small index nestled into the surd's crook.\r\n const deg = layoutMathNode(indexN, scriptCtx(scriptCtx(ctx)));\r\n const degRaise = c.radicalDegreeRaise * surdHeight;\r\n const degPlaced = shiftBox(deg, 0, -degRaise);\r\n const shiftedBody = slideX(bodyBox, deg.width);\r\n const combined = overlayCentered([degPlaced, shiftedBody], \"left\");\r\n return { ...combined, width: deg.width + bodyBox.width };\r\n}\r\n\r\n// \u2500\u2500 Fences \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n\r\nfunction fencedBox(open: string, close: string, childN: MathNode, ctx: MathLayoutCtx): MathBox {\r\n const c = ctx.font.constants(ctx.style.sizePx);\r\n const child = layoutMathNode(childN, ctx);\r\n const boxes: MathBox[] = [];\r\n if (open) boxes.push(delimiterBox(open, child, ctx, c));\r\n boxes.push(child);\r\n if (close) boxes.push(delimiterBox(close, child, ctx, c));\r\n return hbox(boxes);\r\n}\r\n\r\n/** A fence delimiter that GROWS to its content: when the content is taller than a\r\n * normal glyph, the bracket is drawn at an enlarged size and vertically centered\r\n * on the math axis (a size-variant approximation \u2014 no MATH table needed). */\r\nfunction delimiterBox(chr: string, child: MathBox, ctx: MathLayoutCtx, c: ReturnType<MathFont[\"constants\"]>): MathBox {\r\n const base = ctx.style.sizePx;\r\n const contentH = child.ascent + child.descent;\r\n if (contentH <= base * 1.05) return atom(chr, UPRIGHT, ctx); // no stretch needed\r\n const size = Math.min(base * 3.5, contentH + 2 * c.ruleThickness);\r\n return axisCenteredGlyph(chr, size, ctx, c);\r\n}\r\n\r\n// \u2500\u2500 Under / over limits \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n\r\nfunction limitBox(baseN: MathNode, underN: MathNode | undefined, overN: MathNode | undefined, ctx: MathLayoutCtx): MathBox {\r\n const c = ctx.font.constants(ctx.style.sizePx);\r\n const base = layoutMathNode(baseN, ctx);\r\n const sctx = scriptCtx(ctx);\r\n const W = Math.max(base.width, underN ? layoutMathNode(underN, sctx).width : 0, overN ? layoutMathNode(overN, sctx).width : 0);\r\n const parts: MathBox[] = [center(base, W)];\r\n if (overN) {\r\n const over = center(layoutMathNode(overN, sctx), W);\r\n parts.push(shiftBox(over, 0, -(base.ascent + c.thinSpace + over.descent)));\r\n }\r\n if (underN) {\r\n const under = center(layoutMathNode(underN, sctx), W);\r\n parts.push(shiftBox(under, 0, base.descent + c.thinSpace + under.ascent));\r\n }\r\n const merged = overlayCentered(parts, \"left\");\r\n return { ...merged, width: W };\r\n}\r\n\r\n// \u2500\u2500 N-ary operators \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n\r\nfunction naryBox(n: Extract<MathNode, { type: \"nary\" }>, ctx: MathLayoutCtx): MathBox {\r\n const c = ctx.font.constants(ctx.style.sizePx);\r\n // The operator (enlarged for big-ops in display by opAtom) takes over/under\r\n // limits in display style for \u2211 \u220F \u2026, else sub/superscripts (\u222B). The op node\r\n // routes through opAtom, so the bounds position around the enlarged glyph.\r\n const opNode: MathNode = { type: \"op\", text: n.hideOp ? \"\" : n.op };\r\n const limits = ctx.style.display === true && LIMITS_OPS.has(n.op);\r\n const opCluster: MathNode = limits\r\n ? { type: \"limit\", base: opNode, ...(n.sub ? { under: n.sub } : {}), ...(n.sup ? { over: n.sup } : {}) }\r\n : { type: \"script\", base: opNode, ...(n.sub ? { sub: n.sub } : {}), ...(n.sup ? { sup: n.sup } : {}) };\r\n return hbox([layoutMathNode(opCluster, ctx), layoutMathNode(n.body, ctx)], [0, n.hideOp ? 0 : c.thinSpace]);\r\n}\r\n\r\n// \u2500\u2500 Matrices \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n\r\nfunction matrixBox(rows: MathNode[][], ctx: MathLayoutCtx): MathBox {\r\n const c = ctx.font.constants(ctx.style.sizePx);\r\n const colGap = 2 * c.thickSpace;\r\n const rowGap = c.thinSpace * 3;\r\n if (rows.length === 0) return emptyBox();\r\n const cells = rows.map((r) => r.map((cell) => layoutMathNode(cell, ctx)));\r\n const nCols = Math.max(...cells.map((r) => r.length));\r\n if (nCols === 0) return emptyBox(); // all-empty rows \u2192 no negative width\r\n const colW: number[] = [];\r\n for (let j = 0; j < nCols; j++) colW[j] = Math.max(0, ...cells.map((r) => (r[j] ? r[j]!.width : 0)));\r\n const rowH = cells.map((r) => ({\r\n ascent: Math.max(0, ...r.map((b) => b.ascent)),\r\n descent: Math.max(0, ...r.map((b) => b.descent)),\r\n }));\r\n const totalH = rowH.reduce((s, h) => s + h.ascent + h.descent, 0) + rowGap * (rows.length - 1);\r\n const axis = c.axisHeight;\r\n // Center the grid on the math axis. The axis sits axisHeight ABOVE the baseline,\r\n // i.e. at y = -axisHeight (y grows downward), so the grid TOP is at\r\n // -axisHeight - totalH/2. (A +axis here put the grid below the baseline, leaving\r\n // the axis-centered fence brackets visibly too high.)\r\n let y = -(totalH / 2) - axis;\r\n const parts: MathBox[] = [];\r\n for (let i = 0; i < cells.length; i++) {\r\n const h = rowH[i]!;\r\n const baseline = y + h.ascent;\r\n let x = 0;\r\n for (let j = 0; j < nCols; j++) {\r\n const b = cells[i]![j];\r\n if (b) parts.push(shiftBox(slideX(center(b, colW[j]!), x), 0, baseline));\r\n x += colW[j]! + colGap;\r\n }\r\n y += h.ascent + h.descent + rowGap;\r\n }\r\n const width = colW.reduce((s, w) => s + w, 0) + colGap * (nCols - 1);\r\n const merged = overlayCentered(parts, \"left\");\r\n return { ...merged, width };\r\n}\r\n\r\nexport { boxHeight };\r\n", "// GENERATED by scripts/extract-math-constants.mjs from STIX Two Math's OpenType\r\n// MATH table \u2014 do not edit by hand. Values are fractions of the em (font size),\r\n// multiplied by the font size at layout time (see mathFont.ts).\r\n\r\nexport interface StixMathConstants {\r\n axisHeight: number;\r\n ruleThickness: number;\r\n scriptPercent: number;\r\n scriptScriptPercent: number;\r\n fracNumShiftUp: number;\r\n fracDenShiftDown: number;\r\n fracNumGapMin: number;\r\n fracDenGapMin: number;\r\n supShiftUp: number;\r\n supShiftUpCramped: number;\r\n subShiftDown: number;\r\n supSubGapMin: number;\r\n spaceAfterScript: number;\r\n upperLimitGapMin: number;\r\n upperLimitBaselineRiseMin: number;\r\n lowerLimitGapMin: number;\r\n lowerLimitBaselineDropMin: number;\r\n stackGapMin: number;\r\n radicalVerticalGap: number;\r\n radicalRuleThickness: number;\r\n radicalExtraAscender: number;\r\n radicalKernBeforeDegree: number;\r\n radicalKernAfterDegree: number;\r\n radicalDegreeRaise: number;\r\n overbarVerticalGap: number;\r\n overbarRuleThickness: number;\r\n overbarExtraAscender: number;\r\n underbarVerticalGap: number;\r\n accentBaseHeight: number;\r\n displayOperatorMinHeight: number;\r\n delimitedSubFormulaMinHeight: number;\r\n mathLeading: number;\r\n}\r\n\r\nexport const STIX_MATH_CONSTANTS: StixMathConstants = {\r\n \"axisHeight\": 0.258,\r\n \"ruleThickness\": 0.068,\r\n \"scriptPercent\": 0.7,\r\n \"scriptScriptPercent\": 0.55,\r\n \"fracNumShiftUp\": 0.585,\r\n \"fracDenShiftDown\": 0.585,\r\n \"fracNumGapMin\": 0.068,\r\n \"fracDenGapMin\": 0.068,\r\n \"supShiftUp\": 0.36,\r\n \"supShiftUpCramped\": 0.252,\r\n \"subShiftDown\": 0.21,\r\n \"supSubGapMin\": 0.15,\r\n \"spaceAfterScript\": 0.04,\r\n \"upperLimitGapMin\": 0.135,\r\n \"upperLimitBaselineRiseMin\": 0.3,\r\n \"lowerLimitGapMin\": 0.135,\r\n \"lowerLimitBaselineDropMin\": 0.67,\r\n \"stackGapMin\": 0.15,\r\n \"radicalVerticalGap\": 0.085,\r\n \"radicalRuleThickness\": 0.068,\r\n \"radicalExtraAscender\": 0.078,\r\n \"radicalKernBeforeDegree\": 0.065,\r\n \"radicalKernAfterDegree\": -0.335,\r\n \"radicalDegreeRaise\": 0.55,\r\n \"overbarVerticalGap\": 0.175,\r\n \"overbarRuleThickness\": 0.068,\r\n \"overbarExtraAscender\": 0.068,\r\n \"underbarVerticalGap\": 0.175,\r\n \"accentBaseHeight\": 0.48,\r\n \"displayOperatorMinHeight\": 1.8,\r\n \"delimitedSubFormulaMinHeight\": 1.325,\r\n \"mathLeading\": 0.15\r\n};\r\n", "// The metric/constant provider the math typesetter depends on. Abstracted behind\r\n// an interface so the engine is PURE (testable with a stub) and so the real\r\n// STIX Two Math OpenType MATH-table data can replace the defaults later (M4)\r\n// without touching layoutMath.ts.\r\n//\r\n// `constants` are scaled per call by font size. The default ratios are the\r\n// classic TeX values (a good approximation until the MATH table is wired in);\r\n// real fonts carry their own in the MATH table, which this interface will expose.\r\n\r\nimport { fontMetrics, measureTextWidth } from \"../metrics\";\r\nimport { cloneFamilyFor, firstFamilyToken, MATH_FONT_FAMILY } from \"../../fonts/clones\";\r\nimport { STIX_MATH_CONSTANTS } from \"./stixMathConstants\";\r\n\r\nexport interface GlyphMetrics {\r\n width: number;\r\n ascent: number;\r\n descent: number;\r\n /** Italic correction \u2014 extra advance past the visual right edge of a slanted\r\n * glyph, so an attached superscript clears it. */\r\n italicCorrection: number;\r\n}\r\n\r\n/** Layout constants in PIXELS for a given font size (TeX-style names). */\r\nexport interface MathConstants {\r\n axisHeight: number;\r\n ruleThickness: number;\r\n scriptPercent: number;\r\n scriptScriptPercent: number;\r\n fracNumShiftUp: number;\r\n fracDenShiftDown: number;\r\n fracNumGapMin: number;\r\n fracDenGapMin: number;\r\n supShiftUp: number;\r\n subShiftDown: number;\r\n supSubGapMin: number;\r\n spaceAfterScript: number;\r\n radicalRuleThickness: number;\r\n radicalVerticalGap: number;\r\n radicalExtraAscender: number;\r\n radicalDegreeRaise: number;\r\n /** Math spacing quanta (1mu = size/18): thin=3mu, med=4mu, thick=5mu. */\r\n thinSpace: number;\r\n medSpace: number;\r\n thickSpace: number;\r\n /** Minimum height of a display-style n-ary operator (\u2211 \u222B). */\r\n displayOperatorMinHeight: number;\r\n /** Gaps/shifts for over/under limits on big operators. */\r\n upperLimitGapMin: number;\r\n lowerLimitGapMin: number;\r\n upperLimitBaselineRise: number;\r\n lowerLimitBaselineDrop: number;\r\n}\r\n\r\nexport interface MathFont {\r\n family: string;\r\n /** Measure a glyph string at a size; `italic`/`bold` select the face. */\r\n measure(text: string, sizePx: number, italic: boolean, bold: boolean): GlyphMetrics;\r\n constants(sizePx: number): MathConstants;\r\n}\r\n\r\n/** TeX-derived default constants (placeholder for the STIX MATH table). */\r\nexport function defaultMathConstants(sizePx: number): MathConstants {\r\n const mu = sizePx / 18;\r\n const rule = Math.max(0.5, 0.04 * sizePx);\r\n return {\r\n axisHeight: 0.25 * sizePx,\r\n ruleThickness: rule,\r\n scriptPercent: 0.7,\r\n scriptScriptPercent: 0.5,\r\n fracNumShiftUp: 0.45 * sizePx,\r\n fracDenShiftDown: 0.55 * sizePx,\r\n fracNumGapMin: 3 * rule,\r\n fracDenGapMin: 3 * rule,\r\n supShiftUp: 0.42 * sizePx,\r\n subShiftDown: 0.2 * sizePx,\r\n supSubGapMin: 4 * rule,\r\n spaceAfterScript: 0.5 * mu,\r\n radicalRuleThickness: rule,\r\n radicalVerticalGap: 1.5 * rule,\r\n radicalExtraAscender: rule,\r\n radicalDegreeRaise: 0.6,\r\n thinSpace: 3 * mu,\r\n medSpace: 4 * mu,\r\n thickSpace: 5 * mu,\r\n displayOperatorMinHeight: 1.8 * sizePx,\r\n upperLimitGapMin: 0.2 * sizePx,\r\n lowerLimitGapMin: 0.2 * sizePx,\r\n upperLimitBaselineRise: 0.3 * sizePx,\r\n lowerLimitBaselineDrop: 0.6 * sizePx,\r\n };\r\n}\r\n\r\n/** Real STIX Two Math constants (extracted from its OpenType MATH table). Used\r\n * for the bundled math font so positioning matches a professional math renderer;\r\n * the TeX defaults above remain the fallback for the stub font in tests. */\r\nexport function stixMathConstants(sizePx: number): MathConstants {\r\n const s = STIX_MATH_CONSTANTS;\r\n const mu = sizePx / 18;\r\n return {\r\n axisHeight: s.axisHeight * sizePx,\r\n ruleThickness: s.ruleThickness * sizePx,\r\n scriptPercent: s.scriptPercent,\r\n scriptScriptPercent: s.scriptScriptPercent,\r\n fracNumShiftUp: s.fracNumShiftUp * sizePx,\r\n fracDenShiftDown: s.fracDenShiftDown * sizePx,\r\n fracNumGapMin: s.fracNumGapMin * sizePx,\r\n fracDenGapMin: s.fracDenGapMin * sizePx,\r\n supShiftUp: s.supShiftUp * sizePx,\r\n subShiftDown: s.subShiftDown * sizePx,\r\n supSubGapMin: s.supSubGapMin * sizePx,\r\n spaceAfterScript: s.spaceAfterScript * sizePx,\r\n radicalRuleThickness: s.radicalRuleThickness * sizePx,\r\n radicalVerticalGap: s.radicalVerticalGap * sizePx,\r\n radicalExtraAscender: s.radicalExtraAscender * sizePx,\r\n radicalDegreeRaise: s.radicalDegreeRaise,\r\n thinSpace: 3 * mu,\r\n medSpace: 4 * mu,\r\n thickSpace: 5 * mu,\r\n displayOperatorMinHeight: s.displayOperatorMinHeight * sizePx,\r\n upperLimitGapMin: s.upperLimitGapMin * sizePx,\r\n lowerLimitGapMin: s.lowerLimitGapMin * sizePx,\r\n upperLimitBaselineRise: s.upperLimitBaselineRiseMin * sizePx,\r\n lowerLimitBaselineDrop: s.lowerLimitBaselineDropMin * sizePx,\r\n };\r\n}\r\n\r\n/** Default provider backed by the existing clone-metric measurement surface.\r\n * Uses the bundled metric clone of `family` so the editor, browser export, and\r\n * Node backend measure identically. Per-glyph bounding boxes / real italic\r\n * correction await the STIX MATH integration; until then ascent/descent come\r\n * from the font's overall metrics and italic correction is a small estimate. */\r\nexport function createMathFont(family: string): MathFont {\r\n const clone = cloneFamilyFor(firstFamilyToken(family)).clone;\r\n const fontStr = (sizePx: number, italic: boolean, bold: boolean): string =>\r\n `${italic ? \"italic \" : \"\"}${bold ? \"700\" : \"400\"} ${sizePx}px ${clone}`;\r\n // The bundled math font carries real MATH-table constants; anything else\r\n // (a clone fallback) uses the TeX defaults.\r\n const constants = clone === MATH_FONT_FAMILY ? stixMathConstants : defaultMathConstants;\r\n return {\r\n family: clone,\r\n measure(text, sizePx, italic, bold) {\r\n const font = fontStr(sizePx, italic, bold);\r\n const width = measureTextWidth(text, font);\r\n const fm = fontMetrics(font);\r\n // Estimate italic correction from the slant when the glyph is italic.\r\n const italicCorrection = italic ? Math.min(0.12 * sizePx, 0.15 * width) : 0;\r\n return { width, ascent: fm.ascent, descent: fm.descent, italicCorrection };\r\n },\r\n constants,\r\n };\r\n}\r\n", "// Bridge from a stored MathEquation (model) to a typeset MathBox (geometry).\r\n// Memoized per (equation object, family, size) so repeated layouts/renders of the\r\n// same equation are free; the AST is immutable, so object identity is a safe key.\r\n\r\nimport type { MathEquation } from \"@cw/shared\";\r\nimport { layoutMathRow } from \"./layoutMath\";\r\nimport { createMathFont, type MathFont } from \"./mathFont\";\r\nimport type { MathBox } from \"./mathBox\";\r\n\r\n/** Display equations lay out a touch larger than body text for prominence. */\r\nexport const EQUATION_DISPLAY_PX = 22;\r\n\r\nconst fontCache = new Map<string, MathFont>();\r\nconst boxCache = new WeakMap<MathEquation, Map<string, MathBox>>();\r\n\r\nfunction fontFor(family: string): MathFont {\r\n let f = fontCache.get(family);\r\n if (!f) {\r\n f = createMathFont(family);\r\n fontCache.set(family, f);\r\n }\r\n return f;\r\n}\r\n\r\n/** Typeset an equation to a positioned box. Requires a measurement context to be\r\n * installed (the browser canvas is automatic; Node hosts call installMeasureHost\r\n * first). Inline vs display only differ in `sizePx` chosen by the caller. */\r\nexport function equationBox(eq: MathEquation, family: string, sizePx: number): MathBox {\r\n const key = `${family}|${sizePx}`;\r\n let byKey = boxCache.get(eq);\r\n if (byKey) {\r\n const hit = byKey.get(key);\r\n if (hit) return hit;\r\n } else {\r\n byKey = new Map();\r\n boxCache.set(eq, byKey);\r\n }\r\n const box = layoutMathRow(eq.root.children, {\r\n font: fontFor(family),\r\n style: { sizePx, cramped: false, display: eq.display },\r\n });\r\n byKey.set(key, box);\r\n return box;\r\n}\r\n", "// The pretext prepare-cache: prepareRichInline does the expensive measurement\r\n// once per paragraph; invalidated only when the paragraph's revision changes\r\n// (text/style edits). Width changes do NOT invalidate \u2014 re-breaking lines is\r\n// cheap arithmetic.\r\n//\r\n// Soft line breaks: a \"\\v\" in run text is a hard break WITHIN the paragraph\r\n// (Shift+Enter). The paragraph splits into segments at every \\v; each segment\r\n// gets its own prepare. The \\v itself is one UTF-16 unit in the offset space \u2014\r\n// segment k starts at (end of segment k-1) + 1 \u2014 so caret math and backspace\r\n// need zero special-casing.\r\n\r\nimport {\r\n prepareRichInline,\r\n type PreparedRichInline,\r\n type RichInlineItem,\r\n} from \"@chenglou/pretext/rich-inline\";\r\nimport { clearAnalysisCaches, isCJK, setAnalysisLocale } from \"@chenglou/pretext/analysis\";\r\nimport type { CharStyle, Paragraph, Run } from \"@cw/shared\";\r\nimport { charStyleToFont, measureTextWidth } from \"./metrics\";\r\nimport { firstFamilyToken, MATH_FONT_FAMILY } from \"../fonts/clones\";\r\nimport { equationBox } from \"./math/equationLayout\";\r\nimport { SMALL_CAPS_SCALE } from \"../paint/paintStyle\";\r\n\r\n// ---------------------------------------------------------------------------\r\n// Script-fallback tuning (CJK + Arabic). The fallback families are RE-ASSERTED by\r\n// the engine at the top of each layout() pass (a synchronous, await-free span) from\r\n// its per-instance config \u2014 exactly like setActiveFontRegistry. So concurrent\r\n// editors / export jobs each see their own config with no shared-mutable-state race\r\n// and no lock: the values are set and read within the same atomic layout span, never\r\n// across an `await`.\r\n\r\n// The CJK fallback family active for the CURRENT layout pass (null = leave CJK runs\r\n// untouched, so the browser's system fallback renders them on screen).\r\nlet activeCjkFallback: string | null = null;\r\n\r\n/** Set the CJK fallback family for the upcoming layout pass. The engine calls this\r\n * synchronously at layout() top; `\"\"`/whitespace is treated as \"no fallback\". */\r\nexport function setActiveCjkFallback(family: string | null | undefined): void {\r\n activeCjkFallback = family && family.trim().length > 0 ? family.trim() : null;\r\n}\r\n\r\n// The Arabic fallback family active for the CURRENT layout pass (null = leave Arabic\r\n// runs untouched, so the browser's system fallback renders them on screen).\r\nlet activeArabicFallback: string | null = null;\r\n\r\n/** Set the Arabic fallback family for the upcoming layout pass. The engine calls\r\n * this synchronously at layout() top; `\"\"`/whitespace is treated as \"no fallback\". */\r\nexport function setActiveArabicFallback(family: string | null | undefined): void {\r\n activeArabicFallback = family && family.trim().length > 0 ? family.trim() : null;\r\n}\r\n\r\n// The Hebrew fallback family active for the CURRENT layout pass (null = leave Hebrew\r\n// runs untouched, so the browser's system fallback renders them on screen).\r\nlet activeHebrewFallback: string | null = null;\r\n\r\n/** Set the Hebrew fallback family for the upcoming layout pass. The engine calls\r\n * this synchronously at layout() top; `\"\"`/whitespace is treated as \"no fallback\". */\r\nexport function setActiveHebrewFallback(family: string | null | undefined): void {\r\n activeHebrewFallback = family && family.trim().length > 0 ? family.trim() : null;\r\n}\r\n\r\n// pretext's analyzer locale is PROCESS-GLOBAL inside the library (it can't be made\r\n// per-call), so the engine applies it synchronously at layout() top too \u2014 within the\r\n// same await-free span, so concurrent layouts each assert their own. Idempotent per\r\n// value so the editor's per-keystroke relayouts don't thrash the analyzer cache.\r\nlet lastLocale: string | undefined;\r\nlet lastLocaleApplied = false;\r\nexport function applyCjkLocale(locale: string | undefined): void {\r\n if (lastLocaleApplied && lastLocale === locale) return;\r\n setAnalysisLocale(locale);\r\n clearAnalysisCaches();\r\n lastLocale = locale;\r\n lastLocaleApplied = true;\r\n}\r\n\r\nconst hasCjk = (text: string): boolean => {\r\n for (const ch of text) if (isCJK(ch)) return true;\r\n return false;\r\n};\r\n\r\n/** True when the code point is in any Arabic Unicode block.\r\n * Covers Basic Arabic (0600\u201306FF), Arabic Supplement (0750\u2013077F),\r\n * Arabic Extended-B (0870\u2013089F), Arabic Extended-A (08A0\u201308FF),\r\n * Arabic Presentation Forms-A (FB50\u2013FDFF), and\r\n * Arabic Presentation Forms-B (FE70\u2013FEFF). */\r\nfunction isArabic(ch: string): boolean {\r\n const cp = ch.codePointAt(0);\r\n if (cp === undefined) return false;\r\n return (\r\n (cp >= 0x0600 && cp <= 0x06ff) ||\r\n (cp >= 0x0750 && cp <= 0x077f) ||\r\n (cp >= 0x0870 && cp <= 0x089f) ||\r\n (cp >= 0x08a0 && cp <= 0x08ff) ||\r\n (cp >= 0xfb50 && cp <= 0xfdff) ||\r\n (cp >= 0xfe70 && cp <= 0xfeff)\r\n );\r\n}\r\n\r\nconst hasArabic = (text: string): boolean => {\r\n for (const ch of text) if (isArabic(ch)) return true;\r\n return false;\r\n};\r\n\r\n/** True when the code point is in a Hebrew Unicode block.\r\n * Covers the Hebrew block (0590\u201305FF) and the Hebrew letters/ligatures in\r\n * Alphabetic Presentation Forms (FB1D\u2013FB4F). */\r\nfunction isHebrew(ch: string): boolean {\r\n const cp = ch.codePointAt(0);\r\n if (cp === undefined) return false;\r\n return (cp >= 0x0590 && cp <= 0x05ff) || (cp >= 0xfb1d && cp <= 0xfb4f);\r\n}\r\n\r\nconst hasHebrew = (text: string): boolean => {\r\n for (const ch of text) if (isHebrew(ch)) return true;\r\n return false;\r\n};\r\n\r\n/** Script tag for a character: \"arabic\" | \"hebrew\" | \"cjk\" | \"other\". Used to split\r\n * runs at script boundaries when CJK, Arabic, and/or Hebrew fallbacks are configured. */\r\ntype ScriptTag = \"arabic\" | \"hebrew\" | \"cjk\" | \"other\";\r\n\r\nfunction scriptOf(ch: string, cjkFam: string | null, arabicFam: string | null, hebrewFam: string | null): ScriptTag {\r\n if (arabicFam && isArabic(ch)) return \"arabic\";\r\n if (hebrewFam && isHebrew(ch)) return \"hebrew\";\r\n if (cjkFam && isCJK(ch)) return \"cjk\";\r\n return \"other\";\r\n}\r\n\r\n/** Split runs at CJK \u2194 Arabic \u2194 other script boundaries, retargeting each script\r\n * piece to its configured fallback family. Offset-transparent: the concatenated text\r\n * and its length are unchanged, so every downstream offset/itemIndex mapping still\r\n * holds. No-op when no fallback fonts are configured or a run carries no CJK/Arabic. */\r\nexport function scriptSplitRuns(runs: Run[]): Run[] {\r\n const cjkFam = activeCjkFallback;\r\n const arabicFam = activeArabicFallback;\r\n const hebrewFam = activeHebrewFallback;\r\n if (!cjkFam && !arabicFam && !hebrewFam) return runs;\r\n\r\n const out: Run[] = [];\r\n let changed = false;\r\n for (const run of runs) {\r\n const runFamily = firstFamilyToken(run.style.fontFamily);\r\n const needsCjk = cjkFam && runFamily !== cjkFam && hasCjk(run.text);\r\n const needsArabic = arabicFam && runFamily !== arabicFam && hasArabic(run.text);\r\n const needsHebrew = hebrewFam && runFamily !== hebrewFam && hasHebrew(run.text);\r\n if (run.text.length === 0 || (!needsCjk && !needsArabic && !needsHebrew)) {\r\n out.push(run);\r\n continue;\r\n }\r\n changed = true;\r\n let buf = \"\";\r\n let bufScript: ScriptTag | null = null;\r\n const flush = (): void => {\r\n if (buf.length === 0) return;\r\n let fontFamily = run.style.fontFamily;\r\n if (bufScript === \"arabic\" && arabicFam) fontFamily = arabicFam;\r\n else if (bufScript === \"hebrew\" && hebrewFam) fontFamily = hebrewFam;\r\n else if (bufScript === \"cjk\" && cjkFam) fontFamily = cjkFam;\r\n out.push({ text: buf, style: fontFamily === run.style.fontFamily ? run.style : { ...run.style, fontFamily } });\r\n buf = \"\";\r\n };\r\n for (const ch of run.text) {\r\n const s = scriptOf(ch, cjkFam, arabicFam, hebrewFam);\r\n if (bufScript !== null && s !== bufScript) flush();\r\n bufScript = s;\r\n buf += ch;\r\n }\r\n flush();\r\n }\r\n return changed ? out : runs;\r\n}\r\n\r\nexport interface PreparedSegment {\r\n prepared: PreparedRichInline;\r\n /** The segment's runs (\\v stripped) \u2014 itemIndex in pretext fragments maps here. */\r\n runs: Run[];\r\n /** Global UTF-16 offset of the segment start within the paragraph text. */\r\n startOffset: number;\r\n}\r\n\r\ninterface Entry {\r\n revision: number;\r\n segments: PreparedSegment[];\r\n}\r\n\r\n/** Split runs at \"\\v\" into per-segment run lists with global start offsets. */\r\nexport function segmentRuns(runs: Run[]): { runs: Run[]; startOffset: number }[] {\r\n const segs: { runs: Run[]; startOffset: number }[] = [];\r\n let cur: Run[] = [];\r\n let segStart = 0;\r\n let pos = 0;\r\n for (const r of runs) {\r\n let local = 0;\r\n for (;;) {\r\n const idx = r.text.indexOf(\"\\v\", local);\r\n if (idx < 0) break;\r\n const piece = r.text.slice(local, idx);\r\n if (piece.length > 0) cur.push({ text: piece, style: r.style });\r\n pos += idx - local;\r\n segs.push({ runs: cur, startOffset: segStart });\r\n pos += 1; // the \\v itself occupies one offset\r\n segStart = pos;\r\n cur = [];\r\n local = idx + 1;\r\n }\r\n const rest = r.text.slice(local);\r\n if (rest.length > 0) cur.push({ text: rest, style: r.style });\r\n pos += rest.length;\r\n }\r\n segs.push({ runs: cur, startOffset: segStart });\r\n return segs;\r\n}\r\n\r\nfunction toItems(runs: Run[]): RichInlineItem[] {\r\n // Hidden runs stay in the list (so item indices line up with seg.runs and the\r\n // run-offset accounting is unchanged) but contribute EMPTY text to pretext \u2014 no\r\n // fragment, zero width, never painted. Offsets still span the full text.\r\n return runs.map((run) => {\r\n // Inline equation: the run is a single U+FFFC reserving the math box width. We\r\n // keep the sentinel as the item text (pretext drops empty-text items, so a\r\n // true zero-width placeholder would erase the fragment entirely). pretext's\r\n // occupied width for a `break:'never'` item is `naturalWidth + extraWidth`, so\r\n // we set extraWidth to the SIGNED delta `box.width - sentinelW`: occupied then\r\n // collapses to exactly `box.width` for narrow AND wide equations (the old\r\n // `max(0, \u2026)` clamp over-reserved whenever the box was narrower than the U+FFFC\r\n // glyph \u2014 see #16). `naturalWidth === sentinelW` since both measure the sentinel\r\n // through the same context. `break:'never'` keeps it atomic; breakNextLine then\r\n // swaps the box's metrics in for the line.\r\n if (run.style.equation && !run.style.hidden) {\r\n const font = charStyleToFont(run.style);\r\n const box = equationBox(run.style.equation, MATH_FONT_FAMILY, run.style.fontSizePx);\r\n const sentinelW = measureTextWidth(run.text, font);\r\n return { text: run.text, font, break: \"never\", extraWidth: box.width - sentinelW };\r\n }\r\n const item: RichInlineItem = { text: run.style.hidden ? \"\" : run.text, font: charStyleToFont(run.style) };\r\n if (!run.style.hidden && run.style.letterSpacingPx !== undefined) item.letterSpacing = run.style.letterSpacingPx;\r\n return item;\r\n });\r\n}\r\n\r\n// ---------------------------------------------------------------------------\r\n// Case transforms (w:caps / w:smallCaps). Both render letters UPPERCASED; the\r\n// transform is applied to throwaway DISPLAY runs the layout measures and paints,\r\n// never to the model. It is offset-transparent: the per-code-point uppercase only\r\n// substitutes forms whose UTF-16 length is unchanged, so the concatenated text\r\n// length \u2014 and therefore every downstream offset/itemIndex/cluster mapping \u2014 is\r\n// preserved (mirrors scriptSplitRuns). The baked runs drop the caps/smallCaps\r\n// flags so a second pass (e.g. tab pieces) is a clean no-op.\r\n\r\nconst r2 = (n: number): number => Math.round(n * 100) / 100;\r\n\r\n// Small caps splits a run by reduced/full size; segment by GRAPHEME CLUSTER (not\r\n// code point) so a combining mark stays attached to its base letter \u2014 otherwise a\r\n// decomposed \"a\u0308\" would split into a reduced \"A\" plus a full-size mark and the\r\n// accent would mis-shape. Matches geometry.ts's cluster granularity.\r\nconst capsSegmenter = new Intl.Segmenter(undefined, { granularity: \"grapheme\" });\r\n\r\n/** Length-preserving uppercase of ONE code point: the uppercased form only when it\r\n * occupies the same number of UTF-16 units (keeps offsets 1:1); else the original\r\n * (rare expanding cases like \u00DF\u2192SS, \uFB00 ligatures stay as authored). */\r\nfunction upperCp(cp: string): string {\r\n const up = cp.toUpperCase();\r\n return up.length === cp.length ? up : cp;\r\n}\r\n\r\n/** A lowercase letter small-caps should shrink \u2014 uppercasing changes it without\r\n * changing its UTF-16 length. */\r\nfunction isSmallCapped(cp: string): boolean {\r\n const up = cp.toUpperCase();\r\n return up.length === cp.length && up !== cp;\r\n}\r\n\r\n/** Bake w:caps / w:smallCaps into display runs. caps: uppercase every letter at full\r\n * size. smallCaps (takes precedence): uppercase every letter, but split the\r\n * originally-lowercase letters into reduced-size sub-runs so the painters draw them\r\n * smaller with no small-caps-specific code. No-op when no run carries either flag. */\r\nexport function applyCaseTransforms(runs: Run[]): Run[] {\r\n let any = false;\r\n for (const r of runs) {\r\n if ((r.style.caps || r.style.smallCaps) && !r.style.equation) {\r\n any = true;\r\n break;\r\n }\r\n }\r\n if (!any) return runs;\r\n\r\n const out: Run[] = [];\r\n for (const run of runs) {\r\n const { caps, smallCaps } = run.style;\r\n if ((!caps && !smallCaps) || run.style.equation || run.text.length === 0) {\r\n out.push(run);\r\n continue;\r\n }\r\n const baseStyle: CharStyle = { ...run.style, caps: undefined, smallCaps: undefined };\r\n if (!smallCaps) {\r\n out.push({ text: [...run.text].map(upperCp).join(\"\"), style: baseStyle });\r\n continue;\r\n }\r\n const reducedStyle: CharStyle = { ...baseStyle, fontSizePx: r2(run.style.fontSizePx * SMALL_CAPS_SCALE) };\r\n let buf = \"\";\r\n let bufReduced: boolean | null = null;\r\n const flush = (): void => {\r\n if (buf.length === 0) return;\r\n out.push({ text: buf, style: bufReduced ? reducedStyle : baseStyle });\r\n buf = \"\";\r\n };\r\n for (const { segment } of capsSegmenter.segment(run.text)) {\r\n // The cluster's BASE code point decides reduction (combining marks ride along).\r\n const base = String.fromCodePoint(segment.codePointAt(0)!);\r\n const reduced = isSmallCapped(base);\r\n if (bufReduced !== null && reduced !== bufReduced) flush();\r\n bufReduced = reduced;\r\n buf += reduced ? [...segment].map(upperCp).join(\"\") : segment;\r\n }\r\n flush();\r\n }\r\n return out;\r\n}\r\n\r\n/** Prepare an arbitrary run list AND return the (case- + CJK-split) run list it was\r\n * prepared from. Callers that map pretext itemIndex/offsets back to runs MUST use\r\n * the returned `runs` (not the originals) \u2014 splitting changes the item count. */\r\nexport function prepareRunSegment(runs: Run[]): { prepared: PreparedRichInline; runs: Run[] } {\r\n const split = scriptSplitRuns(applyCaseTransforms(runs));\r\n return { prepared: prepareRichInline(toItems(split)), runs: split };\r\n}\r\n\r\n/** Prepare an arbitrary run list (used for tab-stop pieces, which are laid out\r\n * outside the per-paragraph segment cache). */\r\nexport function prepareRuns(runs: Run[]): PreparedRichInline {\r\n return prepareRunSegment(runs).prepared;\r\n}\r\n\r\nexport class PrepareCache {\r\n private map = new Map<string, Entry>();\r\n\r\n get(p: Paragraph): PreparedSegment[] {\r\n const hit = this.map.get(p.id);\r\n if (hit && hit.revision === p.revision) return hit.segments;\r\n\r\n const segments: PreparedSegment[] = segmentRuns(p.runs).map((seg) => {\r\n // Script-split for CJK fallback BEFORE prepare so item indices, fragment\r\n // styles, and offsets all derive from the same (split) run list.\r\n return { ...prepareRunSegment(seg.runs), startOffset: seg.startOffset };\r\n });\r\n this.map.set(p.id, { revision: p.revision, segments });\r\n return segments;\r\n }\r\n\r\n evict(blockId: string): void {\r\n this.map.delete(blockId);\r\n }\r\n\r\n /** Drop every entry \u2014 used when the whole document is replaced (the importer\r\n * re-mints block ids from i0, so a stale entry at the same id+revision would\r\n * otherwise leak the previous document's prepared text into the new one). */\r\n clear(): void {\r\n this.map.clear();\r\n }\r\n\r\n /** Drop every entry whose id is NOT in `keep` (paragraphs no longer in the\r\n * document). Called after a full layout to bound the cache to live blocks. */\r\n retainOnly(keep: ReadonlySet<string>): void {\r\n for (const id of this.map.keys()) if (!keep.has(id)) this.map.delete(id);\r\n }\r\n}\r\n", "// Bidirectional text support (UAX#9) for the layout engine. pretext computes the\r\n// per-character embedding levels (see /pretext-patch \u2014 we reuse its UBA impl and\r\n// the explicit-base-level extension); this module turns those levels into a\r\n// VISUAL fragment order and resolves direction-aware paragraph alignment.\r\n//\r\n// Division of labour:\r\n// - pretext (computeSegmentLevels) \u2014 Unicode bidi classes \u2192 embedding levels.\r\n// - this module \u2014 UAX#9 rule L2 (reorder runs by level) + alignment mapping.\r\n// - the canvas (ctx.fillText) \u2014 intra-fragment shaping + RTL glyph ordering,\r\n// which is why a SINGLE-level fragment never needs its characters reversed\r\n// by us; only the ORDER of fragments on the line does.\r\n\r\nimport { computeSegmentLevels } from \"@chenglou/pretext/bidi\";\r\nimport type { ParaStyle } from \"@cw/shared\";\r\n\r\n/** The bidi base embedding level for a paragraph: 1 (RTL) for `direction:\"rtl\"`,\r\n * else 0 (LTR). Word's w:bidi forces the base regardless of content. */\r\nexport function baseLevelFor(direction: ParaStyle[\"direction\"]): 0 | 1 {\r\n return direction === \"rtl\" ? 1 : 0;\r\n}\r\n\r\n// Strong-RTL Unicode blocks (Hebrew, Arabic, Syriac, Thaana, NKo, Arabic\r\n// Supplement/Extended, plus the Arabic/Hebrew presentation forms). A cheap gate\r\n// so the 99% LTR-only paragraph never pays for a full bidi scan.\r\nconst RTL_CHAR = /[\u0590-\u08FF\uFB1D-\uFDFF\uFE70-\uFEFF]/;\r\n\r\n/** Cheap pre-check: could this text need bidi reordering? */\r\nexport function hasRtlChars(text: string): boolean {\r\n return RTL_CHAR.test(text);\r\n}\r\n\r\n/** Per-UTF-16-code-unit embedding levels for `text` under `baseLevel`, or null\r\n * when the text is entirely the base direction (so no reordering is needed \u2014\r\n * the LTR fast path, and pure-base-direction lines). */\r\nexport function levelsFor(text: string, baseLevel: 0 | 1): Int8Array | null {\r\n const n = text.length;\r\n if (n === 0) return null;\r\n // segStarts = every code unit, so the returned array is per-code-unit.\r\n const segStarts = new Array<number>(n);\r\n for (let i = 0; i < n; i++) segStarts[i] = i;\r\n return computeSegmentLevels(text, segStarts, baseLevel);\r\n}\r\n\r\nconst reverseInPlace = <T>(a: T[], lo: number, hi: number): void => {\r\n while (lo < hi) {\r\n const t = a[lo]!;\r\n a[lo] = a[hi]!;\r\n a[hi] = t;\r\n lo++;\r\n hi--;\r\n }\r\n};\r\n\r\n/** UAX#9 rule L2: given the embedding level of each item in LOGICAL order,\r\n * return the indices in VISUAL (left-to-right) order. Reverses each contiguous\r\n * run of level \u2265 L, from the highest level down to the lowest odd level. */\r\nexport function visualOrder(levels: readonly number[]): number[] {\r\n const n = levels.length;\r\n const order = Array.from({ length: n }, (_, i) => i);\r\n if (n <= 1) return order;\r\n const lev = levels.slice();\r\n let max = 0;\r\n let minOdd = Number.POSITIVE_INFINITY;\r\n for (const l of levels) {\r\n if (l > max) max = l;\r\n if (l & 1 && l < minOdd) minOdd = l;\r\n }\r\n if (minOdd === Number.POSITIVE_INFINITY) return order; // all even \u2192 no reorder\r\n for (let level = max; level >= minOdd; level--) {\r\n let i = 0;\r\n while (i < n) {\r\n if (lev[i]! >= level) {\r\n let j = i;\r\n while (j < n && lev[j]! >= level) j++;\r\n reverseInPlace(order, i, j - 1);\r\n reverseInPlace(lev, i, j - 1);\r\n i = j;\r\n } else i++;\r\n }\r\n }\r\n return order;\r\n}\r\n\r\n/** Map a paragraph's stored alignment onto a PHYSICAL alignment given its base\r\n * direction. In an RTL paragraph the \"start\" edge is the right, so `left`/`right`\r\n * are interpreted as start/end and swap; center/justify are unchanged. This makes\r\n * an RTL paragraph right-aligned by default (matching Word's w:bidi behaviour). */\r\nexport function effectiveAlign(\r\n align: ParaStyle[\"align\"],\r\n direction: ParaStyle[\"direction\"],\r\n): ParaStyle[\"align\"] {\r\n if (direction !== \"rtl\") return align;\r\n if (align === \"left\") return \"right\";\r\n if (align === \"right\") return \"left\";\r\n return align;\r\n}\r\n", "// Layer 2: layout engine \u2014 the ONLY module tree that imports @chenglou/pretext.\r\n//\r\n// Per paragraph: runs -> RichInlineItem[] -> prepareRichInline() (cached by revision)\r\n// then layoutNextRichInlineLineRange() loop -> LineBox[]\r\n// Then block flow + pagination -> LayoutTree with page-absolute coordinates.\r\n\r\nimport {\r\n layoutNextRichInlineLineRange,\r\n materializeRichInlineLineRange,\r\n type RichInlineCursor,\r\n} from \"@chenglou/pretext/rich-inline\";\r\nimport type { Block, CharStyle, Document, EquationBlock, ImageBlock, LineNumbering, Paragraph, ParaStyle, Run, SectionBreakType, SectionPatch, SectionProps, TableBlock, TableCell, TabStop } from \"@cw/shared\";\r\nimport { effectiveFractions, isHiddenParagraph } from \"@cw/shared\";\r\nimport { formatListNumber, markerText, type ListDefinition, type ListLevel } from \"@cw/shared\";\r\nimport type { InlineFragment, LayoutTree, LineBox, Page, PlacedBlock, PlacedImage } from \"./layoutTree\";\r\nimport { PrepareCache, prepareRunSegment, setActiveCjkFallback, setActiveArabicFallback, setActiveHebrewFallback, applyCjkLocale, type PreparedSegment } from \"./prepareCache\";\r\nimport { charStyleToFont, fontMetrics, measureTextWidth } from \"./metrics\";\r\nimport { widthScale, PARA_BORDER_PAD_PX } from \"../paint/paintStyle\";\r\nimport { baseLevelFor, effectiveAlign, hasRtlChars, levelsFor, visualOrder } from \"./bidi\";\r\nimport { setActiveFontRegistry, type CustomFontRegistry } from \"../fonts/customRegistry\";\r\nimport { equationBox, EQUATION_DISPLAY_PX } from \"./math/equationLayout\";\r\nimport type { MathBox } from \"./math/mathBox\";\r\nimport { MATH_FONT_FAMILY } from \"../fonts/clones\";\r\n\r\n/** Display equations are typeset with the bundled math font (STIX Two Math). */\r\nconst eqBox = (b: EquationBlock): MathBox => equationBox(b.equation, MATH_FONT_FAMILY, EQUATION_DISPLAY_PX);\r\n\r\n/** Word's default tab interval when a `\\t` runs past the last explicit stop\r\n * (0.5 inch at 96 dpi). */\r\nconst DEFAULT_TAB_STOP_PX = 48;\r\n\r\n/** Active default tab interval for the current layout pass \u2014 set from the\r\n * document's w:defaultTabStop (settings.xml) at the top of layout(), mirroring\r\n * the await-free module-level config the CJK fallback/font registry use. Falls\r\n * back to DEFAULT_TAB_STOP_PX for documents that don't override it. */\r\nlet activeDefaultTabStopPx = DEFAULT_TAB_STOP_PX;\r\n\r\n/** Paint-only paragraph decoration (w:shd fill + w:pBdr border box) for a placed\r\n * paragraph chunk. `boxWidth` is the content width between the paragraph's\r\n * indents at this placement site; `height` is the chunk's rendered height.\r\n * Returns undefined for an undecorated paragraph (no field set). Shared by every\r\n * paragraph-placement path (body flow, floats, table cells, bands, footnotes) so\r\n * borders/shading render consistently everywhere a paragraph lands. */\r\nfunction paraDecorFor(style: ParaStyle, boxWidth: number, height: number): NonNullable<PlacedBlock[\"paraDecor\"]> | undefined {\r\n const { borders, shading } = style;\r\n if (!borders && !shading) return undefined;\r\n // Border-to-text padding: the painters expand the box outward by `pad` so a\r\n // wide/double rule sits OUTSIDE the glyphs (and the shading fill reaches it).\r\n // Only borders need the gap; a shading-only paragraph keeps its text-edge box\r\n // so its fill is byte-identical to before.\r\n const pad = borders ? PARA_BORDER_PAD_PX : 0;\r\n return { width: Math.max(0, boxWidth), height, pad, ...(shading ? { shading } : {}), ...(borders ? { borders } : {}) };\r\n}\r\n\r\n/** Vertical space a bordered paragraph's box claims ABOVE its text, reserved in\r\n * the block gap so the box (and any shading fill) can't paint over the adjacent\r\n * block: the top rule width (if any) plus the border-to-text padding \u2014 the box\r\n * grows by `pad` above the text whenever the paragraph has borders, regardless\r\n * of which edges carry a rule. 0 for an unbordered paragraph. Used by both the\r\n * normal and the float-adjacent placement paths. */\r\nfunction paraBorderReserveTop(style: ParaStyle): number {\r\n if (!style.borders) return 0;\r\n return (style.borders.top?.widthPx ?? 0) + PARA_BORDER_PAD_PX;\r\n}\r\n\r\n/** Mirror of paraBorderReserveTop for the space below the text (bottom rule + pad). */\r\nfunction paraBorderReserveBottom(style: ParaStyle): number {\r\n if (!style.borders) return 0;\r\n return (style.borders.bottom?.widthPx ?? 0) + PARA_BORDER_PAD_PX;\r\n}\r\n\r\nconst sumLineHeights = (lines: LineBox[]): number => lines.reduce((h, l) => h + l.height, 0);\r\n\r\nexport interface LayoutOptions {\r\n /** Band being story-edited: rendered RAW ({page} tokens literal, real block\r\n * ids) so geometry offsets align with the model during editing. */\r\n rawBand?: \"header\" | \"footer\" | null;\r\n}\r\n\r\nexport interface LayoutEngine {\r\n /** Full or incremental relayout. Pass dirty ids from ApplyResult; omit for full. */\r\n layout(doc: Document, dirtyBlockIds?: string[], options?: LayoutOptions): LayoutTree;\r\n evict(blockId: string): void;\r\n /** Drop ALL cached layout \u2014 call when swapping in a wholly different document.\r\n * The importer re-mints block ids from i0 at revision 0, so without a reset the\r\n * new document's paragraphs hit the previous document's cached lines (same\r\n * id+revision+width) and the two documents render merged. */\r\n reset(): void;\r\n}\r\n\r\n/** Per-engine script-fallback config, re-asserted at the top of every layout pass so\r\n * it's never read across an `await` (concurrency-safe without a lock \u2014 see\r\n * prepareCache.ts). */\r\nexport interface LayoutEngineOptions {\r\n /** CJK fallback family: script-split CJK runs render with it. `\"\"`/whitespace or\r\n * omitted = no fallback (browser system fallback renders CJK on screen). */\r\n cjkFallback?: string | null;\r\n /** pretext analyzer locale (CJK line-break tuning) for this engine's layouts. */\r\n cjkLocale?: string;\r\n /** Arabic fallback family: script-split Arabic runs render with it. `\"\"`/whitespace\r\n * or omitted = no fallback (browser system fallback renders Arabic on screen). */\r\n arabicFallback?: string | null;\r\n /** Hebrew fallback family: script-split Hebrew runs render with it. `\"\"`/whitespace\r\n * or omitted = no fallback (browser system fallback renders Hebrew on screen). */\r\n hebrewFallback?: string | null;\r\n}\r\n\r\n/** @param fontRegistry custom-font registry to make active for this engine's layout\r\n * passes (editor mount / export job). Omit to leave the active registry untouched\r\n * (tests + recalc paths that use the process-default global).\r\n * @param opts per-engine CJK fallback + locale (defaults: no fallback, neutral). */\r\nexport function createLayoutEngine(fontRegistry?: CustomFontRegistry, opts?: LayoutEngineOptions): LayoutEngine {\r\n const cjkFallback = opts?.cjkFallback ?? null;\r\n const cjkLocale = opts?.cjkLocale;\r\n const arabicFallback = opts?.arabicFallback ?? null;\r\n const hebrewFallback = opts?.hebrewFallback ?? null;\r\n const prepCache = new PrepareCache();\r\n // Second cache tier: LineBox[] per (block revision, width). A keystroke\r\n // re-breaks ONE paragraph; every other block's lines are reused as-is and\r\n // re-layout degenerates to the pagination walk (pure arithmetic).\r\n const linesCache = new Map<string, { revision: number; width: number; lines: LineBox[] }>();\r\n\r\n // Third cache tier: the full measureTable result per (table revision, width).\r\n // measureTable re-walks every cell (1191 cells / ~9ms on a 98-page report) on\r\n // EVERY layout pass, even for unrelated edits. Its output depends only on the\r\n // table + the column width: any edit to the table OR a cell paragraph bumps\r\n // table.revision (replaceParagraphAt/replaceCellBlocks/replaceTable all do), and\r\n // the result is position-independent (placement assigns page coords afterwards),\r\n // so an unchanged table at the same width reuses its measurement verbatim.\r\n const tableCache = new Map<string, { revision: number; width: number; measured: ReturnType<typeof measureTable> }>();\r\n\r\n // Ids visited during the current FULL layout (null during a partial rawBand\r\n // pass, which only touches one band and must not evict the rest). After a full\r\n // layout we prune both caches to this set, so deleted blocks can't leak.\r\n let touched: Set<string> | null = null;\r\n\r\n const getLines = (p: Paragraph, width: number): LineBox[] => {\r\n touched?.add(p.id);\r\n const hit = linesCache.get(p.id);\r\n if (hit && hit.revision === p.revision && hit.width === width) return hit.lines;\r\n const lines = paragraphLines(p, width, prepCache);\r\n linesCache.set(p.id, { revision: p.revision, width, lines });\r\n return lines;\r\n };\r\n\r\n // Memoized top-level table measurement (body flow only; nested/band tables stay\r\n // direct \u2014 their width is derived inside an ancestor solve and their revision may\r\n // not bump independently).\r\n const getMeasuredTable = (\r\n t: TableBlock,\r\n width: number,\r\n getLinesF: (p: Paragraph, w: number) => LineBox[],\r\n listCtx: CellListCtx,\r\n ): ReturnType<typeof measureTable> => {\r\n touched?.add(t.id);\r\n const hit = tableCache.get(t.id);\r\n if (hit && hit.revision === t.revision && hit.width === width) return hit.measured;\r\n const measured = measureTable(t, width, getLinesF, listCtx);\r\n tableCache.set(t.id, { revision: t.revision, width, measured });\r\n return measured;\r\n };\r\n\r\n // Fourth cache tier: per-page header/footer layout. On a 98-page report this is\r\n // ~196 layoutBand calls (header+footer \u00D7 page) re-shaped from scratch EVERY pass\r\n // \u2014 ~20ms, and a body keystroke never touches a band. layoutBand's output is a\r\n // pure function of (band blocks, width, originX, pageNum, pageCount, rawMode) +\r\n // the active font registry, and the result is shiftPlaced into fresh objects\r\n // before use, so cache it. Band blocks are keyed by array identity: a body edit\r\n // keeps doc.section.header's reference (cache hit); a band edit mints a new array\r\n // (miss). Page-count / page-number changes vary the key (correct: {numpages} /\r\n // {page} must re-render).\r\n const bandArrayId = new WeakMap<object, number>();\r\n let bandArraySeq = 0;\r\n const idOfBandArray = (blocks: Block[]): number => {\r\n let id = bandArrayId.get(blocks);\r\n if (id === undefined) { id = ++bandArraySeq; bandArrayId.set(blocks, id); }\r\n return id;\r\n };\r\n // {date}/{time} resolve against `new Date()` at layout time (not in the cache\r\n // key), so a band carrying them must never be cached \u2014 otherwise a footer clock\r\n // would freeze. Detected once per band-array identity.\r\n const bandVolatile = new WeakMap<object, boolean>();\r\n const hasVolatileToken = (blocks: Block[]): boolean => {\r\n let v = bandVolatile.get(blocks);\r\n if (v === undefined) {\r\n v = blockTexts(blocks).some((t) => /\\{(date|time)\\}/.test(t));\r\n bandVolatile.set(blocks, v);\r\n }\r\n return v;\r\n };\r\n const bandLayoutCache = new Map<string, { placed: PlacedBlock[]; height: number }>();\r\n let touchedBands: Set<string> | null = null;\r\n const getBandLayout = (\r\n blocks: Block[],\r\n width: number,\r\n originX: number,\r\n pageNum: number,\r\n pageCount: number,\r\n bandCache: PrepareCache,\r\n rawMode: boolean,\r\n ): { placed: PlacedBlock[]; height: number } => {\r\n if (hasVolatileToken(blocks)) return layoutBand(blocks, width, originX, pageNum, pageCount, bandCache, rawMode);\r\n const key = `${idOfBandArray(blocks)}|${width}|${originX}|${pageNum}|${pageCount}|${rawMode ? 1 : 0}`;\r\n touchedBands?.add(key);\r\n const hit = bandLayoutCache.get(key);\r\n if (hit) return hit;\r\n const res = layoutBand(blocks, width, originX, pageNum, pageCount, bandCache, rawMode);\r\n bandLayoutCache.set(key, res);\r\n return res;\r\n };\r\n\r\n return {\r\n layout(doc: Document, _dirtyBlockIds?: string[], options?: LayoutOptions): LayoutTree {\r\n // Assert this engine's font registry for the whole (synchronous) layout pass\r\n // so cloneFamilyFor/metricsFor resolve against the right custom fonts. Safe\r\n // for concurrent editors/jobs: layout() never awaits, so nothing can swap the\r\n // active registry mid-pass.\r\n if (fontRegistry) setActiveFontRegistry(fontRegistry);\r\n // Same await-free re-assert for this engine's script-fallback config (see\r\n // prepareCache.ts): scriptSplitRuns reads both fallbacks during this pass.\r\n setActiveCjkFallback(cjkFallback);\r\n setActiveArabicFallback(arabicFallback);\r\n setActiveHebrewFallback(hebrewFallback);\r\n applyCjkLocale(cjkLocale);\r\n // Honor the document's w:defaultTabStop (settings.xml) for this pass; a `\\t`\r\n // past the last explicit stop advances by this interval (Word's behavior).\r\n activeDefaultTabStopPx = doc.defaultTabStopPx && doc.defaultTabStopPx > 0 ? doc.defaultTabStopPx : DEFAULT_TAB_STOP_PX;\r\n const rawBand = options?.rawBand ?? null;\r\n touched = rawBand === null ? new Set<string>() : null;\r\n touchedBands = rawBand === null ? new Set<string>() : null;\r\n try {\r\n const tree = layoutDocument(doc, getLines, (p) => {\r\n touched?.add(p.id);\r\n return prepCache.get(p);\r\n }, rawBand, getMeasuredTable, getBandLayout);\r\n if (touched) {\r\n for (const id of linesCache.keys()) if (!touched.has(id)) linesCache.delete(id);\r\n for (const id of tableCache.keys()) if (!touched.has(id)) tableCache.delete(id);\r\n prepCache.retainOnly(touched);\r\n }\r\n if (touchedBands) {\r\n for (const k of bandLayoutCache.keys()) if (!touchedBands.has(k)) bandLayoutCache.delete(k);\r\n }\r\n return tree;\r\n } finally {\r\n touched = null;\r\n touchedBands = null;\r\n }\r\n },\r\n evict(blockId: string): void {\r\n prepCache.evict(blockId);\r\n linesCache.delete(blockId);\r\n tableCache.delete(blockId);\r\n },\r\n reset(): void {\r\n prepCache.clear();\r\n linesCache.clear();\r\n tableCache.clear();\r\n bandLayoutCache.clear();\r\n },\r\n };\r\n}\r\n\r\n// ---------------------------------------------------------------------------\r\n// Paragraph -> LineBox[]\r\n\r\nfunction countSpaces(text: string): number {\r\n let n = 0;\r\n for (let i = 0; i < text.length; i++) if (text.charCodeAt(i) === 0x20) n++;\r\n return n;\r\n}\r\n\r\nconst isCollapsibleWS = (c: string | undefined): boolean =>\r\n c === \" \" || c === \"\\t\" || c === \"\\n\" || c === \"\\r\";\r\n\r\n/** Map a pretext fragment's text back onto the model run text. Pretext collapses\r\n * consecutive whitespace (white-space: normal), so the rendered fragment can be\r\n * SHORTER than its model range \u2014 a naive indexOf fails and every offset after\r\n * the collapse drifts (caret lands on the wrong character; the \"backspace\r\n * deletes 'd' instead of 'o'\" bug). The tolerant walk skips extra model\r\n * whitespace and emits an offset map only when the mapping is non-identity. */\r\nfunction mapFragmentToRun(\r\n runText: string,\r\n from: number,\r\n fragText: string,\r\n): { start: number; end: number; map?: number[] } {\r\n const exact = runText.indexOf(fragText, from);\r\n if (exact >= 0) return { start: exact, end: exact + fragText.length };\r\n\r\n const map: number[] = [];\r\n let i = from;\r\n let j = 0;\r\n let start = -1;\r\n while (j < fragText.length && i < runText.length) {\r\n if (runText[i] === fragText[j]) {\r\n if (start < 0) start = i;\r\n map.push(i - start);\r\n i++;\r\n j++;\r\n continue;\r\n }\r\n if (isCollapsibleWS(runText[i])) {\r\n i++; // model whitespace with no rendered counterpart (collapsed or eaten)\r\n continue;\r\n }\r\n start = -1; // hard mismatch\r\n break;\r\n }\r\n if (start >= 0 && j === fragText.length) {\r\n // Trailing eaten whitespace belongs to the line break / next gap, not to\r\n // this fragment \u2014 the range ends at the last rendered character.\r\n map.push(i - start);\r\n const identity = i - start === fragText.length;\r\n return identity ? { start, end: i } : { start, end: i, map };\r\n }\r\n // Last resort (should not happen): keep the old advancing fallback.\r\n return { start: from, end: from + fragText.length };\r\n}\r\n\r\ninterface RawFrag {\r\n frag: InlineFragment;\r\n hadGap: boolean; // eaten separator whitespace preceded this fragment\r\n gap: number; // width (px) of that separator gap \u2014 needed to rebuild x after bidi reorder\r\n spaces: number; // U+0020 count inside the fragment text\r\n}\r\n\r\ninterface BrokenLine {\r\n frags: RawFrag[]; // fragments with line-LOCAL x (no alignment applied)\r\n width: number;\r\n height: number;\r\n ascent: number;\r\n end: RichInlineCursor;\r\n}\r\n\r\nfunction segRunOffsets(runs: Run[], base: number): number[] {\r\n const runStarts: number[] = [];\r\n let acc = base;\r\n for (const run of runs) {\r\n runStarts.push(acc);\r\n acc += run.text.length;\r\n }\r\n return runStarts;\r\n}\r\n\r\n/** A fully-hidden paragraph takes ZERO space \u2014 unless it carries a structural\r\n * break, which we keep so the break isn't lost. */\r\nfunction isHiddenLayoutSkip(p: Paragraph): boolean {\r\n return isHiddenParagraph(p) && !p.style.sectionBreak && !p.style.pageBreakBefore;\r\n}\r\n\r\n/** Line-box height for ONE line, honoring fixed line spacing (docx w:lineRule).\r\n * \"exact\" pins the box to `lineHeightPx` (taller glyphs clip); \"atLeast\" floors\r\n * it there but lets a taller line grow; \"auto\" (the default) scales the dominant\r\n * font size by the multiplier. `natural` is the line's glyph height (ascent +\r\n * descent of its tallest run). */\r\nfunction lineBoxHeight(style: ParaStyle, fontSizePx: number, natural: number): number {\r\n if (style.lineRule === \"exact\") return style.lineHeightPx ?? natural;\r\n if (style.lineRule === \"atLeast\") return Math.max(natural, style.lineHeightPx ?? 0);\r\n return Math.max(natural, style.lineHeight * fontSizePx);\r\n}\r\n\r\n/** Default line metrics for a fragment-less line (empty paragraph / segment). */\r\nfunction emptyLineMetrics(p: Paragraph): { height: number; ascent: number } {\r\n const style = p.runs[0]?.style;\r\n const fontSize = style?.fontSizePx ?? 16;\r\n const m = style ? fontMetrics(charStyleToFont(style)) : { ascent: fontSize * 0.8, descent: fontSize * 0.2 };\r\n const natural = m.ascent + m.descent;\r\n const height = lineBoxHeight(p.style, fontSize, natural);\r\n return { height, ascent: (height - natural) / 2 + m.ascent };\r\n}\r\n\r\n/** Break ONE line of a SEGMENT at maxWidth. Mutates runCursors (snapshot before\r\n * calling if the line might be rejected and re-broken at another width). */\r\nfunction breakNextLine(\r\n p: Paragraph,\r\n seg: PreparedSegment,\r\n maxWidth: number,\r\n cursor: RichInlineCursor | undefined,\r\n runStarts: number[],\r\n runCursors: number[],\r\n): BrokenLine | null {\r\n const range = layoutNextRichInlineLineRange(seg.prepared, maxWidth, cursor);\r\n if (range === null) return null;\r\n const line = materializeRichInlineLineRange(seg.prepared, range);\r\n\r\n const frags: RawFrag[] = [];\r\n let x = 0;\r\n let maxAscent = 0;\r\n let maxDescent = 0;\r\n let maxFontSize = 0;\r\n\r\n for (const f of line.fragments) {\r\n x += f.gapBefore;\r\n const run = seg.runs[f.itemIndex]!;\r\n // Inline equation: the math box drives the line's vertical metrics (not the\r\n // sentinel font), and the box rides on the fragment for paint/geometry.\r\n if (run.style.equation) {\r\n const box = equationBox(run.style.equation, MATH_FONT_FAMILY, run.style.fontSizePx);\r\n maxAscent = Math.max(maxAscent, box.ascent);\r\n maxDescent = Math.max(maxDescent, box.descent);\r\n maxFontSize = Math.max(maxFontSize, run.style.fontSizePx);\r\n const m = mapFragmentToRun(run.text, runCursors[f.itemIndex]!, f.text);\r\n runCursors[f.itemIndex] = m.end;\r\n frags.push({\r\n frag: {\r\n blockId: p.id,\r\n startOffset: runStarts[f.itemIndex]! + m.start,\r\n endOffset: runStarts[f.itemIndex]! + m.end,\r\n text: f.text,\r\n style: run.style,\r\n x,\r\n width: f.occupiedWidth,\r\n equation: box,\r\n },\r\n hadGap: f.gapBefore > 0,\r\n gap: f.gapBefore,\r\n spaces: 0,\r\n });\r\n x += f.occupiedWidth;\r\n continue;\r\n }\r\n const fm = fontMetrics(charStyleToFont(run.style));\r\n maxAscent = Math.max(maxAscent, fm.ascent);\r\n maxDescent = Math.max(maxDescent, fm.descent);\r\n maxFontSize = Math.max(maxFontSize, run.style.fontSizePx);\r\n // Character width scaling (w:w): pretext measures the natural advance; the run\r\n // occupies that \u00D7 the scale, so reserve the scaled width here and advance by it.\r\n // scale === 1 (the common case) leaves occupiedWidth byte-identical.\r\n const occupied = f.occupiedWidth * widthScale(run.style);\r\n if (f.text.length > 0) {\r\n const m = mapFragmentToRun(run.text, runCursors[f.itemIndex]!, f.text);\r\n runCursors[f.itemIndex] = m.end;\r\n const frag: InlineFragment = {\r\n blockId: p.id,\r\n startOffset: runStarts[f.itemIndex]! + m.start,\r\n endOffset: runStarts[f.itemIndex]! + m.end,\r\n text: f.text,\r\n style: run.style,\r\n x,\r\n width: occupied,\r\n };\r\n if (m.map) frag.offsetMap = m.map;\r\n frags.push({ frag, hadGap: f.gapBefore > 0, gap: f.gapBefore, spaces: countSpaces(f.text) });\r\n }\r\n x += occupied;\r\n }\r\n\r\n if (maxFontSize === 0) {\r\n const style = p.runs[0]?.style;\r\n if (style) {\r\n const fm = fontMetrics(charStyleToFont(style));\r\n maxAscent = fm.ascent;\r\n maxDescent = fm.descent;\r\n maxFontSize = style.fontSizePx;\r\n }\r\n }\r\n\r\n const natural = maxAscent + maxDescent;\r\n const height = lineBoxHeight(p.style, maxFontSize, natural);\r\n return { frags, width: line.width, height, ascent: lineBaseline(p.style.textAlignment, height, maxAscent, maxDescent), end: line.end };\r\n}\r\n\r\n/** Baseline offset from the line-box top for the line's shared baseline, per the\r\n * paragraph's w:textAlignment. \"baseline\"/absent and \"center\" both center the\r\n * natural text block via half-leading (Word's default); \"top\"/\"bottom\" hug the\r\n * respective edge of a tall line box. Mixed-size runs still share one baseline \u2014\r\n * this shifts that baseline within the box rather than aligning each run's edge. */\r\nfunction lineBaseline(\r\n textAlignment: ParaStyle[\"textAlignment\"],\r\n height: number,\r\n maxAscent: number,\r\n maxDescent: number,\r\n): number {\r\n switch (textAlignment) {\r\n case \"top\":\r\n return maxAscent;\r\n case \"bottom\":\r\n return height - maxDescent;\r\n default:\r\n return (height - (maxAscent + maxDescent)) / 2 + maxAscent; // center / baseline\r\n }\r\n}\r\n\r\ninterface RawLine {\r\n frags: RawFrag[];\r\n width: number;\r\n indent: number;\r\n lineMaxWidth: number;\r\n height: number;\r\n ascent: number;\r\n lastOfSegment: boolean;\r\n emptyOffset?: number;\r\n leaders?: LineBox[\"leaders\"];\r\n tabArrows?: LineBox[\"tabArrows\"];\r\n paragraphEnd?: boolean;\r\n lineBreak?: boolean;\r\n /** Tab-stop line with absolute fragment x baked in \u2014 never bidi-reordered. */\r\n tabbed?: boolean;\r\n}\r\n\r\n/** Next tab stop strictly past `curX`: the first explicit stop, else the next\r\n * default-interval multiple. */\r\nfunction resolveTabStop(curX: number, stops: TabStop[], contentWidth: number): TabStop {\r\n for (const s of stops) if (s.posPx > curX + 0.5) return s;\r\n const interval = activeDefaultTabStopPx;\r\n let pos = (Math.floor(curX / interval) + 1) * interval;\r\n if (pos <= curX) pos = curX + interval;\r\n return { posPx: Math.min(pos, Math.max(curX + 1, contentWidth)), align: \"left\", leader: \"none\" };\r\n}\r\n\r\n/** Width of a piece's text up to (and including) its decimal separator \u2014 for\r\n * decimal-aligned tab stops. Measured with the piece's leading run font. */\r\nfunction decimalPrefixWidth(runs: Run[]): number {\r\n const text = runs.map((r) => r.text).join(\"\");\r\n const font = charStyleToFont(runs[0]?.style ?? DEFAULT_DECIMAL_STYLE);\r\n // The decimal separator is \".\" (en-US); fall back to \",\" only if there's no\r\n // period, so a thousands comma in \"$1,234.50\" doesn't hijack the alignment.\r\n let m = text.indexOf(\".\");\r\n if (m < 0) m = text.indexOf(\",\");\r\n return measureTextWidth(m < 0 ? text : text.slice(0, m + 1), font);\r\n}\r\nconst DEFAULT_DECIMAL_STYLE = { fontFamily: \"Georgia, serif\", fontSizePx: 16 } as CharStyle;\r\n\r\n/** Paint style for margin line numbers (w:lnNumType) \u2014 small, muted, like Word. */\r\nconst LINE_NUMBER_STYLE = { fontFamily: \"Georgia, serif\", fontSizePx: 12, color: \"#9aa0a6\" } as CharStyle;\r\n/** Default gap (px) between the line numbers and the text edge when w:distance is absent. */\r\nconst LINE_NUMBER_DISTANCE = 18;\r\n\r\n/** Lay out a `\\t`-containing segment. Each tab-delimited piece is positioned at\r\n * the next tab stop (left/center/right/decimal, with optional leaders); the\r\n * piece's text then WRAPS normally \u2014 its first line continues from the stop and\r\n * any overflow flows to new full-width lines at the left margin (so a common\r\n * leading-tab first-line indent wraps like Word instead of running off the\r\n * page). Returns one RawLine per visual line. */\r\nfunction layoutTabbedSegment(\r\n p: Paragraph,\r\n segRuns: Run[],\r\n segStart: number,\r\n contentWidth: number,\r\n firstIndent: number,\r\n): RawLine[] {\r\n // Split runs at \"\\t\" into pieces, tracking each piece's global start offset\r\n // (the \"\\t\" itself occupies one offset \u2014 caret can land between pieces).\r\n const pieces: { runs: Run[]; start: number }[] = [];\r\n let cur: Run[] = [];\r\n let pieceStart = segStart;\r\n let pos = segStart;\r\n for (const r of segRuns) {\r\n let local = 0;\r\n for (;;) {\r\n const idx = r.text.indexOf(\"\\t\", local);\r\n if (idx < 0) break;\r\n const piece = r.text.slice(local, idx);\r\n if (piece.length > 0) cur.push({ text: piece, style: r.style });\r\n pos += idx - local;\r\n pieces.push({ runs: cur, start: pieceStart });\r\n pos += 1;\r\n pieceStart = pos;\r\n cur = [];\r\n local = idx + 1;\r\n }\r\n const rest = r.text.slice(local);\r\n if (rest.length > 0) cur.push({ text: rest, style: r.style });\r\n pos += rest.length;\r\n }\r\n pieces.push({ runs: cur, start: pieceStart });\r\n\r\n const stops = (p.style.tabStops ?? []).slice().sort((a, b) => a.posPx - b.posPx);\r\n const baseStyle = segRuns.find((r) => r.text.length > 0)?.style ?? p.runs[0]?.style;\r\n const out: RawLine[] = [];\r\n\r\n // The current visual line being assembled.\r\n let curFrags: RawFrag[] = [];\r\n let curLeaders: NonNullable<RawLine[\"leaders\"]> = [];\r\n let curArrows: NonNullable<RawLine[\"tabArrows\"]> = [];\r\n let curX = firstIndent;\r\n let maxH = 0;\r\n let maxA = 0;\r\n let hasTab = false;\r\n\r\n const flush = (isLast: boolean): void => {\r\n if (maxH === 0 && baseStyle) {\r\n const fm = fontMetrics(charStyleToFont(baseStyle));\r\n maxH = lineBoxHeight(p.style, baseStyle.fontSizePx, fm.ascent + fm.descent);\r\n maxA = (maxH - (fm.ascent + fm.descent)) / 2 + fm.ascent;\r\n }\r\n out.push({\r\n frags: curFrags,\r\n width: curX,\r\n indent: 0, // fragment x is already absolute (tab/indent baked in)\r\n lineMaxWidth: contentWidth,\r\n height: maxH,\r\n ascent: maxA,\r\n // A tab-positioned line stays ragged (its manual x must not be re-justified);\r\n // pure wrapped continuation lines justify normally when the paragraph does.\r\n lastOfSegment: isLast || hasTab,\r\n ...(hasTab ? { tabbed: true } : {}),\r\n ...(curLeaders.length > 0 ? { leaders: curLeaders } : {}),\r\n ...(curArrows.length > 0 ? { tabArrows: curArrows } : {}),\r\n });\r\n curFrags = [];\r\n curLeaders = [];\r\n curArrows = [];\r\n curX = 0;\r\n maxH = 0;\r\n maxA = 0;\r\n hasTab = false;\r\n };\r\n\r\n pieces.forEach((pc, i) => {\r\n // Position this piece at its tab stop (relative to the running x cursor).\r\n if (i > 0) {\r\n const stop = resolveTabStop(curX, stops, contentWidth);\r\n const align = stop.align ?? \"left\";\r\n const fullW = measureTextWidth(pc.runs.map((r) => r.text).join(\"\"), charStyleToFont(pc.runs[0]?.style ?? baseStyle ?? DEFAULT_DECIMAL_STYLE));\r\n const fits = curX + fullW <= contentWidth; // right/center/decimal need the piece on one line\r\n let targetX = stop.posPx;\r\n if (fits && align === \"right\") targetX = stop.posPx - fullW;\r\n else if (fits && align === \"center\") targetX = stop.posPx - fullW / 2;\r\n else if (fits && align === \"decimal\") targetX = stop.posPx - decimalPrefixWidth(pc.runs);\r\n if (targetX < curX) targetX = curX;\r\n if ((stop.leader ?? \"none\") !== \"none\" && targetX > curX + 1 && baseStyle) {\r\n curLeaders.push({ x1: curX, x2: targetX, kind: stop.leader ?? \"none\", color: baseStyle.color, fontSizePx: baseStyle.fontSizePx });\r\n }\r\n // Formatting-marks overlay: remember the gap this tab opened (drawn as \"\u2192\").\r\n curArrows.push({ x1: curX, x2: Math.max(targetX, curX) });\r\n curX = targetX;\r\n hasTab = true;\r\n }\r\n if (pc.runs.length === 0) return; // empty piece (e.g. text before a leading tab)\r\n\r\n // Lay the piece out with wrapping: first sub-line continues from curX; any\r\n // overflow opens new full-width lines at the left margin. Use the CJK-split\r\n // runs the prepare actually saw so itemIndex/offset/cursor stay in sync.\r\n const prep = prepareRunSegment(pc.runs);\r\n const pseg: PreparedSegment = { prepared: prep.prepared, runs: prep.runs, startOffset: pc.start };\r\n const runStarts = segRunOffsets(prep.runs, pc.start);\r\n const runCursors = prep.runs.map(() => 0);\r\n let cursor: RichInlineCursor | undefined = undefined;\r\n let firstSub = true;\r\n for (;;) {\r\n const maxW = Math.max(24, contentWidth - (firstSub ? curX : 0));\r\n const bl = breakNextLine(p, pseg, maxW, cursor, runStarts, runCursors);\r\n if (bl === null) break;\r\n if (!firstSub) {\r\n flush(false); // previous line complete; this piece wrapped to a new line\r\n }\r\n const shift = firstSub ? curX : 0;\r\n for (const rf of bl.frags) {\r\n rf.frag.x += shift;\r\n curFrags.push(rf);\r\n }\r\n curX = shift + bl.width;\r\n maxH = Math.max(maxH, bl.height);\r\n maxA = Math.max(maxA, bl.ascent);\r\n cursor = bl.end;\r\n firstSub = false;\r\n }\r\n });\r\n\r\n flush(true);\r\n return out;\r\n}\r\n\r\n/** Justify a line: distribute `slack` px across every inter-word space (painted\r\n * via ctx.wordSpacing, so the fragment stays ONE fillText) and every eaten\r\n * inter-fragment gap. Mutates each fragment's x / width / wordSpacing in place;\r\n * the caller applies any left-edge offset (indent / float box) separately. */\r\nfunction justifyLine(frags: RawFrag[], slack: number): void {\r\n if (slack <= 0) return;\r\n const totalGaps = frags.reduce((s, rf) => s + rf.spaces + (rf.hadGap ? 1 : 0), 0);\r\n if (totalGaps <= 0) return;\r\n const extra = slack / totalGaps;\r\n let shift = 0;\r\n for (const rf of frags) {\r\n if (rf.hadGap) shift += extra;\r\n rf.frag.x += shift;\r\n if (rf.spaces > 0) {\r\n rf.frag.wordSpacingPx = extra;\r\n rf.frag.width += rf.spaces * extra;\r\n shift += rf.spaces * extra;\r\n }\r\n }\r\n}\r\n\r\n/** Per-code-unit bidi embedding levels over the WHOLE paragraph text (global\r\n * offsets \u2014 fragments carry the same), or null when the paragraph is purely its\r\n * base direction and needs no reordering (the LTR fast path AND a pure-Latin RTL\r\n * paragraph, which only needs right-alignment, handled by effectiveAlign). */\r\nfunction paragraphLevels(p: Paragraph): Int8Array | null {\r\n const base = baseLevelFor(p.style.direction);\r\n let text = \"\";\r\n const forced: [number, number][] = [];\r\n for (const r of p.runs) {\r\n const start = text.length;\r\n text += r.text;\r\n if (r.style.rtl) forced.push([start, text.length]);\r\n }\r\n if (base === 0 && forced.length === 0 && !hasRtlChars(text)) return null;\r\n let levels = levelsFor(text, base);\r\n if (levels === null) {\r\n // No strong-RTL characters resolved (e.g. an RTL paragraph of Latin text):\r\n // alignment alone makes it right-aligned, so only an explicit run `rtl` flag\r\n // forces any reordering.\r\n if (forced.length === 0) return null;\r\n levels = new Int8Array(text.length); // base-LTR fill; forced ranges go RTL below\r\n }\r\n for (const [a, b] of forced) {\r\n for (let i = a; i < b; i++) if ((levels[i]! & 1) === 0) levels[i] = levels[i]! + 1;\r\n }\r\n return levels;\r\n}\r\n\r\n/** Split a fragment whose model range spans more than one embedding level into\r\n * per-level sub-fragments (each becomes a single-direction fillText). Skips the\r\n * collapsed-whitespace case (offsetMap present), tagging the whole fragment with\r\n * its start level \u2014 mixed-script inside a single collapsed run is vanishingly\r\n * rare. Returns sub-RawFrags in LOGICAL order; only the first keeps the gap. */\r\nfunction splitFragByLevel(rf: RawFrag, levels: Int8Array): RawFrag[] {\r\n const { frag } = rf;\r\n const s = frag.startOffset;\r\n const e = frag.endOffset;\r\n const startLevel = levels[s] ?? 0;\r\n // Keep collapsed-whitespace fragments and field results (PAGE/{page} tokens are\r\n // resolved as ONE fragment by a later post-pass \u2014 splitting \"{page}\" across the\r\n // brace/letter level boundary would stop the token from ever matching) atomic.\r\n if (frag.offsetMap || frag.style.fieldId !== undefined || frag.text.length !== e - s) {\r\n frag.level = startLevel;\r\n return [rf];\r\n }\r\n // Find level-change boundaries within [s, e).\r\n const bounds: number[] = [0];\r\n for (let i = s + 1; i < e; i++) if (levels[i] !== levels[i - 1]) bounds.push(i - s);\r\n if (bounds.length === 1) {\r\n frag.level = startLevel;\r\n return [rf];\r\n }\r\n bounds.push(e - s);\r\n const font = charStyleToFont(frag.style);\r\n const fullW = measureTextWidth(frag.text, font) || frag.width;\r\n const out: RawFrag[] = [];\r\n for (let k = 0; k < bounds.length - 1; k++) {\r\n const a = bounds[k]!;\r\n const b = bounds[k + 1]!;\r\n const sub = frag.text.slice(a, b);\r\n // Proportional width keeps the sub-pieces summing to the fragment's measured\r\n // width (pretext's occupiedWidth includes letter-spacing this measure omits).\r\n // Guard fullW===0 (zero-width control/combining runs) so we never emit NaN.\r\n const w = fullW > 0 ? (measureTextWidth(sub, font) / fullW) * frag.width : 0;\r\n out.push({\r\n hadGap: k === 0 ? rf.hadGap : false,\r\n gap: k === 0 ? rf.gap : 0,\r\n spaces: countSpaces(sub),\r\n frag: {\r\n ...frag,\r\n text: sub,\r\n startOffset: s + a,\r\n endOffset: s + b,\r\n width: w,\r\n level: levels[s + a] ?? startLevel,\r\n },\r\n });\r\n }\r\n return out;\r\n}\r\n\r\n/** Reorder a line's fragments into VISUAL (left-to-right) order per UAX#9 L2 and\r\n * rebuild their line-local x. Returns the reordered frags and the new line width.\r\n * Pure-LTR lines never reach here (paragraphLevels returns null). */\r\nfunction bidiReorderLine(frags: RawFrag[], levels: Int8Array): { frags: RawFrag[]; width: number } {\r\n const split: RawFrag[] = [];\r\n for (const rf of frags) split.push(...splitFragByLevel(rf, levels));\r\n const order = visualOrder(split.map((rf) => rf.frag.level ?? 0));\r\n const visual = order.map((i) => split[i]!);\r\n let x = 0;\r\n for (const rf of visual) {\r\n x += rf.gap;\r\n rf.frag.x = x;\r\n x += rf.frag.width;\r\n }\r\n return { frags: visual, width: x };\r\n}\r\n\r\n/** Mirror a tab-stopped line for an RTL base-direction paragraph. `layoutTabbedSegment`\r\n * always lays tab stops out in LOGICAL-advance space (the cursor starts at the start\r\n * edge and grows in reading order, stop positions measured from that edge). For an\r\n * RTL paragraph the start edge is the RIGHT margin, so the line is reflected about the\r\n * content box: a piece at logical distance `d` from the start edge ends up `d` from the\r\n * right edge, and the tab cells fill right-to-left.\r\n *\r\n * Reflecting fragments in their LOGICAL order also yields the correct VISUAL order for\r\n * free (the first logical cell lands on the right), so no extra L2 reorder is needed.\r\n * Embedding levels are assigned (from `levels`, splitting mixed-level fragments; else\r\n * the RTL base) so the renderer anchors each fragment on the correct edge and caret /\r\n * hit-testing take the bidi (non-monotonic-x) path. Leaders and tab arrows mirror too. */\r\nfunction mirrorTabbedLineRtl(rl: RawLine, levels: Int8Array | null, contentWidth: number): void {\r\n const split: RawFrag[] = [];\r\n for (const rf of rl.frags) {\r\n if (levels) {\r\n // splitFragByLevel copies the parent x onto every sub-piece, so re-spread the\r\n // sub-pieces sequentially across the parent's box before the reflection below.\r\n let x = rf.frag.x;\r\n for (const sub of splitFragByLevel(rf, levels)) {\r\n sub.frag.x = x;\r\n x += sub.frag.width;\r\n split.push(sub);\r\n }\r\n } else {\r\n rf.frag.level = 1; // pure base-direction RTL line \u2014 every fragment is RTL\r\n split.push(rf);\r\n }\r\n }\r\n for (const rf of split) rf.frag.x = contentWidth - rf.frag.x - rf.frag.width;\r\n rl.frags = split;\r\n // The reflected fragments already span the content box anchored at the right edge,\r\n // so neutralize phase-2 alignment (slack === 0 \u2192 no further shift).\r\n rl.width = contentWidth;\r\n if (rl.leaders) rl.leaders = rl.leaders.map((l) => ({ ...l, x1: contentWidth - l.x2, x2: contentWidth - l.x1 }));\r\n if (rl.tabArrows) rl.tabArrows = rl.tabArrows.map((a) => ({ x1: contentWidth - a.x2, x2: contentWidth - a.x1 }));\r\n}\r\n\r\nfunction paragraphLines(p: Paragraph, contentWidth: number, cache: PrepareCache): LineBox[] {\r\n const segments = cache.get(p);\r\n const lines: LineBox[] = [];\r\n const levels = paragraphLevels(p);\r\n const dir = p.style.direction;\r\n\r\n // Phase 1: break lines per SEGMENT (segments = soft-break \"\\v\" pieces).\r\n // Fragments are line-LOCAL; justification needs to know each segment's last\r\n // line (it stays ragged, like a paragraph's final line), so alignment is a\r\n // second pass.\r\n const raw: RawLine[] = [];\r\n\r\n let first = true; // first line of the PARAGRAPH (first-line indent)\r\n // Index of the last raw line each segment contributed \u2014 the segment boundary\r\n // where a formatting mark lands (\u00B6 for the paragraph's end, \u21B5 for a soft break\r\n // between segments). Set after every segment so each one always has an entry.\r\n const segLastLine: number[] = [];\r\n for (let si = 0; si < segments.length; si++) {\r\n const seg = segments[si]!;\r\n // Tab path: a segment with hard tabs lays out as one tab-stopped line (the\r\n // pretext collapse path would otherwise eat the tabs). Dormant unless run\r\n // text actually carries \"\\t\".\r\n if (seg.runs.some((r) => r.text.includes(\"\\t\"))) {\r\n raw.push(...layoutTabbedSegment(p, seg.runs, seg.startOffset, contentWidth, first ? p.style.indentFirstLinePx : 0));\r\n first = false;\r\n segLastLine[si] = raw.length - 1;\r\n continue;\r\n }\r\n\r\n const runStarts = segRunOffsets(seg.runs, seg.startOffset);\r\n const runCursors: number[] = seg.runs.map(() => 0);\r\n let cursor: RichInlineCursor | undefined = undefined;\r\n let produced = false;\r\n\r\n for (;;) {\r\n const indent = first ? p.style.indentFirstLinePx : 0;\r\n const lineMaxWidth = contentWidth - indent;\r\n const bl = breakNextLine(p, seg, lineMaxWidth, cursor, runStarts, runCursors);\r\n if (bl === null) break;\r\n raw.push({\r\n frags: bl.frags,\r\n width: bl.width,\r\n indent,\r\n lineMaxWidth,\r\n height: bl.height,\r\n ascent: bl.ascent,\r\n lastOfSegment: false,\r\n });\r\n cursor = bl.end;\r\n first = false;\r\n produced = true;\r\n }\r\n\r\n if (!produced) {\r\n // Empty segment (\"\\v\" at paragraph end, or \"\\v\\v\"): a blank line the\r\n // caret can land on \u2014 its offset is the segment start.\r\n const m = emptyLineMetrics(p);\r\n raw.push({\r\n frags: [],\r\n width: 0,\r\n indent: 0,\r\n lineMaxWidth: contentWidth,\r\n height: m.height,\r\n ascent: m.ascent,\r\n lastOfSegment: true,\r\n emptyOffset: seg.startOffset,\r\n });\r\n first = false;\r\n } else {\r\n raw[raw.length - 1]!.lastOfSegment = true;\r\n }\r\n segLastLine[si] = raw.length - 1;\r\n }\r\n\r\n // Formatting marks: each segment boundary carries a pilcrow (the paragraph's\r\n // final segment) or a line-break arrow (a soft return separating segments).\r\n for (let si = 0; si < segLastLine.length; si++) {\r\n const idx = segLastLine[si];\r\n if (idx === undefined) continue;\r\n if (si === segments.length - 1) raw[idx]!.paragraphEnd = true;\r\n else raw[idx]!.lineBreak = true;\r\n }\r\n\r\n // Phase 2: bidi reorder (RTL/mixed only), alignment + justification, final boxes.\r\n const align = effectiveAlign(p.style.align, dir);\r\n const rtlBase = baseLevelFor(dir) === 1;\r\n let y = 0;\r\n for (const rl of raw) {\r\n // Tabbed lines bake absolute x at tab stops, so the generic edge-to-edge bidi\r\n // reorder (which discards those x positions) can't run on them. An RTL paragraph\r\n // instead REFLECTS the line about the content box: tab stops then measure from\r\n // the right (start) edge and cells fill right-to-left, the Word w:bidi behavior.\r\n if (rl.tabbed) {\r\n // Mirror any RTL tabbed line that carries geometry \u2014 text, leaders, or just a\r\n // tab-arrow overlay (a \"\\t\"-only line has arrows but no fragments/leaders).\r\n const hasGeometry =\r\n rl.frags.length > 0 || (rl.leaders?.length ?? 0) > 0 || (rl.tabArrows?.length ?? 0) > 0;\r\n if (rtlBase && hasGeometry) mirrorTabbedLineRtl(rl, levels, contentWidth);\r\n } else if (levels !== null && rl.frags.length > 0) {\r\n const r = bidiReorderLine(rl.frags, levels);\r\n rl.frags = r.frags;\r\n rl.width = r.width;\r\n }\r\n const slack = rl.lineMaxWidth - rl.width;\r\n let startX = rl.indent;\r\n if (align === \"center\") startX += slack / 2;\r\n else if (align === \"right\") startX += slack;\r\n // Justify works on the VISUAL fragment order (bidi reorder already ran), so it\r\n // distributes slack across the line's gaps edge-to-edge regardless of direction.\r\n else if (align === \"justify\" && !rl.lastOfSegment) justifyLine(rl.frags, slack);\r\n for (const rf of rl.frags) rf.frag.x += startX;\r\n const box: LineBox = { y, height: rl.height, ascent: rl.ascent, fragments: rl.frags.map((rf) => rf.frag) };\r\n if (rl.emptyOffset !== undefined) box.emptyOffset = rl.emptyOffset;\r\n if (rl.leaders && rl.leaders.length > 0) {\r\n box.leaders = rl.leaders.map((l) => ({ ...l, x1: l.x1 + startX, x2: l.x2 + startX }));\r\n }\r\n if (rl.tabArrows && rl.tabArrows.length > 0) {\r\n box.tabArrows = rl.tabArrows.map((a) => ({ x1: a.x1 + startX, x2: a.x2 + startX }));\r\n }\r\n if (rl.paragraphEnd) box.paragraphEnd = true;\r\n if (rl.lineBreak) box.lineBreak = true;\r\n lines.push(box);\r\n y += rl.height;\r\n }\r\n\r\n return lines;\r\n}\r\n\r\n// ---------------------------------------------------------------------------\r\n// Block flow + pagination (line-level page breaks: a paragraph may span pages).\r\n// Word-default break rules: orphan control (\u22652 lines stay at the bottom of the\r\n// page where a paragraph starts, else the whole paragraph moves), widow control\r\n// (\u22652 lines reach the paragraph's final page), keep-with-next for headings.\r\n\r\nconst ORPHAN_MIN = 2; // min lines kept on the starting page when breaking\r\nconst WIDOW_MIN = 2; // min lines carried onto the paragraph's last page\r\nconst TOC_GUTTER = 48; // right gutter reserved on TOC entries for the page number\r\n\r\n// ---------------------------------------------------------------------------\r\n// Sections: a section-break paragraph TERMINATES a section (OOXML sectPr\r\n// placement); blocks after the last break belong to `doc.section`. Absent\r\n// patch fields inherit from doc.section (\"link to previous\").\r\n\r\nconst BAND_KEYS = [\"header\", \"footer\", \"headerFirst\", \"headerEven\", \"footerFirst\", \"footerEven\"] as const;\r\n\r\nexport function effectiveSection(base: SectionProps, patch: SectionPatch): SectionProps {\r\n const out: SectionProps = {\r\n pageWidthPx: patch.pageWidthPx ?? base.pageWidthPx,\r\n pageHeightPx: patch.pageHeightPx ?? base.pageHeightPx,\r\n marginPx: patch.marginPx ?? base.marginPx,\r\n };\r\n // columns: undefined = inherit, null = explicitly single-column\r\n const columns = patch.columns === undefined ? base.columns : (patch.columns ?? undefined);\r\n if (columns) out.columns = columns;\r\n // page-number restart is a section's OWN property \u2014 never inherited\r\n if (patch.pageNumberStart !== undefined) out.pageNumberStart = patch.pageNumberStart;\r\n // Band distances inherit from the document section (the report sets them once).\r\n const headerDist = patch.headerDistancePx ?? base.headerDistancePx;\r\n if (headerDist !== undefined) out.headerDistancePx = headerDist;\r\n const footerDist = patch.footerDistancePx ?? base.footerDistancePx;\r\n if (footerDist !== undefined) out.footerDistancePx = footerDist;\r\n // Page fill & borders inherit from the document section unless overridden.\r\n const pageColorHex = patch.pageColorHex ?? base.pageColorHex;\r\n if (pageColorHex !== undefined) out.pageColorHex = pageColorHex;\r\n const pageBorders = patch.pageBorders ?? base.pageBorders;\r\n if (pageBorders !== undefined) out.pageBorders = pageBorders;\r\n // Line numbering is a section's OWN property (like page-number restart): a\r\n // section either declares its own w:lnNumType or has none \u2014 it never inherits.\r\n if (patch.lineNumbering !== undefined) out.lineNumbering = patch.lineNumbering;\r\n for (const key of BAND_KEYS) {\r\n const blocks = patch[key] ?? base[key];\r\n if (blocks) out[key] = blocks;\r\n }\r\n return out;\r\n}\r\n\r\n/** Top Y of the header band. Word anchors the header's TOP edge at w:header from\r\n * the page top (the band grows down); absent that, center it in the top margin. */\r\nfunction headerBandTop(s: SectionProps, bandHeight: number): number {\r\n if (s.headerDistancePx !== undefined) return s.headerDistancePx;\r\n return Math.max(8, (s.marginPx.top - bandHeight) / 2);\r\n}\r\n\r\n/** Top Y of the footer band. Word anchors the footer's BOTTOM edge at w:footer\r\n * from the page bottom (the band grows up), so a tall footer sits higher than a\r\n * bottom-flush one; absent that, center it in the bottom margin. */\r\nfunction footerBandTop(s: SectionProps, bandHeight: number): number {\r\n if (s.footerDistancePx !== undefined) return s.pageHeightPx - s.footerDistancePx - bandHeight;\r\n return s.pageHeightPx - Math.max(8, (s.marginPx.bottom - bandHeight) / 2) - bandHeight;\r\n}\r\n\r\ninterface ResolvedSection {\r\n props: SectionProps;\r\n /** Index (inclusive) of this section's last top-level block. */\r\n endBlock: number;\r\n /** The OOXML w:type that governs how THIS section's first page begins\r\n * (\"nextPage\"/\"evenPage\"/\"oddPage\"). Read when the engine starts the section. */\r\n breakType: SectionBreakType;\r\n}\r\n\r\nexport function resolveSections(doc: Document): ResolvedSection[] {\r\n const out: ResolvedSection[] = [];\r\n for (let i = 0; i < doc.blocks.length; i++) {\r\n const b = doc.blocks[i]!;\r\n if (b.kind === \"paragraph\" && b.style.sectionBreak) {\r\n out.push({\r\n props: effectiveSection(doc.section, b.style.sectionBreak.props),\r\n endBlock: i,\r\n breakType: b.style.sectionBreak.type,\r\n });\r\n }\r\n }\r\n // The trailing body section keeps its own start type (even/odd parity), so a\r\n // document whose final section begins on a parity page is honored, not flattened.\r\n out.push({ props: doc.section, endBlock: doc.blocks.length - 1, breakType: doc.section.breakType ?? \"nextPage\" });\r\n return out;\r\n}\r\n\r\nfunction layoutDocument(\r\n doc: Document,\r\n getLines: (p: Paragraph, width: number) => LineBox[],\r\n getPrepared: (p: Paragraph) => PreparedSegment[],\r\n rawBand: \"header\" | \"footer\" | null,\r\n measureTableCached: (\r\n t: TableBlock,\r\n width: number,\r\n getLinesF: (p: Paragraph, w: number) => LineBox[],\r\n listCtx: CellListCtx,\r\n ) => ReturnType<typeof measureTable> = measureTable,\r\n layoutBandCached: (\r\n blocks: Block[],\r\n width: number,\r\n originX: number,\r\n pageNum: number,\r\n pageCount: number,\r\n bandCache: PrepareCache,\r\n rawMode: boolean,\r\n ) => { placed: PlacedBlock[]; height: number } = layoutBand,\r\n): LayoutTree {\r\n // Tall bands PUSH the content box (Word): a header taller than its margin\r\n // moves contentTop down; a tall footer raises contentBottom. Heights are\r\n // estimated per section by pre-laying each band variant once with\r\n // representative page numbers (the real per-page band layout happens after\r\n // the walk \u2014 actual heights can only be \u2264 the estimate's digit width).\r\n const BAND_GAP = 6;\r\n const bandBoxCache = new Map<SectionProps, { top: number; bottom: number }>();\r\n let bandProbeCache: PrepareCache | null = null;\r\n const contentBoxOf = (s: SectionProps): { top: number; bottom: number } => {\r\n const hit = bandBoxCache.get(s);\r\n if (hit) return hit;\r\n let top = s.marginPx.top;\r\n let bottom = s.pageHeightPx - s.marginPx.bottom;\r\n const headers = [s.header, s.headerFirst, s.headerEven].filter((b): b is Block[] => !!b);\r\n const footers = [s.footer, s.footerFirst, s.footerEven].filter((b): b is Block[] => !!b);\r\n if (headers.length > 0 || footers.length > 0) {\r\n bandProbeCache ??= new PrepareCache();\r\n const cw = s.pageWidthPx - s.marginPx.left - s.marginPx.right;\r\n const cx = s.marginPx.left;\r\n const heightOf = (blocks: Block[]): number =>\r\n layoutBand(blocks, cw, cx, 999, 999, bandProbeCache!, false).height;\r\n // Height from the band's FIRST visible row to its bottom \u2014 leading blank\r\n // lines don't need exclusive body space (they overlap the body's blank tail).\r\n const bandVisibleHeight = (blocks: Block[]): number => {\r\n const band = layoutBand(blocks, cw, cx, 999, 999, bandProbeCache!, false);\r\n for (const pb of band.placed) {\r\n const visible =\r\n !!pb.table ||\r\n !!pb.image ||\r\n !!pb.equation ||\r\n pb.lines.some((l) => l.fragments.some((f) => f.text.trim().length > 0 || !!f.equation));\r\n if (visible) return band.height - pb.y;\r\n }\r\n return 0;\r\n };\r\n const headerH = headers.reduce((m, b) => Math.max(m, heightOf(b)), 0);\r\n if (headerH > 0) {\r\n const y0 = headerBandTop(s, headerH);\r\n top = Math.max(top, y0 + headerH + BAND_GAP);\r\n }\r\n const footerH = footers.reduce((m, b) => Math.max(m, heightOf(b)), 0);\r\n if (footerH > 0) {\r\n if (s.footerDistancePx !== undefined) {\r\n // Anchored footer: reserve down to its first VISIBLE row, not the band\r\n // top. Leading blank footer lines may overlap the body's (also blank)\r\n // tail \u2014 reserving them would strand a trailing blank line on a new page.\r\n const footerBottom = s.pageHeightPx - s.footerDistancePx;\r\n const visibleH = footers.reduce((m, b) => Math.max(m, bandVisibleHeight(b)), 0);\r\n bottom = Math.min(bottom, footerBottom - visibleH);\r\n } else {\r\n bottom = Math.min(bottom, footerBandTop(s, footerH) - BAND_GAP);\r\n }\r\n }\r\n bottom = Math.max(bottom, top + 24); // degenerate giant bands: keep a sliver\r\n }\r\n const box = { top, bottom };\r\n bandBoxCache.set(s, box);\r\n return box;\r\n };\r\n\r\n // Page geometry is PER SECTION \u2014 mutable, swapped as the walk crosses\r\n // section boundaries. (Single-section documents never reassign.)\r\n const sections = resolveSections(doc);\r\n let sec: SectionProps = sections[0]!.props;\r\n let contentX = 0;\r\n let contentTop = 0;\r\n let contentBottom = 0;\r\n let contentWidth = 0;\r\n // Newspaper columns: flow fills column boxes left-to-right before paging.\r\n // colBoxes holds each column's x + width; colWidth is the single MEASURE width\r\n // (the narrowest box for unequal columns, so wrapped content never overflows \u2014\r\n // a documented single-pass limitation). colSeparatorsX are the gap midpoints\r\n // when a separator line is requested.\r\n let colCount = 1;\r\n let colWidth = 0;\r\n let colBoxes: { x: number; width: number }[] = [];\r\n let colSeparatorsX: number[] = [];\r\n const applySection = (props: SectionProps): void => {\r\n sec = props;\r\n const box = contentBoxOf(sec);\r\n contentX = sec.marginPx.left;\r\n contentTop = box.top;\r\n contentBottom = box.bottom;\r\n contentWidth = sec.pageWidthPx - sec.marginPx.left - sec.marginPx.right;\r\n colCount = Math.max(1, sec.columns?.count ?? 1);\r\n const gap = sec.columns?.gapPx ?? 24;\r\n const cols = sec.columns?.cols;\r\n if (colCount > 1 && cols && cols.length === colCount) {\r\n // Explicit per-column widths + per-column trailing gap (Word honors literally).\r\n let x = contentX;\r\n colBoxes = cols.map((c, i) => {\r\n const b = { x, width: c.widthPx };\r\n x += c.widthPx + (i < colCount - 1 ? c.spaceAfterPx : 0);\r\n return b;\r\n });\r\n colWidth = Math.min(...cols.map((c) => c.widthPx));\r\n } else if (colCount > 1) {\r\n colWidth = (contentWidth - (colCount - 1) * gap) / colCount;\r\n colBoxes = Array.from({ length: colCount }, (_, i) => ({\r\n x: contentX + i * (colWidth + gap),\r\n width: colWidth,\r\n }));\r\n } else {\r\n colWidth = contentWidth;\r\n colBoxes = [{ x: contentX, width: contentWidth }];\r\n }\r\n colSeparatorsX = sec.columns?.sep\r\n ? colBoxes.slice(0, -1).map((b, i) => (b.x + b.width + colBoxes[i + 1]!.x) / 2)\r\n : [];\r\n };\r\n applySection(sec);\r\n\r\n // List support: per-paragraph effective indent (style + level) and the\r\n // NUMBERING PASS \u2014 counters per (listId, level) in document order, emitting\r\n // paint-only markers. Counter state is pure string arithmetic; line caches\r\n // are untouched (markers can't change line breaking).\r\n const lists = doc.lists ?? {};\r\n const listLevelOf = (p: Paragraph): ListLevel | null => {\r\n const ref = p.style.list;\r\n if (!ref) return null;\r\n const def: ListDefinition | undefined = lists[ref.listId];\r\n if (!def) return null;\r\n return def.levels[Math.min(ref.level, def.levels.length - 1)] ?? null;\r\n };\r\n // Indents are mirrored for RTL paragraphs: the \"start\" indent (left + list) moves\r\n // to the RIGHT edge \u2014 which also opens the right-side gutter the list marker hangs\r\n // in \u2014 and the \"end\" indent (right) moves to the left. LTR is unchanged.\r\n const startIndentOf = (p: Paragraph): number => p.style.indentLeftPx + (listLevelOf(p)?.indentLeftPx ?? 0);\r\n const indentOf = (p: Paragraph): number =>\r\n p.style.direction === \"rtl\" ? (p.style.indentRightPx ?? 0) : startIndentOf(p);\r\n const rightIndentOf = (p: Paragraph): number =>\r\n p.style.direction === \"rtl\" ? startIndentOf(p) : (p.style.indentRightPx ?? 0);\r\n // The list-level indent alone (table cells add it ON TOP of the paragraph's\r\n // own indent, which their placement already applies).\r\n const listIndentOf = (p: Paragraph): number => listLevelOf(p)?.indentLeftPx ?? 0;\r\n\r\n const counters = new Map<string, number[]>();\r\n // Marker x is resolved at PLACEMENT time (placed.x - hangingPx) \u2014 with\r\n // columns, the numbering pass can't know which column the paragraph lands in.\r\n const markers = new Map<string, { text: string; style: CharStyle; hangingPx: number }>();\r\n const numberParagraph = (p: Paragraph): void => {\r\n const ref = p.style.list;\r\n const lvl = listLevelOf(p);\r\n if (!ref || !lvl) return;\r\n const def = lists[ref.listId]!;\r\n const stack = counters.get(ref.listId) ?? [];\r\n stack[ref.level] = (stack[ref.level] ?? lvl.start - 1) + 1;\r\n stack.length = ref.level + 1; // incrementing a level resets all deeper ones\r\n counters.set(ref.listId, stack);\r\n const text = markerText(def, ref.level, stack);\r\n if (text.length === 0) return;\r\n const baseStyle = p.runs[0]?.style;\r\n if (!baseStyle) return;\r\n markers.set(p.id, {\r\n text,\r\n style: { ...baseStyle, ...(lvl.markerStyle ?? {}) },\r\n hangingPx: lvl.hangingPx,\r\n });\r\n };\r\n\r\n // Numbering runs over the whole body in reading order BEFORE measurement \u2014\r\n // recursing into table cells so a list continues straight through them (Word\r\n // counts 1,2,3 down a column of cells, not restarting per cell). Markers are\r\n // then read at placement time for both body and cell paragraphs.\r\n const numberBlocks = (blocks: Block[]): void => {\r\n for (const b of blocks) {\r\n if (b.kind === \"paragraph\") numberParagraph(b);\r\n else if (b.kind === \"table\") for (const row of b.rows) for (const cell of row.cells) numberBlocks(cell.blocks);\r\n }\r\n };\r\n numberBlocks(doc.blocks);\r\n const cellListCtx: CellListCtx = { indentOf: listIndentOf, markers };\r\n\r\n // Measure every block first (prepare/line caches make re-runs cheap); break\r\n // rules need full sizes before placement decisions.\r\n type Measured =\r\n | { kind: \"para\"; block: Paragraph; lines: LineBox[] }\r\n | { kind: \"image\"; block: ImageBlock; height: number }\r\n | { kind: \"equation\"; block: EquationBlock; box: MathBox; height: number }\r\n | { kind: \"table\"; block: TableBlock; rows: MeasuredRow[]; colWidths: number[]; height: number; tableWidth: number; xOffset: number };\r\n\r\n // Measured at each block's OWN section width (the section pointer advances\r\n // through the same block order the walk uses).\r\n const measured: Measured[] = [];\r\n let secIdx = 0;\r\n for (let bi = 0; bi < doc.blocks.length; bi++) {\r\n while (bi > sections[secIdx]!.endBlock) applySection(sections[++secIdx]!.props);\r\n const block = doc.blocks[bi]!;\r\n if (block.kind === \"paragraph\") {\r\n if (isHiddenLayoutSkip(block)) continue; // fully-hidden anchor: contributes no layout\r\n // Indented paragraphs (quotes, list levels) measure at the narrowed width;\r\n // colWidth IS contentWidth in single-column sections. TOC entries reserve\r\n // a right gutter so their text never collides with the page number.\r\n const gutter = block.style.tocEntry ? TOC_GUTTER : 0;\r\n measured.push({\r\n kind: \"para\",\r\n block,\r\n lines: getLines(block, colWidth - indentOf(block) - rightIndentOf(block) - gutter),\r\n });\r\n } else if (block.kind === \"image\") {\r\n // Anchored (out-of-flow) images contribute no flow height.\r\n measured.push({ kind: \"image\", block, height: block.anchor ? 0 : block.heightPx });\r\n } else if (block.kind === \"equation\") {\r\n const box = eqBox(block);\r\n measured.push({ kind: \"equation\", block, box, height: box.ascent + box.descent });\r\n } else {\r\n const t = measureTableCached(block, colWidth, getLines, cellListCtx);\r\n measured.push({ kind: \"table\", block, ...t });\r\n }\r\n }\r\n secIdx = 0;\r\n applySection(sections[0]!.props);\r\n\r\n // Which section governs each page \u2014 bands and paint read per-page geometry.\r\n const pageSections: SectionProps[] = [];\r\n const mkPage = (): Page => {\r\n pageSections.push(sec);\r\n const p: Page = {\r\n index: pageSections.length - 1,\r\n number: pageSections.length, // provisional; the post-pass sets the real value\r\n blocks: [],\r\n widthPx: sec.pageWidthPx,\r\n heightPx: sec.pageHeightPx,\r\n marginPx: sec.marginPx,\r\n contentTopPx: contentTop,\r\n contentBottomPx: contentBottom,\r\n };\r\n if (sec.pageColorHex !== undefined) p.pageColorHex = sec.pageColorHex;\r\n if (sec.pageBorders !== undefined) p.pageBorders = sec.pageBorders;\r\n if (colSeparatorsX.length) p.columnSeparatorsX = colSeparatorsX.slice();\r\n return p;\r\n };\r\n\r\n const pages: Page[] = [mkPage()];\r\n let page = pages[0]!;\r\n let y = contentTop;\r\n\r\n // TOC entries: last placed chunk per entry block \u2014 the page-number\r\n // decoration is attached there in a post-pass once page numbers exist.\r\n const tocPlacements = new Map<string, { chunk: PlacedBlock; rightEdge: number; para: Paragraph }>();\r\n\r\n // ---- footnotes ----------------------------------------------------------\r\n // A note reserves space at the bottom of the page its REFERENCE lands on:\r\n // `reserved` shrinks the effective bottom for everything placed after, and\r\n // the chunk carrying the ref is shrunk until chunk + notes co-fit (the\r\n // greedy version of Word's per-page fixpoint \u2014 one pass, deterministic).\r\n const FN_SEP = 14; // separator rule + padding above the first note\r\n const FN_INDENT = 18; // note text indent; the number marker hangs in it\r\n const fns = doc.footnotes ?? {};\r\n const hasNotes = Object.keys(fns).length > 0;\r\n let reserved = 0;\r\n const bottomY = (): number => contentBottom - reserved;\r\n const placedNotes = new Set<string>();\r\n const pageNotes: string[][] = [[]];\r\n const pageReserved: number[] = [0];\r\n const noteNumbers = new Map<string, string>(); // id -> marker text (the ref run's text)\r\n interface NoteMeasure {\r\n paras: { p: Paragraph; lines: LineBox[] }[];\r\n height: number;\r\n }\r\n const noteMeasure = (id: string): NoteMeasure | null => {\r\n const paras = fns[id];\r\n if (!paras || paras.length === 0) return null;\r\n const w = Math.max(40, contentWidth - FN_INDENT);\r\n let height = 0;\r\n const out = paras.map((p) => {\r\n const lines = getLines(p, w);\r\n height += p.style.spaceBeforePx + totalHeight(lines) + p.style.spaceAfterPx;\r\n return { p, lines };\r\n });\r\n return { paras: out, height };\r\n };\r\n /** New (unplaced) refs inside lines[i..i+take): [refId, markerText][] */\r\n const refsInLines = (lines: LineBox[], i: number, take: number): [string, string][] => {\r\n const out: [string, string][] = [];\r\n for (let k = i; k < i + take; k++) {\r\n for (const f of lines[k]!.fragments) {\r\n const id = f.style.footnoteRef;\r\n if (id && fns[id] && !placedNotes.has(id) && !out.some(([o]) => o === id)) out.push([id, f.text]);\r\n }\r\n }\r\n return out;\r\n };\r\n\r\n // Column cursor: blocks place at colX(); flow-driven breaks advance the\r\n // column first, then the page. \"Empty page\" guards become \"empty COLUMN\"\r\n // guards (forced progress, atomic placement) \u2014 tracked by where the current\r\n // column started in page.blocks.\r\n let colIdx = 0;\r\n let colStartCount = 0;\r\n const colX = (): number => colBoxes[colIdx]?.x ?? contentX;\r\n const colHasContent = (): boolean => page.blocks.length > colStartCount;\r\n\r\n /** Explicit page break / section start: always a fresh page, column 1. */\r\n const hardPage = (): void => {\r\n colIdx = 0;\r\n colStartCount = 0;\r\n page = mkPage();\r\n pages.push(page);\r\n pageNotes.push([]);\r\n pageReserved.push(0);\r\n reserved = 0; // footnote reservations are per PAGE (columns share the area)\r\n y = contentTop; // note: space-before is suppressed at the top of a page (Word behavior)\r\n floats = []; // floats never cross pages (or columns)\r\n };\r\n\r\n /** Flow advance: next column, or next page when columns are exhausted. */\r\n const newPage = (): void => {\r\n if (colIdx + 1 < colCount) {\r\n colIdx++;\r\n colStartCount = page.blocks.length;\r\n y = contentTop;\r\n floats = [];\r\n } else {\r\n hardPage();\r\n }\r\n };\r\n\r\n /** Re-stamp the current (empty) page with the active section's geometry instead\r\n * of leaving a blank page when a section starts at a fresh page boundary. */\r\n const restampEmptyPage = (): void => {\r\n page.widthPx = sec.pageWidthPx;\r\n page.heightPx = sec.pageHeightPx;\r\n page.marginPx = sec.marginPx;\r\n page.contentTopPx = contentTop;\r\n page.contentBottomPx = contentBottom;\r\n if (sec.pageColorHex !== undefined) page.pageColorHex = sec.pageColorHex;\r\n else delete page.pageColorHex;\r\n if (sec.pageBorders !== undefined) page.pageBorders = sec.pageBorders;\r\n else delete page.pageBorders;\r\n if (colSeparatorsX.length) page.columnSeparatorsX = colSeparatorsX.slice();\r\n else delete page.columnSeparatorsX;\r\n pageSections[page.index] = sec;\r\n colIdx = 0;\r\n colStartCount = 0;\r\n y = contentTop;\r\n floats = [];\r\n };\r\n\r\n /** Section boundary: start the next section's first page. An EMPTY current\r\n * page is re-stamped with the new geometry instead of leaving a blank page.\r\n * For an evenPage/oddPage break the section's first content page must land on\r\n * an even/odd page number \u2014 a blank filler page is inserted when the running\r\n * parity is wrong (Word's behavior). Parity is read off the provisional 1-based\r\n * page number, which equals the printed number absent a pageNumberStart restart. */\r\n const startSectionPage = (breakType: SectionBreakType): void => {\r\n if (page.blocks.length === 0) restampEmptyPage();\r\n else hardPage();\r\n if (breakType === \"evenPage\" || breakType === \"oddPage\") {\r\n const wantEven = breakType === \"evenPage\";\r\n if ((page.number % 2 === 0) !== wantEven) {\r\n // Current page is the wrong parity: leave it blank (the filler) and push a\r\n // fresh page (hardPage stamps it from the active section) for the content.\r\n hardPage();\r\n }\r\n }\r\n };\r\n\r\n /** Absolute x of a list marker. LTR: it hangs `hangingPx` left of the text\r\n * start (placedX). RTL: the indent gutter is on the RIGHT, so the marker hangs\r\n * just past the line's (right-aligned) right edge, pushed to the far side of the\r\n * gutter to mirror the LTR gap. */\r\n const markerX = (\r\n block: Paragraph,\r\n placedX: number,\r\n line: LineBox | undefined,\r\n marker: { text: string; style: CharStyle; hangingPx: number },\r\n ): number => {\r\n if (block.style.direction !== \"rtl\") return placedX - marker.hangingPx;\r\n let rightEdge = 0;\r\n for (const f of line?.fragments ?? []) rightEdge = Math.max(rightEdge, f.x + f.width);\r\n const markerW = measureTextWidth(marker.text, charStyleToFont(marker.style));\r\n return placedX + rightEdge + Math.max(0, marker.hangingPx - markerW);\r\n };\r\n\r\n const placeRun = (block: Paragraph, lines: LineBox[], from: number, count: number): void => {\r\n const placed: PlacedBlock = {\r\n blockId: block.id,\r\n x: colX() + indentOf(block),\r\n y,\r\n firstLineIndex: from,\r\n lines: [],\r\n };\r\n const marker = from === 0 ? markers.get(block.id) : undefined;\r\n if (marker) {\r\n placed.marker = { text: marker.text, style: marker.style, x: markerX(block, placed.x, lines[from], marker) };\r\n }\r\n if (block.style.tocEntry) {\r\n // The number decorates the LAST chunk's last line; right edge = this column's.\r\n tocPlacements.set(block.id, { chunk: placed, rightEdge: colX() + colWidth, para: block });\r\n }\r\n page.blocks.push(placed);\r\n let chunkHeight = 0;\r\n for (let k = from; k < from + count; k++) {\r\n const line = lines[k]!;\r\n placed.lines.push({ ...line, y: y - placed.y });\r\n y += line.height;\r\n chunkHeight += line.height;\r\n }\r\n // Paragraph shading / border box (w:shd / w:pBdr): the box spans this column's\r\n // content edges between the paragraph's indents, and this chunk's lines tall.\r\n // Painted behind the text in renderer.ts / pdf paintBlock.ts.\r\n const decor = paraDecorFor(block.style, colWidth - indentOf(block) - rightIndentOf(block), chunkHeight);\r\n if (decor) placed.paraDecor = decor;\r\n };\r\n\r\n /** How many lines starting at `from` fit above the effective bottom at the current y. */\r\n const countFit = (lines: LineBox[], from: number): number => {\r\n let fit = 0;\r\n let yy = y;\r\n while (from + fit < lines.length && yy + lines[from + fit]!.height <= bottomY()) {\r\n yy += lines[from + fit]!.height;\r\n fit++;\r\n }\r\n return fit;\r\n };\r\n\r\n /** Page-bottom space the given refs' notes need (FN_SEP only when this page\r\n * has no notes yet), paired with the measures to commit. */\r\n const measureNotes = (refs: [string, string][]): { H: number; measures: [string, string, NoteMeasure][] } => {\r\n let H = pageNotes[page.index]!.length === 0 ? FN_SEP : 0;\r\n const measures: [string, string, NoteMeasure][] = [];\r\n for (const [id, numText] of refs) {\r\n const m = noteMeasure(id);\r\n if (m) {\r\n H += m.height;\r\n measures.push([id, numText, m]);\r\n }\r\n }\r\n return { H, measures };\r\n };\r\n\r\n /** Reserve `H` px at this page's bottom and mark the notes placed. */\r\n const commitNotes = (measures: [string, string, NoteMeasure][], H: number): void => {\r\n for (const [id, numText] of measures) {\r\n placedNotes.add(id);\r\n pageNotes[page.index]!.push(id);\r\n noteNumbers.set(id, numText);\r\n }\r\n reserved += H;\r\n pageReserved[page.index] = reserved;\r\n };\r\n\r\n /** New (unplaced) footnote refs in a set of table rows (one level deep into\r\n * nested tables), document order: [refId, markerText][]. */\r\n const refsInRows = (rows: TableBlock[\"rows\"]): [string, string][] => {\r\n const out: [string, string][] = [];\r\n const visit = (blocks: Block[]): void => {\r\n for (const b of blocks) {\r\n if (b.kind === \"paragraph\") {\r\n let acc = 0;\r\n for (const r of b.runs) {\r\n const id = r.style.footnoteRef;\r\n if (id && fns[id] && !placedNotes.has(id) && !out.some(([o]) => o === id)) out.push([id, r.text]);\r\n acc += r.text.length;\r\n }\r\n } else if (b.kind === \"table\") {\r\n for (const row of b.rows) for (const cell of row.cells) visit(cell.blocks);\r\n }\r\n }\r\n };\r\n for (const row of rows) for (const cell of row.cells) visit(cell.blocks);\r\n return out;\r\n };\r\n\r\n /** Reserve footnote space for the new refs in lines[i..i+take), shrinking\r\n * `take` until the chunk and its notes co-fit on this page. Mutates the\r\n * reservation state when it commits. */\r\n const fitChunkWithNotes = (lines: LineBox[], i: number, take: number): number => {\r\n for (;;) {\r\n if (take <= 0) return take;\r\n const refs = refsInLines(lines, i, take);\r\n if (refs.length === 0) return take;\r\n const { H, measures } = measureNotes(refs);\r\n if (measures.length === 0) return take;\r\n let chunkH = 0;\r\n for (let k = i; k < i + take; k++) chunkH += lines[k]!.height;\r\n const fits = y + chunkH + H <= bottomY();\r\n if (fits || (take === 1 && !colHasContent())) {\r\n // Commit (overflow rather than loop when even one line can't co-fit\r\n // in an empty column \u2014 the note may then collide; Word splits notes,\r\n // we don't yet).\r\n commitNotes(measures, H);\r\n return take;\r\n }\r\n take--;\r\n }\r\n };\r\n\r\n const placeParagraph = (block: Paragraph, lines: LineBox[]): void => {\r\n // keep-lines-together: a paragraph that would split moves WHOLE to the\r\n // next column/page \u2014 unless it can't fit on an empty one (then it splits\r\n // normally, like Word).\r\n if (block.style.keepLinesTogether === true && colHasContent()) {\r\n const total = totalHeight(lines);\r\n if (y + total > bottomY() && total <= contentBottom - contentTop) newPage();\r\n }\r\n let i = 0;\r\n while (i < lines.length) {\r\n const remaining = lines.length - i;\r\n const fit = countFit(lines, i);\r\n\r\n let take: number;\r\n if (fit >= remaining) {\r\n take = remaining;\r\n } else {\r\n take = fit;\r\n // Widow/orphan control is Word's default (ON); w:widowControl=\"0\" disables it,\r\n // letting a lone first/last line break across the page boundary.\r\n const widow = block.style.widowControl !== false;\r\n // Widow: never push a single last line to the next page \u2014 give it company.\r\n if (widow && remaining - take === 1) take -= WIDOW_MIN - 1;\r\n // Orphan: at the paragraph's start, keep \u22652 lines here or move it whole.\r\n if (widow && i === 0 && take > 0 && take < ORPHAN_MIN) take = 0;\r\n // Forced progress: in an empty column the rules yield (a line taller than\r\n // the page, or a 3-line paragraph that can't satisfy 2+2) \u2014 place what fits.\r\n if (take <= 0) take = !colHasContent() ? Math.max(1, fit) : 0;\r\n }\r\n\r\n // Footnotes referenced by the chunk reserve page-bottom space; the chunk\r\n // shrinks until both co-fit (a smaller chunk references fewer notes).\r\n if (take > 0 && hasNotes) take = fitChunkWithNotes(lines, i, take);\r\n\r\n if (take > 0) {\r\n placeRun(block, lines, i, take);\r\n i += take;\r\n }\r\n if (i >= lines.length) return;\r\n newPage();\r\n }\r\n };\r\n\r\n const totalHeight = (lines: LineBox[]): number => {\r\n let h = 0;\r\n for (const l of lines) h += l.height;\r\n return h;\r\n };\r\n\r\n // Active floats on the CURRENT page (wrap:'square' images). Cleared on page\r\n // break \u2014 floats never cross pages.\r\n interface Float {\r\n left: number;\r\n right: number;\r\n bottom: number;\r\n side: \"left\" | \"right\";\r\n }\r\n let floats: Float[] = [];\r\n const FLOAT_GUTTER = 10;\r\n\r\n /** Line box available at vertical position yy within the CURRENT column,\r\n * shrunk by active floats. */\r\n const lineBoxAt = (yy: number): { x0: number; width: number } => {\r\n let x0 = colX();\r\n let x1 = colX() + colWidth;\r\n for (const f of floats) {\r\n if (yy >= f.bottom) continue;\r\n if (f.side === \"left\") x0 = Math.max(x0, f.right + FLOAT_GUTTER);\r\n else x1 = Math.min(x1, f.left - FLOAT_GUTTER);\r\n }\r\n return { x0, width: Math.max(40, x1 - x0) };\r\n };\r\n\r\n const floatsActiveAt = (yy: number): boolean => floats.some((f) => f.bottom > yy);\r\n\r\n /** wp:anchor + wp:wrapNone: an absolutely-positioned behind/in-front image.\r\n * Positioned at its offset from the relativeFrom origin; it does NOT advance\r\n * the flow cursor and registers NO float (text flows OVER it, not around).\r\n * Z-order falls out of document order \u2014 a background image precedes the body\r\n * in the block list, so it paints first (behind). */\r\n const placeAnchoredImage = (img: ImageBlock): void => {\r\n const a = img.anchor!;\r\n let ox: number;\r\n switch (a.relFromH) {\r\n case \"page\":\r\n case \"leftMargin\": ox = 0; break;\r\n case \"rightMargin\": ox = sec.pageWidthPx - sec.marginPx.right; break;\r\n case \"column\": ox = colX(); break;\r\n default: ox = sec.marginPx.left; break; // margin / character\r\n }\r\n let oy: number;\r\n switch (a.relFromV) {\r\n case \"page\":\r\n case \"topMargin\": oy = 0; break;\r\n case \"bottomMargin\": oy = sec.pageHeightPx - sec.marginPx.bottom; break;\r\n case \"paragraph\":\r\n case \"line\": oy = y; break; // current flow position\r\n default: oy = sec.marginPx.top; break; // margin\r\n }\r\n const placedImage: PlacedImage = { src: img.src, width: img.widthPx, height: img.heightPx, z: a.z ?? 0, ...(img.crop ? { crop: img.crop } : {}) };\r\n if (a.behind) placedImage.behind = true;\r\n else placedImage.front = true;\r\n page.blocks.push({\r\n blockId: img.id,\r\n x: ox + a.offsetXPx,\r\n y: oy + a.offsetYPx,\r\n firstLineIndex: 0,\r\n lines: [],\r\n image: placedImage,\r\n });\r\n };\r\n\r\n const placeImage = (img: ImageBlock): void => {\r\n if (img.anchor) { placeAnchoredImage(img); return; }\r\n if (y + img.heightPx > bottomY() && colHasContent()) newPage();\r\n const floating = img.wrap === \"square\" && img.align !== \"center\";\r\n const slack = colWidth - img.widthPx;\r\n const x =\r\n colX() + (img.align === \"center\" ? slack / 2 : img.align === \"right\" ? slack : 0);\r\n page.blocks.push({\r\n blockId: img.id,\r\n x,\r\n y,\r\n firstLineIndex: 0,\r\n lines: [],\r\n image: { src: img.src, width: img.widthPx, height: img.heightPx, ...(img.crop ? { crop: img.crop } : {}) },\r\n });\r\n if (floating) {\r\n // Text flows beside the image: register the float, do NOT advance y.\r\n floats.push({ left: x, right: x + img.widthPx, bottom: y + img.heightPx, side: img.align === \"right\" ? \"right\" : \"left\" });\r\n } else {\r\n y += img.heightPx;\r\n }\r\n };\r\n\r\n const placeEquation = (eqb: EquationBlock, box: MathBox): void => {\r\n const h = box.ascent + box.descent;\r\n if (y + h > bottomY() && colHasContent()) newPage();\r\n const align = eqb.align ?? \"center\";\r\n const slack = colWidth - box.width;\r\n const x = colX() + (align === \"center\" ? slack / 2 : align === \"right\" ? slack : 0);\r\n page.blocks.push({\r\n blockId: eqb.id,\r\n x,\r\n y,\r\n firstLineIndex: 0,\r\n lines: [],\r\n equation: { box, width: box.width, height: h, baseline: box.ascent },\r\n });\r\n y += h;\r\n };\r\n\r\n /** Float-affected paragraphs: re-break per line with the float-shrunk width\r\n * at the line's own y (pretext's per-line maxWidth makes this cheap). A line\r\n * that doesn't fit the page is ROLLED BACK (runCursors snapshot) and\r\n * re-broken at full width on the next page. Justify is applied with a\r\n * one-line buffer (a line is justified once the NEXT line proves it isn't the\r\n * segment's last \u2014 which stays ragged, like a paragraph's final line). */\r\n const placeParagraphFloating = (p: Paragraph): void => {\r\n const segments = getPrepared(p);\r\n const levels = paragraphLevels(p);\r\n const palign = effectiveAlign(p.style.align, p.style.direction);\r\n let first = true;\r\n let lineIdx = 0;\r\n let placed: PlacedBlock | null = null;\r\n\r\n // Attach the paragraph's shading/border box to the chunk currently being\r\n // built \u2014 once before each page-break reset and once at the end \u2014 so a boxed\r\n // paragraph beside a float still renders its decoration (per chunk).\r\n const decorateFloat = (): void => {\r\n if (placed && placed.lines.length) {\r\n const d = paraDecorFor(p.style, colWidth - indentOf(p) - rightIndentOf(p), sumLineHeights(placed.lines));\r\n if (d) placed.paraDecor = d;\r\n }\r\n };\r\n\r\n const pushLine = (\r\n frags: RawFrag[],\r\n height: number,\r\n ascent: number,\r\n emptyOffset?: number,\r\n ): void => {\r\n if (placed === null) {\r\n placed = { blockId: p.id, x: colX() + indentOf(p), y, firstLineIndex: lineIdx, lines: [] };\r\n const marker = lineIdx === 0 ? markers.get(p.id) : undefined;\r\n if (marker) {\r\n // Beside a float the line text is shifted right (frag.x carries the float\r\n // offset); hang the marker off the FIRST line's actual start so it tracks\r\n // the text instead of stranding at the left margin ON TOP of the float.\r\n // Equals placed.x - hangingPx when there's no shift (frag.x === 0).\r\n // RTL: hang past the line's right edge instead (mirrored gutter).\r\n let mx: number;\r\n if (p.style.direction === \"rtl\") {\r\n let rightEdge = 0;\r\n for (const rf of frags) rightEdge = Math.max(rightEdge, rf.frag.x + rf.frag.width);\r\n const markerW = measureTextWidth(marker.text, charStyleToFont(marker.style));\r\n mx = placed.x + rightEdge + Math.max(0, marker.hangingPx - markerW);\r\n } else {\r\n mx = placed.x + (frags[0]?.frag.x ?? 0) - marker.hangingPx;\r\n }\r\n placed.marker = { text: marker.text, style: marker.style, x: mx };\r\n }\r\n page.blocks.push(placed);\r\n }\r\n const box: LineBox = { y: y - placed.y, height, ascent, fragments: frags.map((rf) => rf.frag) };\r\n if (emptyOffset !== undefined) box.emptyOffset = emptyOffset;\r\n placed.lines.push(box);\r\n y += height;\r\n lineIdx++;\r\n };\r\n\r\n for (const seg of segments) {\r\n const runStarts = segRunOffsets(seg.runs, seg.startOffset);\r\n const runCursors: number[] = seg.runs.map(() => 0);\r\n let cursor: RichInlineCursor | undefined = undefined;\r\n let produced = false;\r\n // Buffered previous line for justify: held until the next line confirms it\r\n // isn't the segment's last (the last line stays ragged). Reset per segment.\r\n let justifyPrev: { frags: RawFrag[]; slack: number } | null = null;\r\n\r\n for (;;) {\r\n const snapshot = runCursors.slice();\r\n const box = lineBoxAt(y);\r\n const indent = first ? p.style.indentFirstLinePx : 0;\r\n const bl = breakNextLine(\r\n p,\r\n seg,\r\n Math.max(24, box.width - indentOf(p) - indent - rightIndentOf(p)),\r\n cursor,\r\n runStarts,\r\n runCursors,\r\n );\r\n if (bl === null) break;\r\n if (y + bl.height > bottomY() && colHasContent()) {\r\n for (let k = 0; k < runCursors.length; k++) runCursors[k] = snapshot[k]!;\r\n decorateFloat();\r\n newPage(); // floats cleared; the line re-breaks at full width\r\n placed = null;\r\n continue;\r\n }\r\n if (levels !== null && bl.frags.length > 0) {\r\n const r = bidiReorderLine(bl.frags, levels);\r\n bl.frags = r.frags;\r\n bl.width = r.width;\r\n }\r\n const slack = box.width - indent - rightIndentOf(p) - bl.width;\r\n let startX = box.x0 - colX() + indent;\r\n if (palign === \"center\") startX += slack / 2;\r\n else if (palign === \"right\") startX += slack;\r\n for (const rf of bl.frags) rf.frag.x += startX;\r\n // Justify the PREVIOUS line now that this one exists (so it's non-last);\r\n // buffer this line for the same decision next iteration. Justify runs on the\r\n // visual fragment order, so bidi-reordered lines justify too.\r\n if (palign === \"justify\") {\r\n if (justifyPrev) justifyLine(justifyPrev.frags, justifyPrev.slack);\r\n justifyPrev = { frags: bl.frags, slack };\r\n }\r\n pushLine(bl.frags, bl.height, bl.ascent);\r\n cursor = bl.end;\r\n first = false;\r\n produced = true;\r\n }\r\n\r\n if (!produced) {\r\n const m = emptyLineMetrics(p);\r\n if (y + m.height > bottomY() && colHasContent()) {\r\n decorateFloat();\r\n newPage();\r\n placed = null;\r\n }\r\n pushLine([], m.height, m.ascent, seg.startOffset);\r\n first = false;\r\n }\r\n }\r\n decorateFloat();\r\n };\r\n\r\n /** Tables split at ROW boundaries across pages (Word behavior). At least one\r\n * row per chunk; a lone row taller than the page overflows in place. */\r\n const placeTableChunked = (m: Measured & { kind: \"table\" }): void => {\r\n // A vertical merge can't survive a row-boundary split \u2014 the rowSpan cell (and\r\n // usually the header row it shares) live only in the first chunk, leaving the\r\n // continuation page with an empty column. So a merged table that fits on a\r\n // full page moves WHOLE to the next column/page rather than splitting (Word's\r\n // effective behavior for these comparable grids). Taller-than-a-page merged\r\n // tables still split (unavoidable).\r\n const hasRowSpan = m.block.rows.some((r) => r.cells.some((c) => (c.rowSpan ?? 1) > 1));\r\n if (hasRowSpan && colHasContent() && y + m.height > bottomY() && m.height <= contentBottom - contentTop) {\r\n newPage();\r\n }\r\n // Repeat-header rows (w:tblHeader): the LEADING contiguous header rows are\r\n // re-drawn at the top of every continuation chunk. They appear normally inside\r\n // the first chunk (rows 0..); on later pages we place them as a SEPARATE table\r\n // block above the data chunk, which keeps each placed block's rows contiguous\r\n // (the invariant geometry/cellRangeRects rely on). Disabled when a vertical\r\n // merge is present (a rowSpan can't survive being detached from its band) or\r\n // when every row is a header (nothing left to continue).\r\n let headerCount = 0;\r\n while (headerCount < m.rows.length && m.block.rows[headerCount]?.props?.repeatHeader) headerCount++;\r\n const repeatHeader = headerCount > 0 && headerCount < m.rows.length && !hasRowSpan;\r\n const headerRows = repeatHeader ? m.rows.slice(0, headerCount) : [];\r\n const headerHeight = headerRows.reduce((s, r) => s + r.height, 0);\r\n // w:cantSplit needs no dedicated branch here: this paginator is ROW-ATOMIC \u2014 the\r\n // chunk loop below only ever slices at row boundaries (m.rows.slice(ri, ri+fit))\r\n // and places whole measured rows, so a row's cells are never broken across a page.\r\n // Every row is therefore kept-whole already; `props.cantSplit` round-trips for\r\n // fidelity and stays the marker to exclude a row should true intra-row splitting\r\n // ever be added. (A row taller than a full empty column still overflows \u2014 there is\r\n // nowhere to move it \u2014 matching the no-cantSplit case.)\r\n let ri = 0;\r\n while (ri < m.rows.length) {\r\n // Once we are past the original header band, every continuation chunk reserves\r\n // space for the repeated header at the top.\r\n const repeat = repeatHeader && ri >= headerCount;\r\n const topUsed = repeat ? headerHeight : 0;\r\n let fit = 0;\r\n let yy = y + topUsed;\r\n while (ri + fit < m.rows.length && yy + m.rows[ri + fit]!.height <= bottomY()) {\r\n yy += m.rows[ri + fit]!.height;\r\n fit++;\r\n }\r\n if (fit === 0) {\r\n if (colHasContent()) {\r\n newPage();\r\n continue;\r\n }\r\n fit = 1; // row taller than an empty column: overflow rather than loop\r\n }\r\n // Footnote refs inside these rows reserve page-bottom space; shrink the\r\n // chunk until rows + notes co-fit (the table analogue of fitChunkWithNotes).\r\n let pendingNotes: [string, string, NoteMeasure][] = [];\r\n let pendingNotesH = 0;\r\n for (;;) {\r\n const refs = refsInRows(m.block.rows.slice(ri, ri + fit));\r\n if (refs.length === 0) break;\r\n const { H, measures } = measureNotes(refs);\r\n if (measures.length === 0) break;\r\n let chunkH = topUsed;\r\n for (let k = ri; k < ri + fit; k++) chunkH += m.rows[k]!.height;\r\n if (y + chunkH + H <= bottomY() || (fit === 1 && !colHasContent())) {\r\n pendingNotes = measures;\r\n pendingNotesH = H;\r\n break;\r\n }\r\n fit--;\r\n if (fit === 0) break; // even one row + its notes overflow \u2192 next page\r\n }\r\n if (fit === 0) {\r\n newPage();\r\n continue;\r\n }\r\n if (pendingNotes.length > 0) commitNotes(pendingNotes, pendingNotesH);\r\n if (repeat) {\r\n // Repeated header band \u2014 its own contiguous placed block at logical rows 0..\r\n page.blocks.push(placeTable(m.block, headerRows, m.colWidths, colX() + m.xOffset, y, m.tableWidth, 0, cellListCtx));\r\n y += headerHeight;\r\n }\r\n const chunk = m.rows.slice(ri, ri + fit);\r\n page.blocks.push(placeTable(m.block, chunk, m.colWidths, colX() + m.xOffset, y, m.tableWidth, ri, cellListCtx));\r\n y += chunk.reduce((s, r) => s + r.height, 0);\r\n ri += fit;\r\n if (ri < m.rows.length) newPage();\r\n }\r\n };\r\n\r\n // Contextual spacing (docx w:contextualSpacing): a paragraph flagged with it\r\n // drops its before/after spacing against an adjacent SAME-STYLE paragraph\r\n // (Word's list-style default), so a run of same-style paragraphs sits tight\r\n // while the run's outer edges keep their spacing. True when `cur` is such a\r\n // paragraph sitting flush against same-named-style paragraph `adj`.\r\n const csSuppresses = (cur: Measured | undefined, adj: Measured | undefined): boolean =>\r\n cur?.kind === \"para\" &&\r\n adj?.kind === \"para\" &&\r\n cur.block.style.contextualSpacing === true &&\r\n cur.block.style.namedStyle === adj.block.style.namedStyle;\r\n\r\n for (let bi = 0; bi < measured.length; bi++) {\r\n // Crossing into a new section: swap geometry, force its first page.\r\n if (bi > sections[secIdx]!.endBlock) {\r\n while (bi > sections[secIdx]!.endBlock) applySection(sections[++secIdx]!.props);\r\n startSectionPage(sections[secIdx]!.breakType);\r\n }\r\n const m = measured[bi]!;\r\n\r\n // Two directly-adjacent atomics (a title-bar table stacked on its data grid,\r\n // back-to-back images) sit FLUSH \u2014 the gap belongs between an atomic and\r\n // surrounding text, not between atomics, so don't double it into an empty line.\r\n // Anchored (behind/in-front) images are out of flow \u2014 transparent to the\r\n // gap logic so they neither take a gap nor suppress one between neighbours.\r\n const atomicKind = (x: Measured | undefined): boolean =>\r\n x?.kind === \"table\" || x?.kind === \"equation\" || (x?.kind === \"image\" && x.block.anchor === undefined);\r\n const prevAtomic = atomicKind(measured[bi - 1]);\r\n const nextAtomic = atomicKind(measured[bi + 1]);\r\n\r\n if (m.kind === \"image\") {\r\n // Out-of-flow anchor: place absolutely, advance nothing, no gap.\r\n if (m.block.anchor) { placeImage(m.block); continue; }\r\n if (!prevAtomic) y += ATOMIC_GAP;\r\n placeImage(m.block);\r\n if (!nextAtomic && (m.block.wrap !== \"square\" || m.block.align === \"center\")) y += ATOMIC_GAP;\r\n continue;\r\n }\r\n if (m.kind === \"equation\") {\r\n if (!prevAtomic) y += ATOMIC_GAP;\r\n for (const f of floats) if (f.bottom > y) y = f.bottom;\r\n placeEquation(m.block, m.box);\r\n if (!nextAtomic) y += ATOMIC_GAP;\r\n continue;\r\n }\r\n if (m.kind === \"table\") {\r\n if (!prevAtomic) y += ATOMIC_GAP;\r\n // Tables don't flow beside floats the way text does \u2014 drop below any float\r\n // still active at y so the grid never overlaps a floated image.\r\n for (const f of floats) if (f.bottom > y) y = f.bottom;\r\n placeTableChunked(m);\r\n if (!nextAtomic) y += ATOMIC_GAP;\r\n continue;\r\n }\r\n\r\n const { block, lines } = m;\r\n // Page break = fresh PAGE (even from column 2); column break = next column.\r\n if (block.style.pageBreakBefore === true && (page.blocks.length > 0 || colIdx > 0)) hardPage();\r\n else if (block.style.columnBreakBefore === true && colHasContent()) newPage();\r\n // Contextual spacing: suppress this paragraph's outer spacing against an\r\n // adjacent same-style paragraph (see csSuppresses).\r\n const suppressBefore = csSuppresses(m, measured[bi - 1]);\r\n const suppressAfter = csSuppresses(m, measured[bi + 1]);\r\n if (!suppressBefore) y += block.style.spaceBeforePx;\r\n if (y >= bottomY() && colHasContent()) newPage();\r\n\r\n // Float-affected paragraphs re-break per line with float-shrunk widths \u2014\r\n // bypassing the precomputed full-width lines (and widow/orphan rules).\r\n if (floatsActiveAt(y)) {\r\n // Reserve the border box (rule widths + pad) around the float-adjacent\r\n // chunk too \u2014 placeParagraphFloating still attaches paraDecor with `pad`,\r\n // so the box would otherwise extend into the next block (w:pBdr).\r\n y += paraBorderReserveTop(block.style);\r\n placeParagraphFloating(block);\r\n y += paraBorderReserveBottom(block.style);\r\n if (!suppressAfter) y += block.style.spaceAfterPx;\r\n continue;\r\n }\r\n\r\n // Keep-with-next: if this block fits here but the keep-CHAIN hanging off it\r\n // can't start on this page (each keepWithNext member must fit WHOLE, and\r\n // the first non-keep successor must keep \u2265 its orphan/widow take \u2014\r\n // mirroring placeParagraph's rules), break before this block instead.\r\n if (block.style.keepWithNext === true && measured[bi + 1] !== undefined && colHasContent()) {\r\n // Mirror the contextual-spacing suppression the real placement applies, so\r\n // a same-style contextual run isn't over-measured and broken when it fits.\r\n let yy = y + totalHeight(lines) + (suppressAfter ? 0 : block.style.spaceAfterPx);\r\n let ok = yy <= bottomY();\r\n for (let k = bi + 1; ok; k++) {\r\n const m2 = measured[k];\r\n if (m2 === undefined) break;\r\n if (m2.kind !== \"para\") {\r\n // Atomic chain end: images need to fit entirely; tables only their\r\n // first row (they chunk at row boundaries).\r\n const firstUnit = m2.kind === \"table\" ? (m2.rows[0]?.height ?? m2.height) : m2.height;\r\n if (yy + ATOMIC_GAP + firstUnit > bottomY()) ok = false;\r\n break;\r\n }\r\n if (!csSuppresses(m2, measured[k - 1])) yy += m2.block.style.spaceBeforePx;\r\n const afterGap = csSuppresses(m2, measured[k + 1]) ? 0 : m2.block.style.spaceAfterPx;\r\n const inChain = m2.block.style.keepWithNext === true && measured[k + 1] !== undefined;\r\n if (inChain || m2.block.style.keepLinesTogether === true) {\r\n // Chain member (or keep-lines paragraph): must fit WHOLE.\r\n const h = totalHeight(m2.lines);\r\n if (yy + h > bottomY()) {\r\n ok = false;\r\n break;\r\n }\r\n yy += h + afterGap;\r\n if (!inChain) break;\r\n continue;\r\n }\r\n // An empty spacer paragraph (e.g. a blank line between a \"keep with next\"\r\n // heading and its table) must NOT satisfy the keep \u2014 otherwise the heading\r\n // sticks to the blank line and orphans from the content it belongs with.\r\n // Bridge through it (fit it whole) to the real next block.\r\n if (measured[k + 1] !== undefined && m2.block.runs.every((r) => r.text.trim().length === 0)) {\r\n const h = totalHeight(m2.lines);\r\n if (yy + h > bottomY()) {\r\n ok = false;\r\n break;\r\n }\r\n yy += h + afterGap;\r\n continue;\r\n }\r\n // Chain terminator: needs its orphan/widow-legal first take.\r\n let fit = 0;\r\n let fy = yy;\r\n while (fit < m2.lines.length && fy + m2.lines[fit]!.height <= bottomY()) {\r\n fy += m2.lines[fit]!.height;\r\n fit++;\r\n }\r\n let take = fit;\r\n // Apply the orphan/widow take only when the terminator has widow control on\r\n // (default); widowControl:false lets a lone line stand, so don't force a page.\r\n if (fit < m2.lines.length && m2.block.style.widowControl !== false) {\r\n if (m2.lines.length - take === 1) take -= WIDOW_MIN - 1; // widow\r\n if (take < ORPHAN_MIN) take = 0; // orphan\r\n }\r\n if (take <= 0) ok = false;\r\n break;\r\n }\r\n if (!ok) newPage();\r\n }\r\n\r\n // Reserve the paragraph border box (top/bottom rule widths + border-to-text\r\n // padding) in the surrounding gaps so a boxed paragraph's box \u2014 expanded\r\n // outward by `pad`, and any shading fill \u2014 doesn't paint over the adjacent\r\n // block (w:pBdr).\r\n y += paraBorderReserveTop(block.style);\r\n placeParagraph(block, lines);\r\n y += paraBorderReserveBottom(block.style);\r\n if (!suppressAfter) y += block.style.spaceAfterPx;\r\n }\r\n\r\n // Margin line numbers (w:lnNumType): walk pages in order and number each body\r\n // text line of every line-numbered section. Runs BEFORE footnote paragraphs are\r\n // appended below, so notes are never numbered, and reads page.blocks in flow\r\n // order (which is vertical order within a column). `countBy` selects which\r\n // numbers show; `restart` controls when the counter resets \u2014 \"newPage\" (Word's\r\n // default), \"newSection\", or \"continuous\" (straight through). Numbers are\r\n // paint-only, pre-measured and right-aligned into the left margin so both the\r\n // canvas renderer and PDF painter just fillText at (x, baseline).\r\n if (pageSections.some((s) => s.lineNumbering)) {\r\n const font = charStyleToFont(LINE_NUMBER_STYLE);\r\n let counter = 1;\r\n let started = false; // \"continuous\": initialise the counter only once\r\n let prevSection: SectionProps | null = null;\r\n for (const pg of pages) {\r\n const s = pageSections[pg.index]!;\r\n const ln: LineNumbering | undefined = s.lineNumbering;\r\n if (!ln) {\r\n prevSection = s;\r\n continue;\r\n }\r\n const start = ln.start ?? 1;\r\n const countBy = Math.max(1, Math.round(ln.countBy ?? 1));\r\n const restart = ln.restart ?? \"newPage\";\r\n if (restart === \"newPage\") counter = start;\r\n else if (restart === \"newSection\") {\r\n if (s !== prevSection) counter = start;\r\n } else if (!started) counter = start; // continuous\r\n started = true;\r\n const rightEdge = pg.marginPx.left - (ln.distancePx ?? LINE_NUMBER_DISTANCE);\r\n const labels: NonNullable<Page[\"lineNumbers\"]> = [];\r\n for (const b of pg.blocks) {\r\n if (b.lines.length === 0 || b.image || b.table || b.equation) continue; // body paragraphs only\r\n for (const line of b.lines) {\r\n if (counter % countBy === 0) {\r\n const text = String(counter);\r\n labels.push({\r\n x: rightEdge - measureTextWidth(text, font),\r\n baseline: b.y + line.y + line.ascent,\r\n text,\r\n style: LINE_NUMBER_STYLE,\r\n });\r\n }\r\n counter++;\r\n }\r\n }\r\n if (labels.length > 0) pg.lineNumbers = labels;\r\n prevSection = s;\r\n }\r\n }\r\n\r\n // Footnote areas: each page's notes stack at the bottom under a separator\r\n // rule, inside the space reserved during the walk. Note paragraphs are REAL\r\n // model paragraphs pushed as page blocks \u2014 geometry indexes them, so caret,\r\n // selection, and typing inside notes work with zero special cases. The\r\n // number marker (the ref run's text) is paint-only, hung in the indent.\r\n for (const pg of pages) {\r\n const ids = pageNotes[pg.index];\r\n if (!ids || ids.length === 0) continue;\r\n const ps = pageSections[pg.index]!;\r\n applySection(ps); // contentWidth/contentBottom for noteMeasure + placement\r\n let ny = contentBottom - pageReserved[pg.index]!;\r\n pg.footnoteRuleY = ny + 4;\r\n ny += FN_SEP;\r\n const nx = ps.marginPx.left;\r\n for (const id of ids) {\r\n const m = noteMeasure(id);\r\n if (!m) continue;\r\n let first = true;\r\n for (const np of m.paras) {\r\n ny += np.p.style.spaceBeforePx;\r\n const placed: PlacedBlock = {\r\n blockId: np.p.id,\r\n x: nx + FN_INDENT,\r\n y: ny,\r\n firstLineIndex: 0,\r\n lines: np.lines,\r\n };\r\n if (first && np.p.runs[0]) {\r\n placed.marker = { text: `${noteNumbers.get(id) ?? \"\u2022\"}.`, style: np.p.runs[0].style, x: nx };\r\n first = false;\r\n }\r\n const noteDecor = paraDecorFor(\r\n np.p.style,\r\n contentWidth - FN_INDENT - np.p.style.indentLeftPx - (np.p.style.indentRightPx ?? 0),\r\n totalHeight(np.lines),\r\n );\r\n if (noteDecor) placed.paraDecor = noteDecor;\r\n pg.blocks.push(placed);\r\n ny += totalHeight(np.lines) + np.p.style.spaceAfterPx;\r\n }\r\n }\r\n }\r\n\r\n // Endnotes: collected at the END of the document, under a separator rule, in\r\n // reference order (Word's \"end of document\" placement \u2014 the counterpart to the\r\n // page-bottom footnote area above). Like footnotes, note paragraphs are REAL\r\n // model paragraphs pushed as page blocks so caret/selection work; the number\r\n // marker (the ref run's text) is paint-only, hung in the indent. Notes flow\r\n // onto continuation pages but aren't split across them (matching footnotes).\r\n const ens = doc.endnotes ?? {};\r\n if (Object.keys(ens).length > 0) {\r\n // References in document order \u2192 [noteId, markerText], deduped.\r\n const enRefs: [string, string][] = [];\r\n const seenEn = new Set<string>();\r\n const collectEn = (blocks: Block[]): void => {\r\n for (const b of blocks) {\r\n if (b.kind === \"paragraph\") {\r\n for (const r of b.runs) {\r\n const id = r.style.endnoteRef;\r\n if (id && ens[id] && !seenEn.has(id)) {\r\n seenEn.add(id);\r\n enRefs.push([id, r.text]);\r\n }\r\n }\r\n } else if (b.kind === \"table\") {\r\n for (const row of b.rows) for (const cell of row.cells) collectEn(cell.blocks);\r\n }\r\n }\r\n };\r\n collectEn(doc.blocks);\r\n if (enRefs.length > 0) {\r\n // Endnotes use the document-end (last) section geometry, single column.\r\n applySection(sections[sections.length - 1]!.props);\r\n const enWidth = Math.max(40, contentWidth - FN_INDENT);\r\n const enx = sec.marginPx.left;\r\n let epage = pages[pages.length - 1]!;\r\n const newEndnotePage = (): void => {\r\n epage = mkPage();\r\n delete epage.columnSeparatorsX; // endnotes are a full-width single-column story\r\n pages.push(epage);\r\n pageNotes.push([]);\r\n pageReserved.push(0);\r\n };\r\n // Start on a fresh page if the last body page already has content.\r\n if (epage.blocks.length > 0) newEndnotePage();\r\n else delete epage.columnSeparatorsX; // reused last page \u2192 drop its column rules too\r\n let ey = epage.contentTopPx;\r\n epage.endnoteRuleY = ey + 4;\r\n ey += FN_SEP;\r\n for (const [id, numText] of enRefs) {\r\n let first = true;\r\n for (const p of ens[id]!) {\r\n const lines = getLines(p, enWidth);\r\n // Page-break before a note paragraph that won't fit (notes aren't split).\r\n // Gate on the page already holding content \u2014 never bump the first note\r\n // off a fresh page (whose `ey` is past the top only because of the rule),\r\n // which would strand a blank separator-only page.\r\n if (ey + p.style.spaceBeforePx + totalHeight(lines) > epage.contentBottomPx && epage.blocks.length > 0) {\r\n newEndnotePage();\r\n ey = epage.contentTopPx;\r\n }\r\n ey += p.style.spaceBeforePx;\r\n const placed: PlacedBlock = {\r\n blockId: p.id,\r\n x: enx + FN_INDENT,\r\n y: ey,\r\n firstLineIndex: 0,\r\n lines,\r\n };\r\n if (first && p.runs[0]) {\r\n placed.marker = { text: `${numText}.`, style: p.runs[0].style, x: enx };\r\n first = false;\r\n }\r\n const noteDecor = paraDecorFor(\r\n p.style,\r\n contentWidth - FN_INDENT - p.style.indentLeftPx - (p.style.indentRightPx ?? 0),\r\n totalHeight(lines),\r\n );\r\n if (noteDecor) placed.paraDecor = noteDecor;\r\n epage.blocks.push(placed);\r\n ey += totalHeight(lines) + p.style.spaceAfterPx;\r\n }\r\n }\r\n }\r\n }\r\n\r\n // Z-order: anchored images are lifted out of the flow into a behind-text or\r\n // in-front-of-text layer. Both the canvas renderer and the PDF painter draw\r\n // blocks in array order, so the FINAL paint order IS this array order \u2014\r\n // making this the single source of truth means the two renderers can never\r\n // drift. Block lists with no anchored images are left untouched (byte-identical\r\n // output for every ordinary document \u2014 no PDF drift risk). Recurses into table\r\n // cells (and nested tables) so behind/front layering works inside cells too.\r\n const reorderAnchoredLayers = (blocks: PlacedBlock[]): PlacedBlock[] => {\r\n for (const b of blocks) {\r\n if (b.table) for (const row of b.table.rows) for (const cell of row.cells) cell.blocks = reorderAnchoredLayers(cell.blocks);\r\n }\r\n if (!blocks.some((b) => b.image?.behind || b.image?.front)) return blocks;\r\n // Stable layer partition (behind \u2192 flow/text \u2192 front); within an anchored\r\n // layer, higher z paints later (on top). Flow blocks keep document order.\r\n const layer = (b: PlacedBlock): number => (b.image?.behind ? 0 : b.image?.front ? 2 : 1);\r\n return blocks\r\n .map((b, i) => ({ b, i }))\r\n .sort((p, q) => {\r\n const dl = layer(p.b) - layer(q.b);\r\n if (dl !== 0) return dl;\r\n if (layer(p.b) !== 1) {\r\n const dz = (p.b.image!.z ?? 0) - (q.b.image!.z ?? 0);\r\n if (dz !== 0) return dz;\r\n }\r\n return p.i - q.i; // stable within a layer / equal z\r\n })\r\n .map((x) => x.b);\r\n };\r\n for (const pg of pages) pg.blocks = reorderAnchoredLayers(pg.blocks);\r\n\r\n // Displayed page numbers: continue counting across sections unless a\r\n // section restarts the sequence (Word's \"start at\"). {page} tokens and the\r\n // even/odd band variant pick both read THESE, not the physical index.\r\n const pageNumbers: number[] = [];\r\n {\r\n let n = 0;\r\n for (let i = 0; i < pages.length; i++) {\r\n const s = pageSections[i]!;\r\n const firstOfSection = i === 0 || pageSections[i - 1] !== s;\r\n if (firstOfSection && s.pageNumberStart !== undefined) n = s.pageNumberStart;\r\n else n++;\r\n pageNumbers.push(n);\r\n pages[i]!.number = n;\r\n }\r\n }\r\n\r\n // Inline body PAGE/NUMPAGES fields: their result run carries a {page}/{pages}\r\n // token (the marker that tells a real field from literal text). The body is\r\n // laid out ONCE, so \u2014 unlike per-page header/footer bands \u2014 these tokens were\r\n // never substituted and would paint literally (\"page {page}\"). Resolve them\r\n // here against the final page map, paint-only: the token run is isolated by its\r\n // fieldId so it's its own fragment \u2014 rewrite that fragment's text, re-measure\r\n // its (always shorter) width, map the shorter text back onto the model range via\r\n // offsetMap so caret/hit-testing stay exact, and slide the rest of the line left\r\n // to close the gap the wider token left. Resolution is clone-on-write per line\r\n // (resolveBlockTokens) so it never mutates the shared line/table caches \u2014 the\r\n // cached {page} token survives, so the number re-resolves every pass even when\r\n // the cache is reused (no relayout, no painter change). Untagged literal \"{page}\"\r\n // body text is left alone (fieldId-gated).\r\n const fieldDefs = doc.fields;\r\n if (fieldDefs) {\r\n const isPageNumField = (fid: string | undefined): boolean => {\r\n if (fid === undefined) return false;\r\n const def = fieldDefs[fid];\r\n const t = def && def.kind === \"builtin\" ? def.spec?.type : undefined;\r\n return t === \"PAGE\" || t === \"NUMPAGES\";\r\n };\r\n const resolveLineTokens = (line: LineBox, pageNum: number): void => {\r\n let dx = 0;\r\n for (const frag of line.fragments) {\r\n if (dx !== 0) frag.x += dx; // close the gap left by an earlier token on this line\r\n if (!isPageNumField(frag.style.fieldId)) continue;\r\n const sub = substituteTokens(frag.text, pageNum, pages.length);\r\n if (sub === frag.text) continue;\r\n const modelLen = frag.endOffset - frag.startOffset;\r\n const oldWidth = frag.width;\r\n frag.text = sub;\r\n frag.width = measureTextWidth(sub, charStyleToFont(frag.style));\r\n // Displayed text ({page} -> \"3\") is shorter than the model run: collapse\r\n // every displayed cluster onto the field's model range so a caret lands at\r\n // the field's start/end, never mid-token (reuses the pretext offsetMap path).\r\n frag.offsetMap = Array.from({ length: sub.length + 1 }, (_v, i) => (i === sub.length ? modelLen : 0));\r\n dx += frag.width - oldWidth;\r\n }\r\n };\r\n const lineHasPageField = (line: LineBox): boolean =>\r\n line.fragments.some((f) => isPageNumField(f.style.fieldId));\r\n const resolveBlockTokens = (b: PlacedBlock, pageNum: number): void => {\r\n // resolveLineTokens MUTATES fragment text/width/x/offsetMap. A placed block's\r\n // `lines` ALIAS cached LineBoxes (linesCache for body paragraphs, tableCache's\r\n // measured cells for table content), so resolving in place would bake the\r\n // resolved number INTO the cache. A later layout that reuses that cache\r\n // verbatim \u2014 e.g. a table pushed to a new page by a page break, its\r\n // revision+width unchanged \u2014 then keeps the stale number, because the cached\r\n // fragment text is already \"1\" (not \"{page}\") and substituteTokens no-ops.\r\n // (A column resize changes the width, busting the cache, which is why it\r\n // \"fixed\" the number \u2014 #48.) Clone-on-write: copy any line that carries a page\r\n // field, and its fragments, before resolving \u2014 the cached {page} token stays\r\n // pristine for the next pass. Lines with no page field are a no-op, so skip.\r\n let out: LineBox[] | null = null;\r\n for (let i = 0; i < b.lines.length; i++) {\r\n const line = b.lines[i]!;\r\n if (!lineHasPageField(line)) continue;\r\n const copy: LineBox = { ...line, fragments: line.fragments.map((f) => ({ ...f })) };\r\n resolveLineTokens(copy, pageNum);\r\n (out ??= b.lines.slice())[i] = copy;\r\n }\r\n if (out) b.lines = out;\r\n if (b.table) for (const row of b.table.rows) for (const cell of row.cells) for (const cb of cell.blocks) resolveBlockTokens(cb, pageNum);\r\n };\r\n for (const pg of pages) for (const b of pg.blocks) resolveBlockTokens(b, pageNumbers[pg.index]!);\r\n }\r\n\r\n // TOC page numbers: PAINT-ONLY decorations resolved against the final page\r\n // map \u2014 they can never go stale and never affect line breaking (entries are\r\n // measured with a reserved right gutter). One pass, no fixpoint.\r\n if (tocPlacements.size > 0) {\r\n const firstPageOf = new Map<string, number>(); // blockId -> displayed number\r\n const mapPage = (blocks: PlacedBlock[], num: number): void => {\r\n for (const b of blocks) {\r\n if (!firstPageOf.has(b.blockId)) firstPageOf.set(b.blockId, num);\r\n // Headings (TOC targets) can live inside table cells \u2014 recurse so their\r\n // page number resolves just like body paragraphs.\r\n if (b.table) for (const row of b.table.rows) for (const cell of row.cells) mapPage(cell.blocks, num);\r\n }\r\n };\r\n for (const pg of pages) mapPage(pg.blocks, pageNumbers[pg.index]!);\r\n for (const rec of tocPlacements.values()) {\r\n const target = rec.para.style.tocEntry!.targetId;\r\n const num = firstPageOf.get(target);\r\n if (num === undefined) continue; // dangling entry: heading was deleted\r\n const style = rec.para.runs[0]?.style;\r\n if (!style || rec.chunk.lines.length === 0) continue;\r\n const numText = String(num);\r\n rec.chunk.toc = {\r\n numText,\r\n numX: rec.rightEdge - measureTextWidth(numText, charStyleToFont(style)),\r\n lineIndex: rec.chunk.lines.length - 1,\r\n style,\r\n targetId: target,\r\n };\r\n }\r\n }\r\n\r\n // Margin-band stories: full blocks (paragraphs/images/tables) laid out per\r\n // page so {page}/{pages} tokens resolve. Band cache is per-relayout; the\r\n // substituted clones get per-page ids so prepares never collide. Each page\r\n // uses ITS section's bands and geometry (sections inherit doc.section bands\r\n // unless their patch overrides them); the First variant overrides on a\r\n // section's first page, the Even variant on even page NUMBERS (Word).\r\n const pickBand = (\r\n ps: SectionProps,\r\n kind: \"header\" | \"footer\",\r\n firstOfSection: boolean,\r\n even: boolean,\r\n ): { blocks: Block[]; source: (typeof BAND_KEYS)[number] } | null => {\r\n const first = kind === \"header\" ? ps.headerFirst : ps.footerFirst;\r\n const evenB = kind === \"header\" ? ps.headerEven : ps.footerEven;\r\n if (firstOfSection && first) return { blocks: first, source: kind === \"header\" ? \"headerFirst\" : \"footerFirst\" };\r\n if (even && evenB) return { blocks: evenB, source: kind === \"header\" ? \"headerEven\" : \"footerEven\" };\r\n const base = ps[kind];\r\n return base ? { blocks: base, source: kind } : null;\r\n };\r\n\r\n if (pageSections.some((s) => BAND_KEYS.some((k) => s[k]))) {\r\n const bandCache = new PrepareCache();\r\n for (const pg of pages) {\r\n const ps = pageSections[pg.index]!;\r\n const cw = ps.pageWidthPx - ps.marginPx.left - ps.marginPx.right;\r\n const cx = ps.marginPx.left;\r\n const firstOfSection = pg.index === 0 || pageSections[pg.index - 1] !== ps;\r\n const pageNum = pageNumbers[pg.index]!;\r\n const even = pageNum % 2 === 0;\r\n const header = pickBand(ps, \"header\", firstOfSection, even);\r\n if (header) {\r\n const raw = rawBand === \"header\";\r\n const band = layoutBandCached(header.blocks, cw, cx, pageNum, pages.length, bandCache, raw);\r\n const y0 = headerBandTop(ps, band.height);\r\n pg.header = band.placed.map((b) => shiftPlaced(b, y0));\r\n pg.headerSource = header.source;\r\n }\r\n const footer = pickBand(ps, \"footer\", firstOfSection, even);\r\n if (footer) {\r\n const raw = rawBand === \"footer\";\r\n const band = layoutBandCached(footer.blocks, cw, cx, pageNum, pages.length, bandCache, raw);\r\n const y0 = footerBandTop(ps, band.height);\r\n pg.footer = band.placed.map((b) => shiftPlaced(b, y0));\r\n pg.footerSource = footer.source;\r\n }\r\n }\r\n }\r\n\r\n return {\r\n pages,\r\n pageWidthPx: doc.section.pageWidthPx,\r\n pageHeightPx: doc.section.pageHeightPx,\r\n marginPx: doc.section.marginPx,\r\n };\r\n}\r\n\r\n// ---------------------------------------------------------------------------\r\n// Margin-band layout: simple vertical stacking (no pagination \u2014 a band that\r\n// outgrows its margin overlaps; Word would push content instead, TODO).\r\n\r\nfunction formatPageNumber(n: number, fmt: string | undefined): string {\r\n switch (fmt) {\r\n case \"roman\": return formatListNumber(n, \"lowerRoman\");\r\n case \"Roman\": return formatListNumber(n, \"upperRoman\");\r\n case \"alpha\": return formatListNumber(n, \"lowerLetter\");\r\n case \"Alpha\": return formatListNumber(n, \"upperLetter\");\r\n default: return String(n);\r\n }\r\n}\r\n\r\nfunction substituteTokens(s: string, page: number, pages: number): string {\r\n return s\r\n .replace(/\\{page(?::(roman|Roman|alpha|Alpha))?\\}/g, (_, fmt: string | undefined) => formatPageNumber(page, fmt))\r\n .replace(/\\{pages\\}/g, String(pages))\r\n .replace(/\\{date\\}/g, () => new Date().toLocaleDateString())\r\n .replace(/\\{time\\}/g, () => new Date().toLocaleTimeString([], { hour: \"2-digit\", minute: \"2-digit\" }));\r\n}\r\n\r\n/** All run texts in a band's blocks (paragraphs + cell paragraphs at any table\r\n * nesting depth) \u2014 used to detect volatile {date}/{time} tokens that must bypass\r\n * the band cache. */\r\nfunction blockTexts(blocks: Block[]): string[] {\r\n const out: string[] = [];\r\n const visit = (bs: Block[]): void => {\r\n for (const b of bs) {\r\n if (b.kind === \"paragraph\") for (const r of b.runs) out.push(r.text);\r\n else if (b.kind === \"table\") for (const row of b.rows) for (const cell of row.cells) visit(cell.blocks);\r\n }\r\n };\r\n visit(blocks);\r\n return out;\r\n}\r\n\r\nfunction substituteBlock(b: Block, page: number, pages: number): Block {\r\n const subPara = (p: Paragraph): Paragraph => {\r\n if (!p.runs.some((r) => r.text.includes(\"{\"))) return p;\r\n return {\r\n ...p,\r\n id: `${p.id}@p${page}`, // per-page identity keeps the band prepare-cache honest\r\n runs: p.runs.map((r) => ({ ...r, text: substituteTokens(r.text, page, pages) })),\r\n };\r\n };\r\n if (b.kind === \"paragraph\") return subPara(b);\r\n if (b.kind === \"table\") {\r\n return {\r\n ...b,\r\n rows: b.rows.map((row) => ({\r\n cells: row.cells.map((cell) => ({\r\n ...cell,\r\n blocks: cell.blocks.map((cb) => (cb.kind === \"paragraph\" ? subPara(cb) : cb)),\r\n })),\r\n })),\r\n };\r\n }\r\n return b;\r\n}\r\n\r\nfunction layoutBand(\r\n blocks: Block[],\r\n width: number,\r\n originX: number,\r\n pageNum: number,\r\n pageCount: number,\r\n bandCache: PrepareCache,\r\n rawMode: boolean,\r\n): { placed: PlacedBlock[]; height: number } {\r\n const getBandLines = (p: Paragraph, w: number): LineBox[] => paragraphLines(p, w, bandCache);\r\n const placed: PlacedBlock[] = [];\r\n let y = 0;\r\n for (const original of blocks) {\r\n const b = rawMode ? original : substituteBlock(original, pageNum, pageCount);\r\n if (b.kind === \"paragraph\") {\r\n y += b.style.spaceBeforePx;\r\n const lines = getBandLines(b, width);\r\n const bandPara: PlacedBlock = { blockId: b.id, x: originX + b.style.indentLeftPx, y, firstLineIndex: 0, lines };\r\n const bandDecor = paraDecorFor(b.style, width - b.style.indentLeftPx - (b.style.indentRightPx ?? 0), totalLinesHeight(lines));\r\n if (bandDecor) bandPara.paraDecor = bandDecor;\r\n placed.push(bandPara);\r\n y += totalLinesHeight(lines) + b.style.spaceAfterPx;\r\n } else if (b.kind === \"image\") {\r\n const slack = width - b.widthPx;\r\n const x = originX + (b.align === \"center\" ? slack / 2 : b.align === \"right\" ? slack : 0);\r\n placed.push({\r\n blockId: b.id,\r\n x,\r\n y,\r\n firstLineIndex: 0,\r\n lines: [],\r\n image: { src: b.src, width: b.widthPx, height: b.heightPx, ...(b.crop ? { crop: b.crop } : {}) },\r\n });\r\n y += b.heightPx;\r\n } else if (b.kind === \"equation\") {\r\n const box = eqBox(b);\r\n const align = b.align ?? \"center\";\r\n const slack = width - box.width;\r\n const x = originX + (align === \"center\" ? slack / 2 : align === \"right\" ? slack : 0);\r\n placed.push({ blockId: b.id, x, y, firstLineIndex: 0, lines: [], equation: { box, width: box.width, height: box.ascent + box.descent, baseline: box.ascent } });\r\n y += box.ascent + box.descent;\r\n } else {\r\n const m = measureTable(b, width, getBandLines, EMPTY_LIST_CTX);\r\n placed.push(placeTable(b, m.rows, m.colWidths, originX + m.xOffset, y, m.tableWidth, 0, EMPTY_LIST_CTX));\r\n y += m.height;\r\n }\r\n }\r\n return { placed, height: y };\r\n}\r\n\r\nfunction shiftPlaced(p: PlacedBlock, dy: number): PlacedBlock {\r\n const out: PlacedBlock = { ...p, y: p.y + dy };\r\n if (p.table) {\r\n out.table = {\r\n ...p.table,\r\n y: p.table.y + dy,\r\n rows: p.table.rows.map((row) => ({\r\n ...row,\r\n y: row.y + dy,\r\n cells: row.cells.map((cell) => ({\r\n ...cell,\r\n y: cell.y + dy,\r\n blocks: cell.blocks.map((cb) => shiftPlaced(cb, dy)),\r\n })),\r\n })),\r\n };\r\n }\r\n return out;\r\n}\r\n\r\n// ---------------------------------------------------------------------------\r\n// Tables: equal column widths, padded cells of stacked paragraphs, atomic on\r\n// the page. TODO: row-level page breaking for long tables.\r\n\r\nconst ATOMIC_GAP = 12; // vertical breathing room around images/tables\r\n\r\n// Cell inner padding. Word's default cell margins (TableNormal) are 0 top/bottom\r\n// and 108 twips (~7.2px) left/right \u2014 vertical is NOT symmetric with horizontal,\r\n// so a single-line row is only as tall as its line, not line + fixed pad. The\r\n// importer resolves the w:tcMar/w:tblCellMar cascade onto cell.margin; cells\r\n// without one (native/programmatic tables) fall back to these Word defaults.\r\nconst DEFAULT_CELL_MARGIN = { top: 0, right: 7.2, bottom: 0, left: 7.2 } as const;\r\nconst cellMargin = (c: TableCell): { top: number; right: number; bottom: number; left: number } =>\r\n c.margin ?? DEFAULT_CELL_MARGIN;\r\n\r\n// ---------------------------------------------------------------------------\r\n// Autofit (content-driven) column sizing \u2014 only exercised when a table's\r\n// widthMode is \"autofitContents\"/\"autofitWindow\". The fixed path (the default)\r\n// never touches any of this.\r\n\r\n/** A column's content-width demand: `min` = it cannot be painted narrower than\r\n * this without clipping its widest unbreakable token; `max` = its natural width\r\n * if nothing wraps. */\r\ninterface ColMinMax {\r\n min: number;\r\n max: number;\r\n}\r\n\r\n/** Width pretext lays the paragraph out at when we want it effectively\r\n * unwrapped (one line per hard break) \u2014 its natural max content width. */\r\nconst AUTOFIT_NATURAL_W = 1_000_000;\r\n/** Floor a solved column at this px so an empty/degenerate column never collapses. */\r\nconst AUTOFIT_MIN_COL = 16;\r\n\r\n/** Content width of a laid-out line = \u03A3 fragment widths. Alignment-independent\r\n * (we sum widths rather than read fragment x), so a centered/right cell measures\r\n * the same as a left one. Tab gaps (gapBefore) are not captured \u2014 a known minor\r\n * gap for tab-heavy autofit cells. */\r\nfunction lineContentWidth(l: LineBox): number {\r\n let w = 0;\r\n for (const f of l.fragments) w += f.width;\r\n return w;\r\n}\r\n\r\n/** Widest laid-out line when the paragraph is broken at `width` (reusing the\r\n * cached prepared segments \u2014 only the cheap re-break runs). At a huge width this\r\n * yields the natural max; at width 1 it yields the widest unbreakable token. */\r\nfunction paragraphExtent(p: Paragraph, getLines: (p: Paragraph, w: number) => LineBox[], width: number): number {\r\n let m = 0;\r\n for (const l of getLines(p, width)) m = Math.max(m, lineContentWidth(l));\r\n return m;\r\n}\r\n\r\n/** Content min/max of one cell BLOCK, in column-width terms (paragraph indents\r\n * count toward the required column width; images are treated as unbreakable;\r\n * nested tables contribute their own solved-grid min/max). */\r\nfunction blockMinMax(\r\n b: Block,\r\n listCtx: CellListCtx,\r\n getLines: (p: Paragraph, w: number) => LineBox[],\r\n available: number,\r\n): ColMinMax {\r\n if (b.kind === \"paragraph\") {\r\n const indent = b.style.indentLeftPx + listCtx.indentOf(b) + (b.style.indentRightPx ?? 0);\r\n return {\r\n min: paragraphExtent(b, getLines, 1) + indent,\r\n max: paragraphExtent(b, getLines, AUTOFIT_NATURAL_W) + indent,\r\n };\r\n }\r\n if (b.kind === \"image\") {\r\n // Anchored images are out of flow; in-flow images are unbreakable blocks\r\n // (the renderer scales them DOWN if a column ends up narrower, so this never\r\n // forces an overflow \u2014 it only expresses the natural-size preference).\r\n if (b.anchor) return { min: 0, max: 0 };\r\n return { min: b.widthPx, max: b.widthPx };\r\n }\r\n if (b.kind === \"equation\") {\r\n const w = eqBox(b).width;\r\n return { min: w, max: w };\r\n }\r\n const cols = autofitColMinMax(b, listCtx, getLines, available);\r\n return {\r\n min: cols.reduce((s, c) => s + c.min, 0),\r\n max: cols.reduce((s, c) => s + c.max, 0),\r\n };\r\n}\r\n\r\n/** Content min/max of a whole cell: the widest block sets each (cell blocks stack\r\n * vertically), plus L/R padding, clamped up to any preferred width (w:tcW). */\r\nfunction cellMinMax(\r\n cell: TableCell,\r\n listCtx: CellListCtx,\r\n getLines: (p: Paragraph, w: number) => LineBox[],\r\n available: number,\r\n): ColMinMax {\r\n const mgn = cellMargin(cell);\r\n const pad = mgn.left + mgn.right;\r\n const rot = cellRotation(cell.textDirection);\r\n if (rot) {\r\n // Vertical-text cell: its column demand is the stack of line heights (the page\r\n // WIDTH after rotation), independent of the column width \u2014 so min === max (the\r\n // text doesn't wrap into the column). The text LENGTH lands on the row height.\r\n let cross = 0;\r\n for (const b of cell.blocks) {\r\n if (b.kind === \"paragraph\") {\r\n cross += b.style.spaceBeforePx + totalLinesHeight(getLines(b, AUTOFIT_NATURAL_W)) + b.style.spaceAfterPx;\r\n } else if (b.kind === \"image\") {\r\n if (!b.anchor) cross += b.heightPx + CELL_BLOCK_GAP;\r\n } else if (b.kind === \"equation\") {\r\n const box = eqBox(b);\r\n cross += box.ascent + box.descent + CELL_BLOCK_GAP;\r\n } else {\r\n cross += measureTable(b, available, getLines, listCtx).height + CELL_BLOCK_GAP;\r\n }\r\n }\r\n let w = cross + pad;\r\n const prefR = cell.preferredWidth;\r\n if (prefR) {\r\n const prefPx = prefR.type === \"pct\" ? prefR.px * available : prefR.px;\r\n if (prefPx > w) w = prefPx;\r\n }\r\n return { min: w, max: w };\r\n }\r\n let min = 0;\r\n let max = 0;\r\n for (const b of cell.blocks) {\r\n const mm = blockMinMax(b, listCtx, getLines, available);\r\n if (mm.min > min) min = mm.min;\r\n if (mm.max > max) max = mm.max;\r\n }\r\n min += pad;\r\n max += pad;\r\n const pref = cell.preferredWidth;\r\n if (pref) {\r\n // abs: px is literal. pct: px holds the fraction (0..1) of the table width,\r\n // resolved against the available width (close enough; the exact table width\r\n // is circular with the solve).\r\n const prefPx = pref.type === \"pct\" ? pref.px * available : pref.px;\r\n if (prefPx > min) min = prefPx;\r\n if (prefPx > max) max = prefPx;\r\n }\r\n return { min, max };\r\n}\r\n\r\n/** Push `demand` into a group of columns, growing each proportionally to its\r\n * current width (so wider columns absorb more), but never shrinking. */\r\nfunction distributeDemand(arr: number[], cols: number[], demand: number): void {\r\n let cur = 0;\r\n for (const c of cols) cur += arr[c]!;\r\n if (demand <= cur) return;\r\n const extra = demand - cur;\r\n let wsum = 0;\r\n for (const c of cols) wsum += arr[c]! + 1;\r\n for (const c of cols) arr[c]! += extra * ((arr[c]! + 1) / wsum);\r\n}\r\n\r\n/** Per-column {min,max} for a table, walking the span-aware grid exactly like\r\n * the height pass: span-1 cells set their column directly; spanning cells are\r\n * deferred and their demand distributed across the columns they cover. */\r\nfunction autofitColMinMax(\r\n t: TableBlock,\r\n listCtx: CellListCtx,\r\n getLines: (p: Paragraph, w: number) => LineBox[],\r\n available: number,\r\n): ColMinMax[] {\r\n const ncols = effectiveFractions(t).length;\r\n const colMin = new Array<number>(ncols).fill(0);\r\n const colMax = new Array<number>(ncols).fill(0);\r\n const spans: { colStart: number; cols: number[]; mm: ColMinMax }[] = [];\r\n const rowsRemaining = new Array<number>(ncols).fill(0);\r\n for (const row of t.rows) {\r\n let col = 0;\r\n for (const cell of row.cells) {\r\n while (col < ncols && rowsRemaining[col]! > 0) col++;\r\n const span = Math.max(1, cell.colSpan ?? 1);\r\n const rowSpan = Math.max(1, cell.rowSpan ?? 1);\r\n const colStart = col;\r\n const mm = cellMinMax(cell, listCtx, getLines, available);\r\n if (span === 1) {\r\n if (colStart < ncols) {\r\n if (mm.min > colMin[colStart]!) colMin[colStart] = mm.min;\r\n if (mm.max > colMax[colStart]!) colMax[colStart] = mm.max;\r\n }\r\n } else {\r\n const cols: number[] = [];\r\n for (let k = 0; k < span && colStart + k < ncols; k++) cols.push(colStart + k);\r\n if (cols.length > 0) spans.push({ colStart, cols, mm });\r\n }\r\n if (rowSpan > 1) for (let k = 0; k < span && colStart + k < ncols; k++) rowsRemaining[colStart + k] = rowSpan;\r\n col = colStart + span;\r\n }\r\n for (let c = 0; c < ncols; c++) if (rowsRemaining[c]! > 0) rowsRemaining[c]!--;\r\n }\r\n // Narrower spans first, so a 2-col span settles before a 3-col span layered on it.\r\n spans.sort((a, b) => a.cols.length - b.cols.length);\r\n for (const s of spans) {\r\n distributeDemand(colMin, s.cols, s.mm.min);\r\n distributeDemand(colMax, s.cols, s.mm.max);\r\n }\r\n const out: ColMinMax[] = [];\r\n for (let c = 0; c < ncols; c++) {\r\n const min = Math.max(AUTOFIT_MIN_COL, colMin[c]!);\r\n out.push({ min, max: Math.max(min, colMax[c]!) });\r\n }\r\n return out;\r\n}\r\n\r\n/** Solve final column widths from per-column min/max and the available width.\r\n * CSS automatic-table-layout rules; \"autofitWindow\" always fills `available`,\r\n * \"autofitContents\" lets the table end up narrower. */\r\nfunction solveColumns(perCol: ColMinMax[], available: number, mode: \"autofitContents\" | \"autofitWindow\"): number[] {\r\n const ncols = perCol.length;\r\n if (ncols === 0) return [];\r\n const min = perCol.map((c) => c.min);\r\n const max = perCol.map((c) => c.max);\r\n const sumMin = min.reduce((s, v) => s + v, 0);\r\n const sumMax = max.reduce((s, v) => s + v, 0);\r\n if (sumMax <= available) {\r\n if (mode === \"autofitWindow\") {\r\n const slack = available - sumMax;\r\n const wsum = sumMax > 0 ? sumMax : ncols;\r\n return max.map((m) => m + slack * ((sumMax > 0 ? m : 1) / wsum));\r\n }\r\n return max.slice();\r\n }\r\n if (sumMin < available) {\r\n const slack = available - sumMin;\r\n const span = sumMax - sumMin;\r\n return min.map((mn, i) => mn + (span > 0 ? slack * ((max[i]! - mn) / span) : slack / ncols));\r\n }\r\n return min.slice(); // overflow: pin to min, content clips/wraps as today\r\n}\r\n\r\ntype MeasuredCellItem =\r\n | { kind: \"para\"; block: Paragraph; lines: LineBox[] }\r\n | { kind: \"image\"; block: ImageBlock; width: number; height: number } // scaled to fit the cell\r\n | { kind: \"equation\"; block: EquationBlock; box: MathBox; width: number; height: number }\r\n | { kind: \"table\"; block: TableBlock; rows: MeasuredRow[]; colWidths: number[]; height: number; tableWidth: number; xOffset: number };\r\n\r\ninterface MeasuredCell {\r\n cell: TableCell;\r\n items: MeasuredCellItem[];\r\n height: number;\r\n /** Rendered width \u2014 colSpan cells cover several columns. */\r\n width: number;\r\n /** First grid column this cell occupies (accounts for rowspan holes above). */\r\n colStart: number;\r\n /** Vertical merge: rows this cell covers (1 = normal). */\r\n rowSpan: number;\r\n /** Vertical text (w:textDirection): the cell's content was laid out UNWRAPPED in\r\n * a swapped frame and is painted rotated 90\u00B0. Absent = horizontal. */\r\n rot?: CellRot;\r\n}\r\ninterface MeasuredRow {\r\n cells: MeasuredCell[];\r\n height: number;\r\n}\r\n\r\nconst CELL_BLOCK_GAP = 4; // vertical gap around non-paragraph blocks in cells\r\n\r\n/** Vertical-text rotation a cell's w:textDirection requests, or null for the\r\n * default horizontal flow. `tbRl` (top\u2192bottom, columns right\u2192left) and the\r\n * East-Asian upright variants `tbRlV`/`tbLrV` rotate the text 90\u00B0 CLOCKWISE;\r\n * `btLr` (bottom\u2192top, columns left\u2192right) rotates 90\u00B0 COUNTER-CLOCKWISE. The\r\n * upright `*V` variants degrade to the same 90\u00B0 rotation (no per-glyph\r\n * uprighting); `lrTb`/`lrTbV` stay horizontal. */\r\ntype CellRot = \"cw\" | \"ccw\";\r\nfunction cellRotation(dir: TableCell[\"textDirection\"]): CellRot | null {\r\n switch (dir) {\r\n case \"tbRl\":\r\n case \"tbRlV\":\r\n case \"tbLrV\":\r\n return \"cw\";\r\n case \"btLr\":\r\n return \"ccw\";\r\n default:\r\n return null;\r\n }\r\n}\r\n/** Canvas/pdf rotation angle (radians) for a rotated cell: +\u03C0/2 = 90\u00B0 CW, \u2212\u03C0/2 = CCW. */\r\nconst cellRotAngle = (rot: CellRot): number => (rot === \"cw\" ? Math.PI / 2 : -Math.PI / 2);\r\n\r\n/** List geometry threaded into the table layout so cell paragraphs can carry a\r\n * list marker, just like body paragraphs. `indentOf` is the list-level indent\r\n * (added on top of the cell paragraph's own indent); `markers` is the shared\r\n * per-paragraph marker map filled by the numbering pass. */\r\ninterface CellListCtx {\r\n indentOf: (p: Paragraph) => number;\r\n markers: Map<string, { text: string; style: CharStyle; hangingPx: number }>;\r\n}\r\n\r\n/** Lists are body-only, so band (header/footer) tables carry no list geometry. */\r\nconst EMPTY_LIST_CTX: CellListCtx = { indentOf: () => 0, markers: new Map() };\r\n\r\nfunction measureTable(\r\n t: TableBlock,\r\n contentWidth: number,\r\n getLines: (p: Paragraph, width: number) => LineBox[],\r\n listCtx: CellListCtx,\r\n): { rows: MeasuredRow[]; colWidths: number[]; height: number; tableWidth: number; xOffset: number } {\r\n const mode = t.widthMode ?? \"fixed\";\r\n let colWidths: number[];\r\n if (mode === \"fixed\") {\r\n const fracs = effectiveFractions(t);\r\n // A preferred width shrinks the whole grid (columns keep their proportions);\r\n // absent, the table spans the full content width as it historically did.\r\n const target = resolveTableWidth(t.preferredWidth, contentWidth, fracs.length);\r\n colWidths = fracs.map((f) => f * target);\r\n } else {\r\n // Content-driven: measure each cell's min/max, solve the grid, THEN run the\r\n // existing height pass below at the solved widths (two passes over the cells;\r\n // the expensive prepared segments are cached so only re-breaks repeat).\r\n const perCol = autofitColMinMax(t, listCtx, getLines, contentWidth);\r\n colWidths = solveColumns(perCol, contentWidth, mode);\r\n }\r\n const ncols = colWidths.length;\r\n\r\n // Grid walk: rowsRemaining[c] > 0 means column c is still covered by a rowspan\r\n // started in an earlier row, so this row has a \"hole\" there and its cells shift\r\n // right past it (HTML-table column assignment). With no rowSpan anywhere this\r\n // reduces exactly to the old left-to-right placement.\r\n const rowsRemaining = new Array<number>(ncols).fill(0);\r\n const rows: MeasuredRow[] = t.rows.map((row) => {\r\n let col = 0;\r\n const cells: MeasuredCell[] = row.cells.map((cell) => {\r\n while (col < ncols && rowsRemaining[col]! > 0) col++;\r\n const span = Math.max(1, cell.colSpan ?? 1);\r\n const rowSpan = Math.max(1, cell.rowSpan ?? 1);\r\n const colStart = col;\r\n let width = 0;\r\n for (let k = 0; k < span; k++) width += colWidths[col + k] ?? colWidths[ncols - 1] ?? 40;\r\n if (rowSpan > 1) for (let k = 0; k < span && col + k < ncols; k++) rowsRemaining[col + k] = rowSpan;\r\n col += span;\r\n const mgn = cellMargin(cell);\r\n const innerWidth = Math.max(8, width - mgn.left - mgn.right);\r\n const rot = cellRotation(cell.textDirection);\r\n if (rot) {\r\n // Vertical-text cell: lay every paragraph out UNWRAPPED (vertical headers\r\n // don't wrap \u2014 the text length sets the row height). After the 90\u00B0 rotation\r\n // the laid-out text LENGTH (longest line) becomes the cell's content HEIGHT,\r\n // so `flow` drives the row; the stack of line heights becomes the cell's\r\n // content WIDTH (the column demand \u2014 see cellMinMax).\r\n let flow = 0;\r\n const rotItems: MeasuredCellItem[] = cell.blocks.map((b) => {\r\n if (b.kind === \"paragraph\") {\r\n const lines = getLines(b, AUTOFIT_NATURAL_W);\r\n let w = 0;\r\n for (const l of lines) w = Math.max(w, lineContentWidth(l));\r\n flow = Math.max(flow, w + b.style.indentLeftPx + listCtx.indentOf(b) + (b.style.indentRightPx ?? 0));\r\n return { kind: \"para\", block: b, lines };\r\n }\r\n if (b.kind === \"image\") {\r\n if (b.anchor) return { kind: \"image\", block: b, width: b.widthPx, height: b.heightPx };\r\n flow = Math.max(flow, b.widthPx + CELL_BLOCK_GAP);\r\n return { kind: \"image\", block: b, width: b.widthPx, height: b.heightPx };\r\n }\r\n if (b.kind === \"equation\") {\r\n const box = eqBox(b);\r\n flow = Math.max(flow, box.width + CELL_BLOCK_GAP);\r\n return { kind: \"equation\", block: b, box, width: box.width, height: box.ascent + box.descent };\r\n }\r\n const m = measureTable(b, innerWidth, getLines, listCtx);\r\n flow = Math.max(flow, m.tableWidth + CELL_BLOCK_GAP);\r\n return { kind: \"table\", block: b, ...m };\r\n });\r\n return { cell, items: rotItems, height: flow + mgn.top + mgn.bottom, width, colStart, rowSpan, rot };\r\n }\r\n let h = 0;\r\n const items: MeasuredCellItem[] = cell.blocks.map((b) => {\r\n if (b.kind === \"paragraph\") {\r\n // Wrap at the cell's inner width minus the paragraph's own left/right\r\n // indent and the list-level indent \u2014 mirroring the body wrap width\r\n // (box.width - indentOf - rightIndentOf). Placement shifts the text\r\n // right by indentLeftPx + the list indent, so omitting them here would\r\n // measure at a wider box than is painted and the text would overflow\r\n // (now clipped) by exactly that indent.\r\n const avail = innerWidth - b.style.indentLeftPx - listCtx.indentOf(b) - (b.style.indentRightPx ?? 0);\r\n const lines = getLines(b, Math.max(8, avail));\r\n h += b.style.spaceBeforePx + totalLinesHeight(lines) + b.style.spaceAfterPx;\r\n return { kind: \"para\", block: b, lines };\r\n }\r\n if (b.kind === \"image\") {\r\n // Anchored (behind/in-front) images are lifted out of the flow: they do\r\n // NOT advance the cursor or consume cell height \u2014 exactly like a\r\n // body-level anchored image. Carry the native size; placement positions\r\n // them by their anchor offsets.\r\n if (b.anchor) return { kind: \"image\", block: b, width: b.widthPx, height: b.heightPx };\r\n // Photo-grid cells: scale wide images down to the cell's inner width.\r\n const scale = Math.min(1, innerWidth / Math.max(1, b.widthPx));\r\n const w = b.widthPx * scale;\r\n const ih = b.heightPx * scale;\r\n h += ih + CELL_BLOCK_GAP;\r\n return { kind: \"image\", block: b, width: w, height: ih };\r\n }\r\n if (b.kind === \"equation\") {\r\n const box = eqBox(b);\r\n const hh = box.ascent + box.descent;\r\n h += hh + CELL_BLOCK_GAP;\r\n return { kind: \"equation\", block: b, box, width: box.width, height: hh };\r\n }\r\n const m = measureTable(b, innerWidth, getLines, listCtx); // nested table\r\n h += m.height + CELL_BLOCK_GAP;\r\n return { kind: \"table\", block: b, ...m };\r\n });\r\n return { cell, items, height: h + mgn.top + mgn.bottom, width, colStart, rowSpan };\r\n });\r\n for (let c = 0; c < ncols; c++) if (rowsRemaining[c]! > 0) rowsRemaining[c]!--;\r\n return { cells, height: 0 };\r\n });\r\n\r\n // Row heights: single-row cells fix their row; a rowspan cell only forces extra\r\n // height (added to its last row) when its content exceeds the rows it covers.\r\n const rowHeight = rows.map((r) => Math.max(0, ...r.cells.filter((c) => c.rowSpan === 1).map((c) => c.height)));\r\n // Fixed/min row height (w:trHeight): \"atLeast\" grows the row to the height floor;\r\n // \"exact\" pins it (content taller than the box is clipped at paint). Applied\r\n // before the rowspan-overflow pass so a forced-tall row counts toward a span.\r\n t.rows.forEach((row, ri) => {\r\n const h = row.props?.height;\r\n if (!h) return;\r\n rowHeight[ri] = h.rule === \"exact\" ? h.value : Math.max(rowHeight[ri]!, h.value);\r\n });\r\n rows.forEach((r, ri) => {\r\n for (const mc of r.cells) {\r\n if (mc.rowSpan <= 1) continue;\r\n const endR = Math.min(rows.length - 1, ri + mc.rowSpan - 1);\r\n let span = 0;\r\n for (let rr = ri; rr <= endR; rr++) span += rowHeight[rr]!;\r\n if (mc.height > span) rowHeight[endR]! += mc.height - span;\r\n }\r\n });\r\n rows.forEach((r, ri) => (r.height = rowHeight[ri]!));\r\n\r\n // Fixed tables render at exactly the box width (fractions sum to 1); autofit\r\n // tables render at the solved column total, which may be narrower (contents) or\r\n // exactly the box (window).\r\n const tableWidth =\r\n mode === \"fixed\" && !t.preferredWidth ? contentWidth : colWidths.reduce((s, w) => s + w, 0);\r\n // Alignment only has room to act when the table is narrower than its band \u2014 true\r\n // for a preferred width OR AutoFit-to-Contents; a full-width table never shifts.\r\n // A table indent (w:tblInd) shifts the whole table right on TOP of that, like a\r\n // paragraph's left indent (issue #61).\r\n const xOffset = tableAlignOffset(t.align, contentWidth, tableWidth) + (t.indentPx ?? 0);\r\n return { rows, colWidths, height: rowHeight.reduce((s, h) => s + h, 0), tableWidth, xOffset };\r\n}\r\n\r\n/** Resolve a table's preferred total width to px, clamped to a sane floor and the\r\n * available content width. Absent preference \u2192 the full content width. */\r\nfunction resolveTableWidth(\r\n pref: TableBlock[\"preferredWidth\"],\r\n contentWidth: number,\r\n ncols: number,\r\n): number {\r\n if (!pref) return contentWidth;\r\n const raw = pref.type === \"pct\" ? (pref.value / 100) * contentWidth : pref.value;\r\n const floor = Math.min(contentWidth, Math.max(1, ncols) * 24); // never below ~24px/col\r\n return Math.max(floor, Math.min(contentWidth, raw));\r\n}\r\n\r\n/** Horizontal shift of a table within its band for the given alignment. */\r\nfunction tableAlignOffset(\r\n align: TableBlock[\"align\"],\r\n contentWidth: number,\r\n tableWidth: number,\r\n): number {\r\n const slack = contentWidth - tableWidth;\r\n if (slack <= 0) return 0;\r\n return align === \"center\" ? slack / 2 : align === \"right\" ? slack : 0;\r\n}\r\n\r\nfunction totalLinesHeight(lines: LineBox[]): number {\r\n let h = 0;\r\n for (const l of lines) h += l.height;\r\n return h;\r\n}\r\n\r\nfunction placeTable(\r\n t: TableBlock,\r\n rows: MeasuredRow[],\r\n colWidths: number[],\r\n x: number,\r\n y: number,\r\n width: number,\r\n firstRowIndex: number,\r\n listCtx: CellListCtx,\r\n): PlacedBlock {\r\n // Cumulative grid-column x offsets, so a cell lands at its colStart regardless\r\n // of rowspan holes in this row; and cumulative row y within the chunk, so a\r\n // rowspan cell's height = the sum of the rows it covers (clamped to the chunk\r\n // if a vertical merge straddles a page break).\r\n const colX = [0];\r\n for (const w of colWidths) colX.push(colX[colX.length - 1]! + w);\r\n const rowY = [y];\r\n for (const row of rows) rowY.push(rowY[rowY.length - 1]! + row.height);\r\n // RTL visual column order (w:bidiVisual, issue #61): mirror each cell's left edge\r\n // about the grid so grid column 0 paints at the right. The logical cell order and\r\n // content are unchanged \u2014 only the x placement flips.\r\n const gridWidth = colX[colX.length - 1] ?? 0;\r\n\r\n const placedRows = [];\r\n for (let lr = 0; lr < rows.length; lr++) {\r\n const row = rows[lr]!;\r\n const ry = rowY[lr]!;\r\n const cells = [];\r\n for (const mc of row.cells) {\r\n const cxStart = colX[mc.colStart] ?? colX[colX.length - 1]!;\r\n const cx = x + (t.bidiVisual ? gridWidth - cxStart - mc.width : cxStart);\r\n const endLr = Math.min(rows.length - 1, lr + mc.rowSpan - 1);\r\n const cellHeight = rowY[endLr + 1]! - ry;\r\n const blocks: PlacedBlock[] = [];\r\n const mgn = cellMargin(mc.cell);\r\n const innerWidth = mc.width - mgn.left - mgn.right;\r\n if (mc.rot) {\r\n // Vertical-text cell: place the blocks in a LOCAL (pre-rotation) frame whose\r\n // local x-axis is the text-advance direction and local y-axis is the stacked\r\n // lines. paint/geometry map local\u2192page via translate(origin)+rotate(angle):\r\n // tbRl (CW) anchors the TOP-RIGHT inner corner, stacking lines leftward;\r\n // btLr (CCW) anchors the BOTTOM-LEFT corner, stacking lines rightward.\r\n const innerH = cellHeight - mgn.top - mgn.bottom;\r\n const angle = cellRotAngle(mc.rot);\r\n const originX = mc.rot === \"cw\" ? cx + mgn.left + innerWidth : cx + mgn.left;\r\n const originY = mc.rot === \"cw\" ? ry + mgn.top : ry + mgn.top + innerH;\r\n let ly = 0; // local stack axis (\u2192 page width after rotation)\r\n for (const it of mc.items) {\r\n if (it.kind === \"para\") {\r\n ly += it.block.style.spaceBeforePx;\r\n const lx = it.block.style.indentLeftPx + listCtx.indentOf(it.block);\r\n const placedPara: PlacedBlock = { blockId: it.block.id, x: lx, y: ly, firstLineIndex: 0, lines: it.lines };\r\n // Carry list markers and paragraph shading/border the same as the\r\n // horizontal path \u2014 they're painted under the cell's rotation transform,\r\n // so their local-frame coords map onto the page correctly.\r\n const marker = listCtx.markers.get(it.block.id);\r\n if (marker) placedPara.marker = { text: marker.text, style: marker.style, x: Math.max(0, lx - marker.hangingPx) };\r\n const cellDecor = paraDecorFor(\r\n it.block.style,\r\n innerH - it.block.style.indentLeftPx - listCtx.indentOf(it.block) - (it.block.style.indentRightPx ?? 0),\r\n totalLinesHeight(it.lines),\r\n );\r\n if (cellDecor) placedPara.paraDecor = cellDecor;\r\n blocks.push(placedPara);\r\n ly += totalLinesHeight(it.lines) + it.block.style.spaceAfterPx;\r\n } else if (it.kind === \"image\") {\r\n const anchor = it.block.anchor;\r\n if (anchor) {\r\n // Anchored (behind/in-front) image: positioned from the cell's content\r\n // origin by its offsets, carrying behind/front/z \u2014 it does NOT advance\r\n // the stack cursor, mirroring the horizontal cell path.\r\n const placedImage: PlacedImage = { src: it.block.src, width: it.block.widthPx, height: it.block.heightPx, z: anchor.z ?? 0 };\r\n if (anchor.behind) placedImage.behind = true;\r\n else placedImage.front = true;\r\n blocks.push({ blockId: it.block.id, x: anchor.offsetXPx, y: anchor.offsetYPx, firstLineIndex: 0, lines: [], image: placedImage });\r\n continue;\r\n }\r\n blocks.push({ blockId: it.block.id, x: 0, y: ly, firstLineIndex: 0, lines: [], image: { src: it.block.src, width: it.width, height: it.height } });\r\n ly += it.height + CELL_BLOCK_GAP;\r\n } else if (it.kind === \"equation\") {\r\n blocks.push({ blockId: it.block.id, x: 0, y: ly, firstLineIndex: 0, lines: [], equation: { box: it.box, width: it.width, height: it.height, baseline: it.box.ascent } });\r\n ly += it.height + CELL_BLOCK_GAP;\r\n } else {\r\n blocks.push(placeTable(it.block, it.rows, it.colWidths, it.xOffset, ly, it.tableWidth, 0, listCtx));\r\n ly += it.height + CELL_BLOCK_GAP;\r\n }\r\n }\r\n cells.push({\r\n x: cx,\r\n y: ry,\r\n width: mc.width,\r\n height: cellHeight,\r\n originRow: firstRowIndex + lr,\r\n originCol: mc.colStart,\r\n blocks,\r\n ...(mc.cell.shading !== undefined ? { shading: mc.cell.shading } : {}),\r\n ...(mc.cell.borders !== undefined ? { borders: mc.cell.borders } : {}),\r\n contentClip: { x: cx + mgn.left, y: ry, width: innerWidth, height: cellHeight },\r\n rotation: { angle, originX, originY },\r\n });\r\n continue;\r\n }\r\n // Vertical alignment: by default content hugs the top. For center/bottom,\r\n // offset the whole block stack by the slack between the content height\r\n // (mc.height already folds in the cell margins) and the cell's painted box,\r\n // which is taller when the row is forced up by a sibling or a rowSpan.\r\n const vAlign = mc.cell.vAlign;\r\n const vSlack = vAlign === \"center\" || vAlign === \"bottom\" ? Math.max(0, cellHeight - mc.height) : 0;\r\n const vOffset = vAlign === \"center\" ? vSlack / 2 : vAlign === \"bottom\" ? vSlack : 0;\r\n let py = ry + mgn.top + vOffset;\r\n for (const it of mc.items) {\r\n if (it.kind === \"para\") {\r\n py += it.block.style.spaceBeforePx;\r\n // List paragraphs shift right by the list indent; the marker hangs in\r\n // that indent, clamped so it stays inside the cell's left padding.\r\n const lx = cx + mgn.left + it.block.style.indentLeftPx + listCtx.indentOf(it.block);\r\n const placedPara: PlacedBlock = {\r\n blockId: it.block.id,\r\n x: lx,\r\n y: py,\r\n firstLineIndex: 0,\r\n lines: it.lines, // line.y is already block-relative; coords stay consistent\r\n };\r\n const marker = listCtx.markers.get(it.block.id);\r\n if (marker) {\r\n placedPara.marker = { text: marker.text, style: marker.style, x: Math.max(cx + 1, lx - marker.hangingPx) };\r\n }\r\n // Paragraph border/shading box, sized to the cell's content width minus\r\n // this paragraph's indents (same as body flow, scoped to the cell).\r\n const cellDecor = paraDecorFor(\r\n it.block.style,\r\n innerWidth - it.block.style.indentLeftPx - listCtx.indentOf(it.block) - (it.block.style.indentRightPx ?? 0),\r\n totalLinesHeight(it.lines),\r\n );\r\n if (cellDecor) placedPara.paraDecor = cellDecor;\r\n blocks.push(placedPara);\r\n py += totalLinesHeight(it.lines) + it.block.style.spaceAfterPx;\r\n } else if (it.kind === \"image\") {\r\n const anchor = it.block.anchor;\r\n if (anchor) {\r\n // Anchored (behind/in-front) cell image: positioned absolutely from the\r\n // cell's content origin by its offsets, carrying behind/front/z so the\r\n // z-order pass can lift it into the right layer. Does NOT advance py \u2014\r\n // text flows over/under it, mirroring placeAnchoredImage at body level.\r\n const placedImage: PlacedImage = {\r\n src: it.block.src,\r\n width: it.block.widthPx,\r\n height: it.block.heightPx,\r\n z: anchor.z ?? 0,\r\n };\r\n if (anchor.behind) placedImage.behind = true;\r\n else placedImage.front = true;\r\n blocks.push({\r\n blockId: it.block.id,\r\n x: cx + mgn.left + anchor.offsetXPx,\r\n y: ry + mgn.top + anchor.offsetYPx,\r\n firstLineIndex: 0,\r\n lines: [],\r\n image: placedImage,\r\n });\r\n continue;\r\n }\r\n const innerH = cellHeight - mgn.top - mgn.bottom;\r\n // A lone photo in a cell taller than it fits (e.g. a rowSpan comp-photo\r\n // column) is filled object-fit:cover \u2014 scaled to cover the cell box,\r\n // centered, and clipped \u2014 instead of sitting at the top over blank space.\r\n if (mc.items.length === 1 && innerH > it.height + 8) {\r\n const scale = Math.max(innerWidth / it.block.widthPx, innerH / it.block.heightPx);\r\n const w = it.block.widthPx * scale;\r\n const h = it.block.heightPx * scale;\r\n const ix0 = cx + mgn.left;\r\n const iy0 = ry + mgn.top;\r\n blocks.push({\r\n blockId: it.block.id,\r\n x: ix0 + (innerWidth - w) / 2,\r\n y: iy0 + (innerH - h) / 2,\r\n firstLineIndex: 0,\r\n lines: [],\r\n image: { src: it.block.src, width: w, height: h, clip: { x: ix0, y: iy0, width: innerWidth, height: innerH } },\r\n });\r\n py += it.height + CELL_BLOCK_GAP;\r\n } else {\r\n const slack = innerWidth - it.width;\r\n const ix =\r\n cx + mgn.left +\r\n (it.block.align === \"center\" ? slack / 2 : it.block.align === \"right\" ? slack : 0);\r\n blocks.push({\r\n blockId: it.block.id,\r\n x: ix,\r\n y: py,\r\n firstLineIndex: 0,\r\n lines: [],\r\n image: { src: it.block.src, width: it.width, height: it.height },\r\n });\r\n py += it.height + CELL_BLOCK_GAP;\r\n }\r\n } else if (it.kind === \"equation\") {\r\n const align = it.block.align ?? \"center\";\r\n const slack = innerWidth - it.width;\r\n const ix = cx + mgn.left + (align === \"center\" ? slack / 2 : align === \"right\" ? slack : 0);\r\n blocks.push({\r\n blockId: it.block.id,\r\n x: ix,\r\n y: py,\r\n firstLineIndex: 0,\r\n lines: [],\r\n equation: { box: it.box, width: it.width, height: it.height, baseline: it.box.ascent },\r\n });\r\n py += it.height + CELL_BLOCK_GAP;\r\n } else {\r\n // nested table \u2014 placed recursively, read-only inner cells\r\n blocks.push(placeTable(it.block, it.rows, it.colWidths, cx + mgn.left + it.xOffset, py, it.tableWidth, 0, listCtx));\r\n py += it.height + CELL_BLOCK_GAP;\r\n }\r\n }\r\n cells.push({\r\n x: cx,\r\n y: ry,\r\n width: mc.width,\r\n height: cellHeight,\r\n originRow: firstRowIndex + lr,\r\n originCol: mc.colStart,\r\n blocks,\r\n ...(mc.cell.shading !== undefined ? { shading: mc.cell.shading } : {}),\r\n ...(mc.cell.borders !== undefined ? { borders: mc.cell.borders } : {}),\r\n // Horizontal content band (full cell height): clips over-wide text to the\r\n // inner box so it never paints onto the border or into the next column.\r\n contentClip: { x: cx + mgn.left, y: ry, width: innerWidth, height: cellHeight },\r\n });\r\n }\r\n placedRows.push({ y: ry, height: row.height, cells });\r\n }\r\n const height = rows.reduce((s, r) => s + r.height, 0);\r\n return {\r\n blockId: t.id,\r\n x,\r\n y,\r\n firstLineIndex: firstRowIndex, // for tables this is the chunk's first ROW index\r\n lines: [],\r\n table: { x, y, width, height, rows: placedRows, colWidths, ...(t.bidiVisual ? { bidiVisual: true } : {}) },\r\n };\r\n}\r\n"],
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;AAKO,IAAM,kBAAkB;AAAA,EAC3B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACJ;AACO,IAAM,sBAAsB;AAAA,EAC/B,CAAC,KAAO,KAAO,IAAI;AAAA,EACnB,CAAC,KAAO,KAAO,IAAI;AAAA,EACnB,CAAC,KAAO,KAAO,IAAI;AAAA,EACnB,CAAC,KAAO,KAAO,IAAI;AAAA,EACnB,CAAC,KAAO,KAAO,IAAI;AAAA,EACnB,CAAC,KAAO,KAAO,KAAK;AAAA,EACpB,CAAC,KAAO,KAAO,IAAI;AAAA,EACnB,CAAC,KAAO,KAAO,IAAI;AAAA,EACnB,CAAC,KAAO,KAAO,IAAI;AAAA,EACnB,CAAC,KAAO,KAAO,IAAI;AAAA,EACnB,CAAC,MAAO,MAAO,IAAI;AAAA,EACnB,CAAC,MAAO,MAAO,KAAK;AAAA,EACpB,CAAC,MAAO,MAAO,IAAI;AAAA,EACnB,CAAC,MAAO,MAAO,IAAI;AAAA,EACnB,CAAC,MAAO,MAAO,IAAI;AAAA,EACnB,CAAC,MAAO,MAAO,GAAG;AAAA,EAClB,CAAC,MAAO,MAAO,KAAK;AAAA,EACpB,CAAC,MAAO,MAAO,GAAG;AAAA,EAClB,CAAC,MAAO,MAAO,KAAK;AAAA,EACpB,CAAC,MAAO,MAAO,GAAG;AAAA,EAClB,CAAC,MAAO,MAAO,KAAK;AAAA,EACpB,CAAC,MAAO,MAAO,GAAG;AAAA,EAClB,CAAC,MAAO,MAAO,KAAK;AAAA,EACpB,CAAC,MAAO,MAAO,GAAG;AAAA,EAClB,CAAC,MAAO,MAAO,KAAK;AAAA,EACpB,CAAC,MAAO,MAAO,GAAG;AAAA,EAClB,CAAC,MAAO,MAAO,IAAI;AAAA,EACnB,CAAC,MAAO,MAAO,IAAI;AAAA,EACnB,CAAC,MAAO,MAAO,IAAI;AAAA,EACnB,CAAC,MAAO,MAAO,IAAI;AAAA,EACnB,CAAC,MAAO,MAAO,IAAI;AAAA,EACnB,CAAC,MAAO,MAAO,IAAI;AAAA,EACnB,CAAC,MAAO,MAAO,IAAI;AAAA,EACnB,CAAC,MAAO,MAAO,IAAI;AAAA,EACnB,CAAC,MAAO,MAAO,KAAK;AAAA,EACpB,CAAC,MAAO,MAAO,IAAI;AAAA,EACnB,CAAC,MAAO,MAAO,KAAK;AAAA,EACpB,CAAC,MAAO,MAAO,IAAI;AAAA,EACnB,CAAC,MAAO,MAAO,IAAI;AAAA,EACnB,CAAC,MAAO,MAAO,IAAI;AAAA,EACnB,CAAC,MAAO,MAAO,IAAI;AAAA,EACnB,CAAC,MAAO,MAAO,KAAK;AAAA,EACpB,CAAC,MAAO,MAAO,IAAI;AAAA,EACnB,CAAC,MAAO,MAAO,KAAK;AAAA,EACpB,CAAC,MAAO,MAAO,IAAI;AAAA,EACnB,CAAC,MAAO,MAAO,IAAI;AAAA,EACnB,CAAC,MAAO,MAAO,KAAK;AAAA,EACpB,CAAC,MAAO,MAAO,IAAI;AAAA,EACnB,CAAC,MAAO,MAAO,KAAK;AAAA,EACpB,CAAC,MAAO,MAAO,IAAI;AAAA,EACnB,CAAC,MAAO,MAAO,KAAK;AAAA,EACpB,CAAC,MAAO,MAAO,IAAI;AAAA,EACnB,CAAC,MAAO,MAAO,IAAI;AAAA,EACnB,CAAC,MAAO,MAAO,IAAI;AAAA,EACnB,CAAC,MAAO,MAAO,KAAK;AAAA,EACpB,CAAC,MAAO,MAAO,IAAI;AAAA,EACnB,CAAC,MAAO,MAAO,KAAK;AAAA,EACpB,CAAC,MAAO,MAAO,IAAI;AAAA,EACnB,CAAC,MAAO,MAAO,KAAK;AAAA,EACpB,CAAC,MAAO,MAAO,IAAI;AAAA,EACnB,CAAC,MAAO,MAAO,GAAG;AAAA,EAClB,CAAC,MAAO,MAAO,KAAK;AAAA,EACpB,CAAC,MAAO,MAAO,GAAG;AAAA,EAClB,CAAC,MAAO,MAAO,IAAI;AAAA,EACnB,CAAC,MAAO,MAAO,GAAG;AAAA,EAClB,CAAC,MAAO,MAAO,KAAK;AAAA,EACpB,CAAC,MAAO,MAAO,GAAG;AAAA,EAClB,CAAC,MAAO,MAAO,KAAK;AAAA,EACpB,CAAC,MAAO,MAAO,GAAG;AAAA,EAClB,CAAC,MAAO,MAAO,KAAK;AAAA,EACpB,CAAC,MAAO,MAAO,GAAG;AAAA,EAClB,CAAC,MAAO,MAAO,KAAK;AAAA,EACpB,CAAC,MAAO,MAAO,GAAG;AAAA,EAClB,CAAC,MAAO,MAAO,KAAK;AAAA,EACpB,CAAC,MAAO,MAAO,GAAG;AAAA,EAClB,CAAC,MAAO,MAAO,KAAK;AAAA,EACpB,CAAC,MAAO,MAAO,GAAG;AAAA,EAClB,CAAC,MAAO,MAAO,IAAI;AAAA,EACnB,CAAC,MAAO,MAAO,IAAI;AAAA,EACnB,CAAC,MAAO,MAAO,IAAI;AAAA,EACnB,CAAC,MAAO,MAAO,KAAK;AAAA,EACpB,CAAC,MAAO,MAAO,IAAI;AAAA,EACnB,CAAC,MAAO,MAAO,KAAK;AAAA,EACpB,CAAC,MAAO,MAAO,IAAI;AAAA,EACnB,CAAC,MAAO,MAAO,KAAK;AAAA,EACpB,CAAC,MAAO,MAAO,KAAK;AAAA,EACpB,CAAC,MAAO,MAAO,KAAK;AAAA,EACpB,CAAC,MAAO,MAAO,KAAK;AAAA,EACpB,CAAC,MAAO,MAAO,KAAK;AAAA,EACpB,CAAC,MAAO,MAAO,KAAK;AAAA,EACpB,CAAC,MAAO,MAAO,KAAK;AAAA,EACpB,CAAC,MAAO,MAAO,KAAK;AAAA,EACpB,CAAC,MAAO,MAAO,KAAK;AAAA,EACpB,CAAC,MAAO,MAAO,KAAK;AAAA,EACpB,CAAC,MAAO,MAAO,KAAK;AAAA,EACpB,CAAC,MAAO,MAAO,KAAK;AAAA,EACpB,CAAC,MAAO,MAAO,IAAI;AAAA,EACnB,CAAC,MAAO,MAAO,IAAI;AAAA,EACnB,CAAC,MAAO,MAAO,KAAK;AAAA,EACpB,CAAC,MAAO,MAAO,KAAK;AAAA,EACpB,CAAC,MAAO,MAAO,KAAK;AAAA,EACpB,CAAC,MAAO,MAAO,KAAK;AAAA,EACpB,CAAC,MAAO,MAAO,KAAK;AAAA,EACpB,CAAC,MAAO,MAAO,KAAK;AAAA,EACpB,CAAC,MAAO,MAAO,KAAK;AAAA,EACpB,CAAC,MAAO,MAAO,KAAK;AAAA,EACpB,CAAC,MAAO,MAAO,KAAK;AAAA,EACpB,CAAC,MAAO,MAAO,KAAK;AAAA,EACpB,CAAC,MAAO,MAAO,KAAK;AAAA,EACpB,CAAC,MAAO,MAAO,KAAK;AAAA,EACpB,CAAC,MAAO,MAAO,KAAK;AAAA,EACpB,CAAC,MAAO,MAAO,KAAK;AAAA,EACpB,CAAC,MAAO,MAAO,KAAK;AAAA,EACpB,CAAC,MAAO,MAAO,IAAI;AAAA,EACnB,CAAC,MAAO,MAAO,KAAK;AAAA,EACpB,CAAC,MAAO,MAAO,KAAK;AAAA,EACpB,CAAC,MAAO,MAAO,KAAK;AAAA,EACpB,CAAC,MAAO,MAAO,KAAK;AAAA,EACpB,CAAC,MAAO,MAAO,KAAK;AAAA,EACpB,CAAC,MAAO,MAAO,KAAK;AAAA,EACpB,CAAC,MAAO,MAAO,KAAK;AAAA,EACpB,CAAC,MAAO,MAAO,KAAK;AAAA,EACpB,CAAC,MAAO,MAAO,KAAK;AAAA,EACpB,CAAC,MAAO,MAAO,KAAK;AAAA,EACpB,CAAC,MAAO,MAAO,KAAK;AAAA,EACpB,CAAC,MAAO,MAAO,IAAI;AAAA,EACnB,CAAC,MAAO,MAAO,IAAI;AAAA,EACnB,CAAC,MAAO,MAAO,IAAI;AAAA,EACnB,CAAC,MAAO,MAAO,KAAK;AAAA,EACpB,CAAC,MAAO,MAAO,KAAK;AAAA,EACpB,CAAC,MAAO,MAAO,KAAK;AAAA,EACpB,CAAC,MAAO,MAAO,KAAK;AAAA,EACpB,CAAC,MAAO,MAAO,KAAK;AAAA,EACpB,CAAC,MAAO,MAAO,KAAK;AAAA,EACpB,CAAC,MAAO,MAAO,KAAK;AAAA,EACpB,CAAC,MAAO,MAAO,KAAK;AAAA,EACpB,CAAC,MAAO,MAAO,IAAI;AAAA,EACnB,CAAC,MAAO,MAAO,KAAK;AAAA,EACpB,CAAC,MAAO,MAAO,KAAK;AAAA,EACpB,CAAC,MAAO,MAAO,KAAK;AAAA,EACpB,CAAC,MAAO,MAAO,KAAK;AAAA,EACpB,CAAC,MAAO,MAAO,KAAK;AAAA,EACpB,CAAC,MAAO,MAAO,KAAK;AAAA,EACpB,CAAC,MAAO,MAAO,KAAK;AAAA,EACpB,CAAC,MAAO,MAAO,KAAK;AAAA,EACpB,CAAC,MAAO,MAAO,KAAK;AAAA,EACpB,CAAC,MAAO,MAAO,KAAK;AAAA,EACpB,CAAC,MAAO,MAAO,KAAK;AAAA,EACpB,CAAC,MAAO,MAAO,KAAK;AAAA,EACpB,CAAC,MAAO,MAAO,KAAK;AAAA,EACpB,CAAC,MAAO,MAAO,KAAK;AAAA,EACpB,CAAC,MAAO,MAAO,KAAK;AAAA,EACpB,CAAC,MAAO,MAAO,IAAI;AAAA,EACnB,CAAC,MAAO,MAAO,KAAK;AAAA,EACpB,CAAC,MAAO,MAAO,KAAK;AAAA,EACpB,CAAC,MAAO,MAAO,KAAK;AAAA,EACpB,CAAC,MAAO,MAAO,KAAK;AAAA,EACpB,CAAC,MAAO,MAAO,KAAK;AAAA,EACpB,CAAC,MAAO,MAAO,KAAK;AAAA,EACpB,CAAC,MAAO,MAAO,KAAK;AAAA,EACpB,CAAC,MAAO,MAAO,KAAK;AAAA,EACpB,CAAC,MAAO,MAAO,IAAI;AAAA,EACnB,CAAC,MAAO,MAAO,KAAK;AAAA,EACpB,CAAC,MAAO,MAAO,KAAK;AAAA,EACpB,CAAC,MAAO,MAAO,KAAK;AAAA,EACpB,CAAC,MAAO,MAAO,KAAK;AAAA,EACpB,CAAC,MAAO,MAAO,KAAK;AAAA,EACpB,CAAC,MAAO,MAAO,KAAK;AAAA,EACpB,CAAC,MAAQ,MAAQ,KAAK;AAAA,EACtB,CAAC,MAAQ,MAAQ,KAAK;AAAA,EACtB,CAAC,MAAQ,MAAQ,KAAK;AAAA,EACtB,CAAC,MAAQ,MAAQ,KAAK;AAAA,EACtB,CAAC,MAAQ,MAAQ,KAAK;AAAA,EACtB,CAAC,MAAQ,MAAQ,KAAK;AAAA,EACtB,CAAC,MAAQ,MAAQ,KAAK;AAAA,EACtB,CAAC,MAAQ,MAAQ,KAAK;AAAA,EACtB,CAAC,MAAQ,MAAQ,KAAK;AAAA,EACtB,CAAC,MAAQ,MAAQ,KAAK;AAAA,EACtB,CAAC,MAAQ,MAAQ,KAAK;AAAA,EACtB,CAAC,MAAQ,MAAQ,KAAK;AAAA,EACtB,CAAC,MAAQ,MAAQ,IAAI;AAAA,EACrB,CAAC,MAAQ,MAAQ,IAAI;AAAA,EACrB,CAAC,MAAQ,MAAQ,IAAI;AAAA,EACrB,CAAC,MAAQ,MAAQ,IAAI;AAAA,EACrB,CAAC,MAAQ,MAAQ,KAAK;AAAA,EACtB,CAAC,MAAQ,MAAQ,KAAK;AAAA,EACtB,CAAC,MAAQ,MAAQ,KAAK;AAAA,EACtB,CAAC,MAAQ,MAAQ,KAAK;AAAA,EACtB,CAAC,MAAQ,MAAQ,KAAK;AAAA,EACtB,CAAC,MAAQ,MAAQ,KAAK;AAAA,EACtB,CAAC,MAAQ,MAAQ,KAAK;AAAA,EACtB,CAAC,MAAQ,MAAQ,KAAK;AAAA,EACtB,CAAC,MAAQ,MAAQ,IAAI;AAAA,EACrB,CAAC,MAAQ,MAAQ,KAAK;AAAA,EACtB,CAAC,MAAQ,MAAQ,IAAI;AAAA,EACrB,CAAC,MAAQ,MAAQ,IAAI;AAAA,EACrB,CAAC,MAAQ,MAAQ,KAAK;AAAA,EACtB,CAAC,MAAQ,MAAQ,IAAI;AAAA,EACrB,CAAC,MAAQ,MAAQ,KAAK;AAAA,EACtB,CAAC,MAAQ,MAAQ,KAAK;AAAA,EACtB,CAAC,MAAQ,MAAQ,KAAK;AAAA,EACtB,CAAC,MAAQ,MAAQ,KAAK;AAAA,EACtB,CAAC,MAAQ,MAAQ,KAAK;AAAA,EACtB,CAAC,MAAQ,MAAQ,KAAK;AAAA,EACtB,CAAC,MAAQ,MAAQ,KAAK;AAAA,EACtB,CAAC,MAAQ,MAAQ,IAAI;AAAA,EACrB,CAAC,MAAQ,MAAQ,IAAI;AAAA,EACrB,CAAC,MAAQ,MAAQ,IAAI;AAAA,EACrB,CAAC,MAAQ,MAAQ,KAAK;AAAA,EACtB,CAAC,MAAQ,MAAQ,KAAK;AAAA,EACtB,CAAC,MAAQ,MAAQ,KAAK;AAAA,EACtB,CAAC,MAAQ,MAAQ,KAAK;AAAA,EACtB,CAAC,MAAQ,MAAQ,KAAK;AAAA,EACtB,CAAC,MAAQ,MAAQ,KAAK;AAAA,EACtB,CAAC,MAAQ,MAAQ,KAAK;AAAA,EACtB,CAAC,MAAQ,MAAQ,KAAK;AAAA,EACtB,CAAC,MAAQ,MAAQ,KAAK;AAAA,EACtB,CAAC,MAAQ,MAAQ,KAAK;AAAA,EACtB,CAAC,MAAQ,MAAQ,KAAK;AAAA,EACtB,CAAC,MAAQ,MAAQ,KAAK;AAAA,EACtB,CAAC,MAAQ,MAAQ,KAAK;AAAA,EACtB,CAAC,MAAQ,MAAQ,KAAK;AAAA,EACtB,CAAC,MAAQ,MAAQ,KAAK;AAAA,EACtB,CAAC,MAAQ,MAAQ,KAAK;AAAA,EACtB,CAAC,MAAQ,MAAQ,KAAK;AAAA,EACtB,CAAC,MAAQ,MAAQ,KAAK;AAAA,EACtB,CAAC,MAAQ,MAAQ,KAAK;AAAA,EACtB,CAAC,MAAQ,MAAQ,KAAK;AAAA,EACtB,CAAC,MAAQ,MAAQ,KAAK;AAAA,EACtB,CAAC,MAAQ,MAAQ,KAAK;AAAA,EACtB,CAAC,MAAQ,MAAQ,KAAK;AAAA,EACtB,CAAC,MAAQ,MAAQ,KAAK;AAAA,EACtB,CAAC,MAAQ,MAAQ,KAAK;AAAA,EACtB,CAAC,MAAQ,MAAQ,KAAK;AAAA,EACtB,CAAC,MAAQ,MAAQ,KAAK;AAAA,EACtB,CAAC,MAAQ,MAAQ,KAAK;AAAA,EACtB,CAAC,MAAQ,MAAQ,KAAK;AAAA,EACtB,CAAC,MAAQ,MAAQ,KAAK;AAAA,EACtB,CAAC,MAAQ,MAAQ,KAAK;AAAA,EACtB,CAAC,MAAQ,MAAQ,KAAK;AAAA,EACtB,CAAC,MAAQ,MAAQ,KAAK;AAAA,EACtB,CAAC,MAAQ,MAAQ,KAAK;AAAA,EACtB,CAAC,MAAQ,MAAQ,IAAI;AAAA,EACrB,CAAC,MAAQ,MAAQ,IAAI;AAAA,EACrB,CAAC,MAAQ,MAAQ,IAAI;AAAA,EACrB,CAAC,MAAQ,MAAQ,IAAI;AAAA,EACrB,CAAC,MAAQ,MAAQ,IAAI;AAAA,EACrB,CAAC,MAAQ,MAAQ,IAAI;AAAA,EACrB,CAAC,MAAQ,MAAQ,IAAI;AAAA,EACrB,CAAC,MAAQ,MAAQ,IAAI;AAAA,EACrB,CAAC,MAAQ,MAAQ,GAAG;AAAA,EACpB,CAAC,MAAQ,MAAQ,IAAI;AAAA,EACrB,CAAC,MAAQ,MAAQ,IAAI;AAAA,EACrB,CAAC,MAAQ,MAAQ,GAAG;AAAA,EACpB,CAAC,MAAQ,MAAQ,IAAI;AAAA,EACrB,CAAC,MAAQ,MAAQ,IAAI;AAAA,EACrB,CAAC,MAAQ,MAAQ,IAAI;AAAA,EACrB,CAAC,MAAQ,MAAQ,IAAI;AAAA,EACrB,CAAC,MAAQ,MAAQ,IAAI;AAAA,EACrB,CAAC,MAAQ,MAAQ,IAAI;AAAA,EACrB,CAAC,MAAQ,MAAQ,IAAI;AAAA,EACrB,CAAC,MAAQ,MAAQ,IAAI;AAAA,EACrB,CAAC,MAAQ,MAAQ,IAAI;AAAA,EACrB,CAAC,MAAQ,MAAQ,IAAI;AAAA,EACrB,CAAC,MAAQ,MAAQ,IAAI;AAAA,EACrB,CAAC,MAAQ,MAAQ,IAAI;AAAA,EACrB,CAAC,MAAQ,MAAQ,IAAI;AAAA,EACrB,CAAC,MAAQ,MAAQ,IAAI;AAAA,EACrB,CAAC,MAAQ,MAAQ,IAAI;AAAA,EACrB,CAAC,MAAQ,MAAQ,IAAI;AAAA,EACrB,CAAC,MAAQ,MAAQ,KAAK;AAAA,EACtB,CAAC,MAAQ,MAAQ,IAAI;AAAA,EACrB,CAAC,MAAQ,MAAQ,IAAI;AAAA,EACrB,CAAC,MAAQ,MAAQ,IAAI;AAAA,EACrB,CAAC,MAAQ,MAAQ,IAAI;AAAA,EACrB,CAAC,MAAQ,MAAQ,IAAI;AAAA,EACrB,CAAC,MAAQ,MAAQ,IAAI;AAAA,EACrB,CAAC,MAAQ,MAAQ,IAAI;AAAA,EACrB,CAAC,MAAQ,MAAQ,IAAI;AAAA,EACrB,CAAC,MAAQ,MAAQ,IAAI;AAAA,EACrB,CAAC,MAAQ,MAAQ,IAAI;AAAA,EACrB,CAAC,MAAQ,MAAQ,IAAI;AAAA,EACrB,CAAC,MAAQ,MAAQ,IAAI;AAAA,EACrB,CAAC,MAAQ,MAAQ,IAAI;AAAA,EACrB,CAAC,MAAQ,MAAQ,IAAI;AAAA,EACrB,CAAC,MAAQ,MAAQ,IAAI;AAAA,EACrB,CAAC,MAAQ,MAAQ,IAAI;AAAA,EACrB,CAAC,MAAQ,MAAQ,IAAI;AAAA,EACrB,CAAC,MAAQ,MAAQ,IAAI;AAAA,EACrB,CAAC,MAAQ,MAAQ,IAAI;AAAA,EACrB,CAAC,MAAQ,MAAQ,IAAI;AAAA,EACrB,CAAC,MAAQ,MAAQ,IAAI;AAAA,EACrB,CAAC,MAAQ,MAAQ,IAAI;AAAA,EACrB,CAAC,MAAQ,MAAQ,IAAI;AAAA,EACrB,CAAC,MAAQ,MAAQ,IAAI;AAAA,EACrB,CAAC,MAAQ,MAAQ,IAAI;AAAA,EACrB,CAAC,MAAQ,OAAQ,IAAI;AAAA,EACrB,CAAC,OAAQ,OAAQ,IAAI;AAAA,EACrB,CAAC,OAAQ,OAAQ,IAAI;AAAA,EACrB,CAAC,OAAQ,OAAQ,IAAI;AAAA,EACrB,CAAC,OAAQ,OAAQ,KAAK;AAAA,EACtB,CAAC,OAAQ,OAAQ,IAAI;AAAA,EACrB,CAAC,OAAQ,OAAQ,KAAK;AAAA,EACtB,CAAC,OAAQ,OAAQ,KAAK;AAAA,EACtB,CAAC,OAAQ,OAAQ,IAAI;AAAA,EACrB,CAAC,OAAQ,OAAQ,IAAI;AAAA,EACrB,CAAC,OAAQ,OAAQ,IAAI;AAAA,EACrB,CAAC,OAAQ,OAAQ,IAAI;AAAA,EACrB,CAAC,OAAQ,OAAQ,IAAI;AAAA,EACrB,CAAC,OAAQ,OAAQ,IAAI;AAAA,EACrB,CAAC,OAAQ,OAAQ,IAAI;AAAA,EACrB,CAAC,OAAQ,OAAQ,IAAI;AAAA,EACrB,CAAC,OAAQ,OAAQ,KAAK;AAAA,EACtB,CAAC,OAAQ,OAAQ,IAAI;AAAA,EACrB,CAAC,OAAQ,OAAQ,IAAI;AAAA,EACrB,CAAC,OAAQ,OAAQ,IAAI;AAAA,EACrB,CAAC,OAAQ,OAAQ,KAAK;AAAA,EACtB,CAAC,OAAQ,OAAQ,IAAI;AAAA,EACrB,CAAC,OAAQ,OAAQ,IAAI;AAAA,EACrB,CAAC,OAAQ,OAAQ,IAAI;AAAA,EACrB,CAAC,OAAQ,OAAQ,IAAI;AAAA,EACrB,CAAC,OAAQ,OAAQ,IAAI;AAAA,EACrB,CAAC,OAAQ,OAAQ,IAAI;AAAA,EACrB,CAAC,OAAQ,OAAQ,IAAI;AAAA,EACrB,CAAC,OAAQ,OAAQ,IAAI;AAAA,EACrB,CAAC,OAAQ,OAAQ,IAAI;AAAA,EACrB,CAAC,OAAQ,OAAQ,IAAI;AAAA,EACrB,CAAC,OAAQ,OAAQ,IAAI;AAAA,EACrB,CAAC,OAAQ,OAAQ,IAAI;AAAA,EACrB,CAAC,OAAQ,OAAQ,IAAI;AAAA,EACrB,CAAC,OAAQ,OAAQ,IAAI;AAAA,EACrB,CAAC,OAAQ,OAAQ,IAAI;AAAA,EACrB,CAAC,OAAQ,OAAQ,IAAI;AAAA,EACrB,CAAC,OAAQ,OAAQ,KAAK;AAAA,EACtB,CAAC,OAAQ,OAAQ,IAAI;AAAA,EACrB,CAAC,OAAQ,OAAQ,KAAK;AAAA,EACtB,CAAC,OAAQ,OAAQ,IAAI;AAAA,EACrB,CAAC,OAAQ,OAAQ,KAAK;AAAA,EACtB,CAAC,OAAQ,OAAQ,KAAK;AAAA,EACtB,CAAC,OAAQ,OAAQ,IAAI;AAAA,EACrB,CAAC,OAAQ,OAAQ,IAAI;AAAA,EACrB,CAAC,OAAQ,OAAQ,KAAK;AAAA,EACtB,CAAC,OAAQ,OAAQ,KAAK;AAAA,EACtB,CAAC,OAAQ,OAAQ,KAAK;AAAA,EACtB,CAAC,OAAQ,OAAQ,KAAK;AAAA,EACtB,CAAC,OAAQ,OAAQ,IAAI;AAAA,EACrB,CAAC,OAAQ,OAAQ,KAAK;AAAA,EACtB,CAAC,OAAQ,OAAQ,IAAI;AAAA,EACrB,CAAC,OAAQ,OAAQ,IAAI;AAAA,EACrB,CAAC,OAAQ,OAAQ,KAAK;AAAA,EACtB,CAAC,OAAQ,OAAQ,KAAK;AAAA,EACtB,CAAC,OAAQ,OAAQ,KAAK;AAAA,EACtB,CAAC,OAAQ,OAAQ,KAAK;AAAA,EACtB,CAAC,OAAQ,OAAQ,KAAK;AAAA,EACtB,CAAC,OAAQ,OAAQ,KAAK;AAAA,EACtB,CAAC,OAAQ,OAAQ,KAAK;AAAA,EACtB,CAAC,OAAQ,OAAQ,KAAK;AAAA,EACtB,CAAC,OAAQ,OAAQ,KAAK;AAAA,EACtB,CAAC,OAAQ,OAAQ,KAAK;AAAA,EACtB,CAAC,OAAQ,OAAQ,KAAK;AAAA,EACtB,CAAC,OAAQ,OAAQ,KAAK;AAAA,EACtB,CAAC,OAAQ,OAAQ,KAAK;AAAA,EACtB,CAAC,OAAQ,OAAQ,KAAK;AAAA,EACtB,CAAC,OAAQ,OAAQ,KAAK;AAAA,EACtB,CAAC,OAAQ,OAAQ,KAAK;AAAA,EACtB,CAAC,OAAQ,OAAQ,KAAK;AAAA,EACtB,CAAC,OAAQ,OAAQ,KAAK;AAAA,EACtB,CAAC,OAAQ,OAAQ,KAAK;AAAA,EACtB,CAAC,OAAQ,OAAQ,KAAK;AAAA,EACtB,CAAC,OAAQ,OAAQ,KAAK;AAAA,EACtB,CAAC,OAAQ,OAAQ,KAAK;AAAA,EACtB,CAAC,OAAQ,OAAQ,KAAK;AAAA,EACtB,CAAC,OAAQ,OAAQ,IAAI;AAAA,EACrB,CAAC,OAAQ,OAAQ,KAAK;AAAA,EACtB,CAAC,OAAQ,OAAQ,KAAK;AAAA,EACtB,CAAC,OAAQ,OAAQ,KAAK;AAAA,EACtB,CAAC,OAAQ,OAAQ,GAAG;AAAA,EACpB,CAAC,OAAQ,OAAQ,KAAK;AAAA,EACtB,CAAC,OAAQ,OAAQ,GAAG;AAAA,EACpB,CAAC,OAAQ,OAAQ,IAAI;AAAA,EACrB,CAAC,OAAQ,OAAQ,GAAG;AAAA,EACpB,CAAC,OAAQ,OAAQ,IAAI;AAAA,EACrB,CAAC,OAAQ,OAAQ,IAAI;AAAA,EACrB,CAAC,OAAQ,OAAQ,IAAI;AAAA,EACrB,CAAC,OAAQ,OAAQ,IAAI;AAAA,EACrB,CAAC,OAAQ,OAAQ,IAAI;AAAA,EACrB,CAAC,OAAQ,OAAQ,IAAI;AAAA,EACrB,CAAC,OAAQ,OAAQ,IAAI;AAAA,EACrB,CAAC,OAAQ,OAAQ,IAAI;AAAA,EACrB,CAAC,OAAQ,OAAQ,IAAI;AAAA,EACrB,CAAC,OAAQ,OAAQ,IAAI;AAAA,EACrB,CAAC,OAAQ,OAAQ,IAAI;AAAA,EACrB,CAAC,OAAQ,OAAQ,KAAK;AAAA,EACtB,CAAC,OAAQ,OAAQ,IAAI;AAAA,EACrB,CAAC,OAAQ,OAAQ,KAAK;AAAA,EACtB,CAAC,OAAQ,OAAQ,IAAI;AAAA,EACrB,CAAC,OAAQ,OAAQ,IAAI;AAAA,EACrB,CAAC,OAAQ,OAAQ,IAAI;AAAA,EACrB,CAAC,OAAQ,OAAQ,IAAI;AAAA,EACrB,CAAC,OAAQ,OAAQ,IAAI;AAAA,EACrB,CAAC,OAAQ,OAAQ,IAAI;AAAA,EACrB,CAAC,OAAQ,OAAQ,IAAI;AAAA,EACrB,CAAC,OAAQ,OAAQ,IAAI;AAAA,EACrB,CAAC,OAAQ,OAAQ,IAAI;AAAA,EACrB,CAAC,OAAQ,OAAQ,IAAI;AAAA,EACrB,CAAC,OAAQ,OAAQ,IAAI;AAAA,EACrB,CAAC,OAAQ,OAAQ,IAAI;AAAA,EACrB,CAAC,OAAQ,OAAQ,IAAI;AAAA,EACrB,CAAC,OAAQ,OAAQ,IAAI;AAAA,EACrB,CAAC,OAAQ,OAAQ,IAAI;AAAA,EACrB,CAAC,OAAQ,OAAQ,IAAI;AAAA,EACrB,CAAC,OAAQ,OAAQ,IAAI;AAAA,EACrB,CAAC,OAAQ,OAAQ,IAAI;AAAA,EACrB,CAAC,OAAQ,OAAQ,IAAI;AAAA,EACrB,CAAC,OAAQ,OAAQ,IAAI;AAAA,EACrB,CAAC,OAAQ,OAAQ,IAAI;AAAA,EACrB,CAAC,OAAQ,OAAQ,IAAI;AAAA,EACrB,CAAC,OAAQ,OAAQ,IAAI;AAAA,EACrB,CAAC,OAAQ,OAAQ,IAAI;AAAA,EACrB,CAAC,OAAQ,OAAQ,IAAI;AAAA,EACrB,CAAC,OAAQ,OAAQ,IAAI;AAAA,EACrB,CAAC,OAAQ,OAAQ,IAAI;AAAA,EACrB,CAAC,OAAQ,OAAQ,IAAI;AAAA,EACrB,CAAC,OAAQ,OAAQ,IAAI;AAAA,EACrB,CAAC,OAAQ,OAAQ,IAAI;AAAA,EACrB,CAAC,OAAQ,OAAQ,IAAI;AAAA,EACrB,CAAC,OAAQ,OAAQ,IAAI;AAAA,EACrB,CAAC,OAAQ,OAAQ,IAAI;AAAA,EACrB,CAAC,OAAQ,OAAQ,IAAI;AAAA,EACrB,CAAC,OAAQ,OAAQ,IAAI;AAAA,EACrB,CAAC,OAAS,OAAS,IAAI;AAAA,EACvB,CAAC,OAAS,OAAS,IAAI;AAAA,EACvB,CAAC,OAAS,OAAS,IAAI;AAAA,EACvB,CAAC,OAAS,OAAS,IAAI;AAAA,EACvB,CAAC,OAAS,OAAS,KAAK;AAAA,EACxB,CAAC,OAAS,OAAS,KAAK;AAAA,EACxB,CAAC,OAAS,OAAS,IAAI;AAAA,EACvB,CAAC,OAAS,OAAS,KAAK;AAAA,EACxB,CAAC,OAAS,OAAS,GAAG;AAAA,EACtB,CAAC,OAAS,OAAS,IAAI;AAAA,EACvB,CAAC,OAAS,OAAS,GAAG;AAAA,EACtB,CAAC,OAAS,OAAS,KAAK;AAAA,EACxB,CAAC,OAAS,OAAS,GAAG;AAAA,EACtB,CAAC,OAAS,OAAS,KAAK;AAAA,EACxB,CAAC,OAAS,OAAS,GAAG;AAAA,EACtB,CAAC,OAAS,OAAS,KAAK;AAAA,EACxB,CAAC,OAAS,OAAS,GAAG;AAAA,EACtB,CAAC,OAAS,OAAS,KAAK;AAAA,EACxB,CAAC,OAAS,OAAS,GAAG;AAAA,EACtB,CAAC,OAAS,OAAS,KAAK;AAAA,EACxB,CAAC,OAAS,OAAS,GAAG;AAAA,EACtB,CAAC,OAAS,OAAS,KAAK;AAAA,EACxB,CAAC,OAAS,OAAS,GAAG;AAAA,EACtB,CAAC,OAAS,OAAS,IAAI;AAAA,EACvB,CAAC,OAAS,OAAS,GAAG;AAAA,EACtB,CAAC,OAAS,OAAS,IAAI;AAAA,EACvB,CAAC,OAAS,OAAS,KAAK;AAAA,EACxB,CAAC,OAAS,OAAS,IAAI;AAAA,EACvB,CAAC,OAAS,OAAS,IAAI;AAAA,EACvB,CAAC,OAAS,OAAS,IAAI;AAAA,EACvB,CAAC,OAAS,OAAS,IAAI;AAAA,EACvB,CAAC,OAAS,OAAS,GAAG;AAAA,EACtB,CAAC,OAAS,OAAS,KAAK;AAAA,EACxB,CAAC,OAAS,OAAS,IAAI;AAAA,EACvB,CAAC,OAAS,OAAS,GAAG;AAAA,EACtB,CAAC,OAAS,OAAS,IAAI;AAAA,EACvB,CAAC,OAAS,OAAS,GAAG;AAAA,EACtB,CAAC,OAAS,OAAS,KAAK;AAAA,EACxB,CAAC,OAAS,OAAS,GAAG;AAAA,EACtB,CAAC,OAAS,OAAS,IAAI;AAAA,EACvB,CAAC,OAAS,OAAS,IAAI;AAAA,EACvB,CAAC,OAAS,OAAS,IAAI;AAAA,EACvB,CAAC,OAAS,OAAS,KAAK;AAAA,EACxB,CAAC,OAAS,OAAS,GAAG;AAAA,EACtB,CAAC,OAAS,OAAS,IAAI;AAAA,EACvB,CAAC,OAAS,OAAS,KAAK;AAAA,EACxB,CAAC,OAAS,OAAS,IAAI;AAAA,EACvB,CAAC,OAAS,OAAS,GAAG;AAAA,EACtB,CAAC,OAAS,OAAS,KAAK;AAAA,EACxB,CAAC,OAAS,OAAS,GAAG;AAAA,EACtB,CAAC,OAAS,OAAS,KAAK;AAAA,EACxB,CAAC,OAAS,OAAS,KAAK;AAAA,EACxB,CAAC,OAAS,OAAS,IAAI;AAAA,EACvB,CAAC,OAAS,OAAS,KAAK;AAAA,EACxB,CAAC,OAAS,OAAS,KAAK;AAAA,EACxB,CAAC,OAAS,OAAS,KAAK;AAAA,EACxB,CAAC,OAAS,OAAS,KAAK;AAAA,EACxB,CAAC,OAAS,OAAS,KAAK;AAAA,EACxB,CAAC,OAAS,OAAS,KAAK;AAAA,EACxB,CAAC,OAAS,OAAS,KAAK;AAAA,EACxB,CAAC,OAAS,OAAS,KAAK;AAAA,EACxB,CAAC,OAAS,OAAS,KAAK;AAAA,EACxB,CAAC,OAAS,OAAS,KAAK;AAAA,EACxB,CAAC,OAAS,OAAS,KAAK;AAAA,EACxB,CAAC,OAAS,OAAS,KAAK;AAAA,EACxB,CAAC,OAAS,OAAS,KAAK;AAAA,EACxB,CAAC,OAAS,OAAS,KAAK;AAAA,EACxB,CAAC,OAAS,OAAS,KAAK;AAAA,EACxB,CAAC,OAAS,OAAS,KAAK;AAAA,EACxB,CAAC,OAAS,OAAS,KAAK;AAAA,EACxB,CAAC,OAAS,OAAS,KAAK;AAAA,EACxB,CAAC,OAAS,OAAS,KAAK;AAAA,EACxB,CAAC,OAAS,OAAS,KAAK;AAAA,EACxB,CAAC,OAAS,OAAS,KAAK;AAAA,EACxB,CAAC,OAAS,OAAS,KAAK;AAAA,EACxB,CAAC,OAAS,OAAS,KAAK;AAAA,EACxB,CAAC,OAAS,OAAS,KAAK;AAAA,EACxB,CAAC,OAAS,OAAS,KAAK;AAAA,EACxB,CAAC,OAAS,OAAS,KAAK;AAAA,EACxB,CAAC,OAAS,OAAS,KAAK;AAAA,EACxB,CAAC,OAAS,OAAS,KAAK;AAAA,EACxB,CAAC,OAAS,OAAS,KAAK;AAAA,EACxB,CAAC,OAAS,OAAS,KAAK;AAAA,EACxB,CAAC,OAAS,OAAS,KAAK;AAAA,EACxB,CAAC,OAAS,OAAS,KAAK;AAAA,EACxB,CAAC,OAAS,OAAS,KAAK;AAAA,EACxB,CAAC,OAAS,OAAS,KAAK;AAAA,EACxB,CAAC,OAAS,OAAS,KAAK;AAAA,EACxB,CAAC,OAAS,OAAS,KAAK;AAAA,EACxB,CAAC,OAAS,OAAS,KAAK;AAAA,EACxB,CAAC,OAAS,OAAS,KAAK;AAAA,EACxB,CAAC,OAAS,OAAS,KAAK;AAAA,EACxB,CAAC,OAAS,OAAS,KAAK;AAAA,EACxB,CAAC,OAAS,OAAS,KAAK;AAAA,EACxB,CAAC,OAAS,OAAS,KAAK;AAAA,EACxB,CAAC,OAAS,OAAS,KAAK;AAAA,EACxB,CAAC,OAAS,OAAS,KAAK;AAAA,EACxB,CAAC,OAAS,OAAS,KAAK;AAAA,EACxB,CAAC,OAAS,OAAS,KAAK;AAAA,EACxB,CAAC,OAAS,OAAS,IAAI;AAAA,EACvB,CAAC,OAAS,OAAS,KAAK;AAAA,EACxB,CAAC,OAAS,OAAS,KAAK;AAAA,EACxB,CAAC,OAAS,OAAS,KAAK;AAAA,EACxB,CAAC,OAAS,OAAS,KAAK;AAAA,EACxB,CAAC,OAAS,OAAS,KAAK;AAAA,EACxB,CAAC,OAAS,OAAS,KAAK;AAAA,EACxB,CAAC,OAAS,OAAS,KAAK;AAAA,EACxB,CAAC,OAAS,OAAS,KAAK;AAAA,EACxB,CAAC,OAAS,OAAS,KAAK;AAAA,EACxB,CAAC,OAAS,OAAS,KAAK;AAAA,EACxB,CAAC,OAAS,OAAS,KAAK;AAAA,EACxB,CAAC,OAAS,OAAS,KAAK;AAAA,EACxB,CAAC,OAAS,OAAS,KAAK;AAAA,EACxB,CAAC,OAAS,OAAS,KAAK;AAAA,EACxB,CAAC,OAAS,OAAS,KAAK;AAAA,EACxB,CAAC,OAAS,OAAS,KAAK;AAAA,EACxB,CAAC,OAAS,OAAS,KAAK;AAAA,EACxB,CAAC,OAAS,OAAS,KAAK;AAAA,EACxB,CAAC,OAAS,OAAS,KAAK;AAAA,EACxB,CAAC,OAAS,OAAS,KAAK;AAAA,EACxB,CAAC,OAAS,OAAS,KAAK;AAAA,EACxB,CAAC,OAAS,OAAS,KAAK;AAAA,EACxB,CAAC,OAAS,OAAS,KAAK;AAAA,EACxB,CAAC,OAAS,OAAS,KAAK;AAAA,EACxB,CAAC,OAAS,OAAS,KAAK;AAAA,EACxB,CAAC,OAAS,OAAS,KAAK;AAAA,EACxB,CAAC,OAAS,OAAS,KAAK;AAAA,EACxB,CAAC,OAAS,OAAS,KAAK;AAAA,EACxB,CAAC,OAAS,OAAS,KAAK;AAAA,EACxB,CAAC,OAAS,OAAS,KAAK;AAAA,EACxB,CAAC,OAAS,OAAS,KAAK;AAAA,EACxB,CAAC,OAAS,OAAS,KAAK;AAAA,EACxB,CAAC,OAAS,OAAS,KAAK;AAAA,EACxB,CAAC,OAAS,OAAS,KAAK;AAAA,EACxB,CAAC,OAAS,OAAS,KAAK;AAAA,EACxB,CAAC,OAAS,OAAS,KAAK;AAAA,EACxB,CAAC,OAAS,OAAS,KAAK;AAAA,EACxB,CAAC,OAAS,OAAS,KAAK;AAAA,EACxB,CAAC,OAAS,OAAS,KAAK;AAAA,EACxB,CAAC,OAAS,OAAS,KAAK;AAAA,EACxB,CAAC,OAAS,OAAS,KAAK;AAAA,EACxB,CAAC,OAAS,OAAS,KAAK;AAAA,EACxB,CAAC,OAAS,OAAS,KAAK;AAAA,EACxB,CAAC,OAAS,OAAS,KAAK;AAAA,EACxB,CAAC,OAAS,OAAS,KAAK;AAAA,EACxB,CAAC,OAAS,OAAS,KAAK;AAAA,EACxB,CAAC,OAAS,OAAS,KAAK;AAAA,EACxB,CAAC,OAAS,OAAS,KAAK;AAAA,EACxB,CAAC,OAAS,OAAS,IAAI;AAAA,EACvB,CAAC,OAAS,OAAS,IAAI;AAAA,EACvB,CAAC,OAAS,OAAS,IAAI;AAAA,EACvB,CAAC,OAAS,OAAS,KAAK;AAAA,EACxB,CAAC,OAAS,OAAS,KAAK;AAAA,EACxB,CAAC,OAAS,OAAS,KAAK;AAAA,EACxB,CAAC,OAAS,OAAS,KAAK;AAAA,EACxB,CAAC,OAAS,OAAS,KAAK;AAAA,EACxB,CAAC,OAAS,OAAS,KAAK;AAAA,EACxB,CAAC,OAAS,OAAS,KAAK;AAAA,EACxB,CAAC,OAAS,OAAS,KAAK;AAAA,EACxB,CAAC,OAAS,OAAS,IAAI;AAAA,EACvB,CAAC,OAAS,OAAS,KAAK;AAAA,EACxB,CAAC,QAAS,QAAS,KAAK;AAAA,EACxB,CAAC,QAAS,QAAS,IAAI;AAAA,EACvB,CAAC,QAAS,QAAS,IAAI;AAAA,EACvB,CAAC,OAAS,QAAS,IAAI;AAAA,EACvB,CAAC,QAAS,QAAS,IAAI;AAAA,EACvB,CAAC,QAAS,QAAS,IAAI;AAAA,EACvB,CAAC,QAAS,QAAS,IAAI;AAAA,EACvB,CAAC,QAAS,QAAS,IAAI;AAAA,EACvB,CAAC,QAAS,QAAS,KAAK;AAAA,EACxB,CAAC,QAAS,QAAS,KAAK;AAAA,EACxB,CAAC,QAAS,QAAS,KAAK;AAAA,EACxB,CAAC,QAAS,QAAS,IAAI;AAAA,EACvB,CAAC,QAAS,QAAS,KAAK;AAAA,EACxB,CAAC,QAAS,QAAS,KAAK;AAAA,EACxB,CAAC,QAAS,QAAS,KAAK;AAAA,EACxB,CAAC,QAAS,QAAS,IAAI;AAAA,EACvB,CAAC,QAAS,QAAS,IAAI;AAAA,EACvB,CAAC,QAAS,QAAS,KAAK;AAAA,EACxB,CAAC,QAAS,QAAS,IAAI;AAAA,EACvB,CAAC,QAAS,QAAS,IAAI;AAAA,EACvB,CAAC,QAAS,QAAS,IAAI;AAAA,EACvB,CAAC,QAAS,QAAS,IAAI;AAAA,EACvB,CAAC,QAAS,QAAS,IAAI;AAAA,EACvB,CAAC,QAAS,QAAS,IAAI;AAAA,EACvB,CAAC,QAAS,QAAS,IAAI;AAAA,EACvB,CAAC,QAAS,QAAS,IAAI;AAAA,EACvB,CAAC,QAAS,QAAS,IAAI;AAAA,EACvB,CAAC,QAAS,QAAS,IAAI;AAAA,EACvB,CAAC,QAAS,QAAS,IAAI;AAAA,EACvB,CAAC,QAAS,QAAS,IAAI;AAAA,EACvB,CAAC,QAAS,QAAS,IAAI;AAAA,EACvB,CAAC,QAAS,QAAS,KAAK;AAAA,EACxB,CAAC,QAAS,QAAS,KAAK;AAAA,EACxB,CAAC,QAAS,QAAS,KAAK;AAAA,EACxB,CAAC,QAAS,QAAS,KAAK;AAAA,EACxB,CAAC,QAAS,QAAS,KAAK;AAAA,EACxB,CAAC,QAAS,QAAS,KAAK;AAAA,EACxB,CAAC,QAAS,QAAS,KAAK;AAAA,EACxB,CAAC,QAAS,QAAS,KAAK;AAAA,EACxB,CAAC,QAAS,QAAS,KAAK;AAAA,EACxB,CAAC,QAAS,QAAS,KAAK;AAAA,EACxB,CAAC,QAAS,QAAS,KAAK;AAAA,EACxB,CAAC,QAAS,QAAS,KAAK;AAAA,EACxB,CAAC,QAAS,QAAS,KAAK;AAAA,EACxB,CAAC,QAAS,QAAS,KAAK;AAAA,EACxB,CAAC,QAAS,QAAS,KAAK;AAAA,EACxB,CAAC,QAAS,QAAS,IAAI;AAAA,EACvB,CAAC,QAAS,QAAS,KAAK;AAAA,EACxB,CAAC,QAAS,QAAS,KAAK;AAAA,EACxB,CAAC,QAAS,QAAS,KAAK;AAAA,EACxB,CAAC,QAAS,QAAS,KAAK;AAAA,EACxB,CAAC,QAAS,QAAS,KAAK;AAAA,EACxB,CAAC,QAAS,QAAS,KAAK;AAAA,EACxB,CAAC,QAAS,QAAS,GAAG;AAAA,EACtB,CAAC,QAAS,QAAS,KAAK;AAAA,EACxB,CAAC,QAAS,QAAS,GAAG;AAAA,EACtB,CAAC,QAAS,QAAS,KAAK;AAAA,EACxB,CAAC,QAAS,QAAS,GAAG;AAAA,EACtB,CAAC,QAAS,QAAS,IAAI;AAAA,EACvB,CAAC,QAAS,QAAS,GAAG;AAAA,EACtB,CAAC,QAAS,QAAS,IAAI;AAAA,EACvB,CAAC,QAAS,QAAS,GAAG;AAAA,EACtB,CAAC,QAAS,QAAS,IAAI;AAAA,EACvB,CAAC,QAAS,QAAS,IAAI;AAAA,EACvB,CAAC,QAAS,QAAS,IAAI;AAAA,EACvB,CAAC,QAAS,QAAS,GAAG;AAAA,EACtB,CAAC,QAAS,QAAS,IAAI;AAAA,EACvB,CAAC,QAAS,QAAS,IAAI;AAAA,EACvB,CAAC,QAAS,QAAS,IAAI;AAAA,EACvB,CAAC,QAAS,QAAS,IAAI;AAAA,EACvB,CAAC,QAAS,QAAS,IAAI;AAAA,EACvB,CAAC,QAAS,QAAS,IAAI;AAAA,EACvB,CAAC,QAAS,QAAS,IAAI;AAAA,EACvB,CAAC,QAAS,QAAS,IAAI;AAAA,EACvB,CAAC,QAAS,QAAS,IAAI;AAAA,EACvB,CAAC,QAAS,QAAS,IAAI;AAAA,EACvB,CAAC,QAAS,QAAS,IAAI;AAAA,EACvB,CAAC,QAAS,QAAS,IAAI;AAAA,EACvB,CAAC,QAAS,QAAS,IAAI;AAAA,EACvB,CAAC,QAAS,QAAS,IAAI;AAAA,EACvB,CAAC,QAAS,QAAS,IAAI;AAAA,EACvB,CAAC,QAAS,QAAS,IAAI;AAAA,EACvB,CAAC,QAAS,QAAS,IAAI;AAAA,EACvB,CAAC,QAAS,QAAS,IAAI;AAAA,EACvB,CAAC,QAAS,QAAS,IAAI;AAAA,EACvB,CAAC,QAAS,QAAS,IAAI;AAAA,EACvB,CAAC,QAAS,QAAS,IAAI;AAAA,EACvB,CAAC,QAAS,QAAS,IAAI;AAAA,EACvB,CAAC,QAAS,QAAS,IAAI;AAAA,EACvB,CAAC,QAAS,QAAS,IAAI;AAAA,EACvB,CAAC,QAAS,QAAS,IAAI;AAAA,EACvB,CAAC,QAAS,QAAS,IAAI;AAAA,EACvB,CAAC,QAAS,QAAS,IAAI;AAAA,EACvB,CAAC,QAAS,QAAS,IAAI;AAAA,EACvB,CAAC,QAAS,QAAS,IAAI;AAAA,EACvB,CAAC,QAAS,QAAS,IAAI;AAAA,EACvB,CAAC,QAAS,QAAS,IAAI;AAAA,EACvB,CAAC,QAAS,QAAS,IAAI;AAAA,EACvB,CAAC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",
|
|
6
|
-
"names": ["advances", "sharedGraphemeSegmenter", "getSharedGraphemeSegmenter", "sharedGraphemeSegmenter", "getSharedGraphemeSegmenter", "a", "a", "a"]
|
|
7
|
-
}
|