@beyondwork/docx-react-component 1.0.109 → 1.0.110
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/package.json +1 -1
- package/src/model/layout/runtime-page-graph-types.ts +25 -0
- package/src/runtime/document-runtime.ts +46 -0
- package/src/runtime/geometry/adjacent-geometry-intake.ts +450 -13
- package/src/runtime/geometry/geometry-index.ts +17 -2
- package/src/runtime/layout/layout-engine-instance.ts +231 -4
- package/src/runtime/layout/layout-engine-version.ts +16 -1
- package/src/runtime/layout/page-graph.ts +7 -0
- package/src/runtime/layout/paginated-layout-engine.ts +34 -0
- package/src/runtime/layout/public-facet.ts +68 -9
- package/src/runtime/layout/resolve-page-previews.ts +46 -8
- package/src/ui-tailwind/chrome-overlay/tw-table-split-row-carry-overlay.tsx +62 -0
- package/src/ui-tailwind/editor-surface/tw-prosemirror-surface.tsx +1 -0
- package/src/ui-tailwind/page-stack/tw-page-chrome-entry.tsx +62 -0
- package/src/ui-tailwind/page-stack/tw-page-stack-chrome-layer.tsx +1 -0
|
@@ -25,15 +25,60 @@ export interface AdjacentGeometryPageSpan {
|
|
|
25
25
|
readonly endPage?: number | null;
|
|
26
26
|
}
|
|
27
27
|
|
|
28
|
+
export type AdjacentGeometryPageIndexStatus =
|
|
29
|
+
| "matches-runtime"
|
|
30
|
+
| "differs-from-runtime"
|
|
31
|
+
| "runtime-missing"
|
|
32
|
+
| "word-page-missing";
|
|
33
|
+
|
|
34
|
+
export interface AdjacentGeometryL04FrameProjection {
|
|
35
|
+
readonly pageIndex?: number;
|
|
36
|
+
readonly pageId?: string;
|
|
37
|
+
readonly frameId?: string;
|
|
38
|
+
readonly frameCompleteness?: string;
|
|
39
|
+
readonly physicalBoundsTwips?: AdjacentGeometryTwipsRect;
|
|
40
|
+
readonly markerLane?: AdjacentGeometryTwipsRect;
|
|
41
|
+
readonly textColumn?: AdjacentGeometryTwipsRect;
|
|
42
|
+
readonly fieldStartAnchorTwips?: {
|
|
43
|
+
readonly x?: number;
|
|
44
|
+
readonly y?: number;
|
|
45
|
+
};
|
|
46
|
+
readonly fieldEndAnchorTwips?: {
|
|
47
|
+
readonly x?: number;
|
|
48
|
+
readonly y?: number;
|
|
49
|
+
};
|
|
50
|
+
readonly coordinateSpace: "l04-frame-twips";
|
|
51
|
+
readonly precision: "word-page-local-calibration";
|
|
52
|
+
readonly status:
|
|
53
|
+
| "projected-l04-frame"
|
|
54
|
+
| "page-index-differs-from-runtime"
|
|
55
|
+
| "runtime-page-missing"
|
|
56
|
+
| "word-page-missing"
|
|
57
|
+
| "missing-l04-page-frame"
|
|
58
|
+
| "missing-word-page-local-geometry";
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
interface AdjacentGeometryPageFrame {
|
|
62
|
+
readonly pageId?: string;
|
|
63
|
+
readonly pageIndex: number;
|
|
64
|
+
readonly frameId?: string;
|
|
65
|
+
readonly completeness?: string;
|
|
66
|
+
readonly physicalBoundsTwips?: AdjacentGeometryTwipsRect;
|
|
67
|
+
}
|
|
68
|
+
|
|
28
69
|
export interface AdjacentGeometryPageLocalNumberingGeometry {
|
|
29
70
|
readonly wordPage?: number;
|
|
71
|
+
readonly normalizedWordPageIndex?: number;
|
|
30
72
|
readonly runtimePageIndex?: number;
|
|
73
|
+
readonly pageIndexStatus: AdjacentGeometryPageIndexStatus;
|
|
31
74
|
readonly runtimeFragmentId?: string;
|
|
32
75
|
readonly markerLane?: AdjacentGeometryTwipsRect;
|
|
33
76
|
readonly textColumn?: AdjacentGeometryTwipsRect;
|
|
77
|
+
readonly l04FrameProjection: AdjacentGeometryL04FrameProjection;
|
|
34
78
|
readonly coordinateSpace: "word-page-twips";
|
|
35
79
|
readonly precision: "word-page-local-calibration";
|
|
36
80
|
readonly normalizationStatus:
|
|
81
|
+
| "l04-frame-twips-projected"
|
|
37
82
|
| "word-page-local-awaiting-l04-frame-projection"
|
|
38
83
|
| "missing-word-page-local-lane";
|
|
39
84
|
}
|
|
@@ -56,9 +101,11 @@ export interface AdjacentGeometryPageLocalFieldGeometry {
|
|
|
56
101
|
readonly x?: number;
|
|
57
102
|
readonly y?: number;
|
|
58
103
|
};
|
|
104
|
+
readonly l04FrameProjection: AdjacentGeometryL04FrameProjection;
|
|
59
105
|
readonly coordinateSpace: "word-page-twips";
|
|
60
106
|
readonly precision: "word-page-local-calibration";
|
|
61
107
|
readonly normalizationStatus:
|
|
108
|
+
| "l04-frame-twips-projected"
|
|
62
109
|
| "word-page-local-awaiting-l04-frame-projection"
|
|
63
110
|
| "missing-word-placement";
|
|
64
111
|
}
|
|
@@ -69,6 +116,9 @@ export interface AdjacentGeometryNumberingRowSummary {
|
|
|
69
116
|
readonly canonicalBlockId?: string;
|
|
70
117
|
readonly runtimeBlockId?: string;
|
|
71
118
|
readonly runtimeFragmentId?: string;
|
|
119
|
+
readonly runtimeNumberingId?: string;
|
|
120
|
+
readonly layoutObjectId?: string;
|
|
121
|
+
readonly runtimeJoinSource: "adjacent-live" | "l04-numbering-readback";
|
|
72
122
|
readonly runtimePageIndex?: number;
|
|
73
123
|
readonly sourceParagraphPath?: string;
|
|
74
124
|
readonly canonicalNumberingInstanceId?: string;
|
|
@@ -141,6 +191,7 @@ export interface AdjacentGeometryDocumentSummary {
|
|
|
141
191
|
readonly docId: string;
|
|
142
192
|
readonly numberingRows: number;
|
|
143
193
|
readonly numberingRowsWithRuntimeFragment: number;
|
|
194
|
+
readonly numberingRowsJoinedFromL04Readback: number;
|
|
144
195
|
readonly numberingParagraphLineRects: number;
|
|
145
196
|
readonly numberingTextOnlyLineRects: number;
|
|
146
197
|
readonly numberingRawMarkerRectRows: number;
|
|
@@ -150,6 +201,10 @@ export interface AdjacentGeometryDocumentSummary {
|
|
|
150
201
|
readonly numberingRowsWithUiaCapture: number;
|
|
151
202
|
readonly numberingRowsWithPageLocalMarkerLane: number;
|
|
152
203
|
readonly numberingRowsWithPageLocalTextColumn: number;
|
|
204
|
+
readonly numberingRowsWithRuntimePageMatch: number;
|
|
205
|
+
readonly numberingUiaRowsWithRuntimePageMatch: number;
|
|
206
|
+
readonly numberingRowsWithL04FrameProjection: number;
|
|
207
|
+
readonly numberingUiaRowsWithL04FrameProjection: number;
|
|
153
208
|
readonly fieldRegionRows: number;
|
|
154
209
|
readonly fieldRegionRowsWithRuntimeId: number;
|
|
155
210
|
readonly fieldRegionResultLineRects: number;
|
|
@@ -157,10 +212,12 @@ export interface AdjacentGeometryDocumentSummary {
|
|
|
157
212
|
readonly fieldRegionRowsWithWordPlacement: number;
|
|
158
213
|
readonly fieldRegionRowsWithRuntimePageMatch: number;
|
|
159
214
|
readonly fieldRegionRowsWithRuntimePageContainment: number;
|
|
215
|
+
readonly fieldRegionRowsWithL04FrameProjection: number;
|
|
216
|
+
readonly fieldRegionUiaRowsWithL04FrameProjection: number;
|
|
160
217
|
}
|
|
161
218
|
|
|
162
219
|
export interface AdjacentGeometryIntakeSummary {
|
|
163
|
-
readonly schemaVersion: "layer-05-adjacent-geometry-intake/
|
|
220
|
+
readonly schemaVersion: "layer-05-adjacent-geometry-intake/v1";
|
|
164
221
|
readonly generatedAtUtc: string;
|
|
165
222
|
readonly sourceRuns: {
|
|
166
223
|
readonly adjacentLiveWordJoins: string;
|
|
@@ -170,6 +227,7 @@ export interface AdjacentGeometryIntakeSummary {
|
|
|
170
227
|
readonly totals: {
|
|
171
228
|
readonly numberingRows: number;
|
|
172
229
|
readonly numberingRowsWithRuntimeFragment: number;
|
|
230
|
+
readonly numberingRowsJoinedFromL04Readback: number;
|
|
173
231
|
readonly numberingParagraphLineRects: number;
|
|
174
232
|
readonly numberingTextOnlyLineRects: number;
|
|
175
233
|
readonly numberingRawMarkerRectRows: number;
|
|
@@ -179,6 +237,10 @@ export interface AdjacentGeometryIntakeSummary {
|
|
|
179
237
|
readonly numberingRowsWithUiaCapture: number;
|
|
180
238
|
readonly numberingRowsWithPageLocalMarkerLane: number;
|
|
181
239
|
readonly numberingRowsWithPageLocalTextColumn: number;
|
|
240
|
+
readonly numberingRowsWithRuntimePageMatch: number;
|
|
241
|
+
readonly numberingUiaRowsWithRuntimePageMatch: number;
|
|
242
|
+
readonly numberingRowsWithL04FrameProjection: number;
|
|
243
|
+
readonly numberingUiaRowsWithL04FrameProjection: number;
|
|
182
244
|
readonly fieldRegionRows: number;
|
|
183
245
|
readonly fieldRegionRowsWithRuntimeId: number;
|
|
184
246
|
readonly fieldRegionResultLineRects: number;
|
|
@@ -186,6 +248,8 @@ export interface AdjacentGeometryIntakeSummary {
|
|
|
186
248
|
readonly fieldRegionRowsWithWordPlacement: number;
|
|
187
249
|
readonly fieldRegionRowsWithRuntimePageMatch: number;
|
|
188
250
|
readonly fieldRegionRowsWithRuntimePageContainment: number;
|
|
251
|
+
readonly fieldRegionRowsWithL04FrameProjection: number;
|
|
252
|
+
readonly fieldRegionUiaRowsWithL04FrameProjection: number;
|
|
189
253
|
};
|
|
190
254
|
readonly routing: {
|
|
191
255
|
readonly routedTo: "L05";
|
|
@@ -198,6 +262,8 @@ export interface AdjacentGeometryIntakeSummary {
|
|
|
198
262
|
readonly coordinateSpace: "word-page-twips";
|
|
199
263
|
readonly precision: "word-page-local-calibration";
|
|
200
264
|
readonly requiredUpstreamFact: "L04 frame-to-pixel projection";
|
|
265
|
+
readonly l04FrameProjectionCoordinateSpace: "l04-frame-twips";
|
|
266
|
+
readonly l04FrameProjectionPrecision: "word-page-local-calibration";
|
|
201
267
|
readonly compositorReady: false;
|
|
202
268
|
};
|
|
203
269
|
readonly documents: readonly AdjacentGeometryDocumentSummary[];
|
|
@@ -210,16 +276,23 @@ export function summarizeAdjacentGeometryIntake(input: {
|
|
|
210
276
|
readonly sourceRuns: AdjacentGeometryIntakeSummary["sourceRuns"];
|
|
211
277
|
readonly numberingArtifact: unknown;
|
|
212
278
|
readonly numberingLiveJoinArtifacts: readonly unknown[];
|
|
279
|
+
readonly numberingRuntimeReadbackArtifacts?: readonly unknown[];
|
|
213
280
|
readonly fieldRegionRuntimeReadback: unknown;
|
|
214
281
|
readonly fieldRegionLiveJoinArtifacts: readonly unknown[];
|
|
215
282
|
}): AdjacentGeometryIntakeSummary {
|
|
283
|
+
const pageFramesByDocId = collectPageFramesByDocId(
|
|
284
|
+
input.numberingRuntimeReadbackArtifacts ?? [],
|
|
285
|
+
);
|
|
216
286
|
const numberingRows = summarizeNumberingRows(
|
|
217
287
|
input.numberingArtifact,
|
|
218
288
|
input.numberingLiveJoinArtifacts,
|
|
289
|
+
input.numberingRuntimeReadbackArtifacts ?? [],
|
|
290
|
+
pageFramesByDocId,
|
|
219
291
|
);
|
|
220
292
|
const fieldRegionRows = summarizeFieldRegionRows(
|
|
221
293
|
input.fieldRegionRuntimeReadback,
|
|
222
294
|
input.fieldRegionLiveJoinArtifacts,
|
|
295
|
+
pageFramesByDocId,
|
|
223
296
|
);
|
|
224
297
|
const docIds = [
|
|
225
298
|
...new Set([
|
|
@@ -228,7 +301,7 @@ export function summarizeAdjacentGeometryIntake(input: {
|
|
|
228
301
|
]),
|
|
229
302
|
].sort();
|
|
230
303
|
return {
|
|
231
|
-
schemaVersion: "layer-05-adjacent-geometry-intake/
|
|
304
|
+
schemaVersion: "layer-05-adjacent-geometry-intake/v1",
|
|
232
305
|
generatedAtUtc: input.generatedAtUtc,
|
|
233
306
|
sourceRuns: input.sourceRuns,
|
|
234
307
|
totals: {
|
|
@@ -236,6 +309,9 @@ export function summarizeAdjacentGeometryIntake(input: {
|
|
|
236
309
|
numberingRowsWithRuntimeFragment: numberingRows.filter(
|
|
237
310
|
(row) => row.runtimeFragmentId !== undefined,
|
|
238
311
|
).length,
|
|
312
|
+
numberingRowsJoinedFromL04Readback: numberingRows.filter(
|
|
313
|
+
(row) => row.runtimeJoinSource === "l04-numbering-readback",
|
|
314
|
+
).length,
|
|
239
315
|
numberingParagraphLineRects: sum(
|
|
240
316
|
numberingRows,
|
|
241
317
|
(row) => row.paragraphLineRectCount,
|
|
@@ -258,6 +334,19 @@ export function summarizeAdjacentGeometryIntake(input: {
|
|
|
258
334
|
numberingRowsWithPageLocalTextColumn: numberingRows.filter(
|
|
259
335
|
(row) => row.pageLocalGeometry.textColumn !== undefined,
|
|
260
336
|
).length,
|
|
337
|
+
numberingRowsWithRuntimePageMatch: numberingRows.filter(
|
|
338
|
+
(row) => row.pageLocalGeometry.pageIndexStatus === "matches-runtime",
|
|
339
|
+
).length,
|
|
340
|
+
numberingUiaRowsWithRuntimePageMatch: numberingRows.filter(
|
|
341
|
+
(row) =>
|
|
342
|
+
hasNumberingUiaCapture(row) &&
|
|
343
|
+
row.pageLocalGeometry.pageIndexStatus === "matches-runtime",
|
|
344
|
+
).length,
|
|
345
|
+
numberingRowsWithL04FrameProjection: numberingRows.filter(hasL04FrameProjection)
|
|
346
|
+
.length,
|
|
347
|
+
numberingUiaRowsWithL04FrameProjection: numberingRows.filter(
|
|
348
|
+
(row) => hasNumberingUiaCapture(row) && hasL04FrameProjection(row),
|
|
349
|
+
).length,
|
|
261
350
|
fieldRegionRows: fieldRegionRows.length,
|
|
262
351
|
fieldRegionRowsWithRuntimeId: fieldRegionRows.filter(
|
|
263
352
|
(row) => row.runtimeFieldRegionId !== undefined,
|
|
@@ -278,6 +367,12 @@ export function summarizeAdjacentGeometryIntake(input: {
|
|
|
278
367
|
fieldRegionRowsWithRuntimePageContainment: fieldRegionRows.filter(
|
|
279
368
|
(row) => row.pageLocalGeometry.pageSpanStatus === "contained-in-runtime",
|
|
280
369
|
).length,
|
|
370
|
+
fieldRegionRowsWithL04FrameProjection: fieldRegionRows.filter(
|
|
371
|
+
hasL04FrameProjection,
|
|
372
|
+
).length,
|
|
373
|
+
fieldRegionUiaRowsWithL04FrameProjection: fieldRegionRows.filter(
|
|
374
|
+
(row) => row.resultLineRectCount > 0 && hasL04FrameProjection(row),
|
|
375
|
+
).length,
|
|
281
376
|
},
|
|
282
377
|
routing: {
|
|
283
378
|
routedTo: "L05",
|
|
@@ -290,6 +385,8 @@ export function summarizeAdjacentGeometryIntake(input: {
|
|
|
290
385
|
coordinateSpace: "word-page-twips",
|
|
291
386
|
precision: "word-page-local-calibration",
|
|
292
387
|
requiredUpstreamFact: "L04 frame-to-pixel projection",
|
|
388
|
+
l04FrameProjectionCoordinateSpace: "l04-frame-twips",
|
|
389
|
+
l04FrameProjectionPrecision: "word-page-local-calibration",
|
|
293
390
|
compositorReady: false,
|
|
294
391
|
},
|
|
295
392
|
documents: docIds.map((docId) =>
|
|
@@ -307,6 +404,8 @@ export function summarizeAdjacentGeometryIntake(input: {
|
|
|
307
404
|
function summarizeNumberingRows(
|
|
308
405
|
artifact: unknown,
|
|
309
406
|
liveJoinArtifacts: readonly unknown[],
|
|
407
|
+
runtimeReadbackArtifacts: readonly unknown[],
|
|
408
|
+
pageFramesByDocId: ReadonlyMap<string, ReadonlyMap<number, AdjacentGeometryPageFrame>>,
|
|
310
409
|
): readonly AdjacentGeometryNumberingRowSummary[] {
|
|
311
410
|
const uiaRowsByKey = new Map<string, Record<string, unknown>>();
|
|
312
411
|
for (const raw of array(record(artifact).rows)) {
|
|
@@ -322,8 +421,16 @@ function summarizeNumberingRows(
|
|
|
322
421
|
const liveRows = liveJoinArtifacts.flatMap((artifact) =>
|
|
323
422
|
array(record(artifact).numberingRows).map(record),
|
|
324
423
|
);
|
|
424
|
+
const runtimeReadbacksByKey = collectNumberingRuntimeReadbacks(
|
|
425
|
+
runtimeReadbackArtifacts,
|
|
426
|
+
);
|
|
325
427
|
const rows = liveRows.length > 0
|
|
326
|
-
? liveRows.filter((row) =>
|
|
428
|
+
? liveRows.filter((row) => {
|
|
429
|
+
if (stringValue(row.runtimeFragmentId) !== undefined) return true;
|
|
430
|
+
return (
|
|
431
|
+
numberingRuntimeReadbackForRow(row, runtimeReadbacksByKey) !== undefined
|
|
432
|
+
);
|
|
433
|
+
})
|
|
327
434
|
: array(record(artifact).rows).map(record);
|
|
328
435
|
|
|
329
436
|
return rows
|
|
@@ -338,6 +445,10 @@ function summarizeNumberingRows(
|
|
|
338
445
|
const uiaRow =
|
|
339
446
|
uiaRowsByKey.get(numberingKey(docId, wordParagraphOrdinalGlobal) ?? "") ??
|
|
340
447
|
{};
|
|
448
|
+
const runtimeReadback = numberingRuntimeReadbackForRow(
|
|
449
|
+
row,
|
|
450
|
+
runtimeReadbacksByKey,
|
|
451
|
+
);
|
|
341
452
|
const uiaTargetJoin = record(uiaRow.targetJoin);
|
|
342
453
|
const paragraphLineRects = chooseRects(
|
|
343
454
|
uiaRow.paragraphLineRects,
|
|
@@ -350,28 +461,60 @@ function summarizeNumberingRows(
|
|
|
350
461
|
const rawMarkerRects = chooseRawArray(uiaRow.markerRects, row.markerRects);
|
|
351
462
|
const markerRects = chooseRects(uiaRow.markerRects, row.markerRects);
|
|
352
463
|
const markerLane =
|
|
353
|
-
normalizeTwipsRect(row.markerLane) ??
|
|
464
|
+
normalizeTwipsRect(row.markerLane) ??
|
|
465
|
+
normalizeTwipsRect(runtimeReadback?.markerLane) ??
|
|
466
|
+
normalizeTwipsRect(uiaTargetJoin.markerLane);
|
|
354
467
|
const textColumn =
|
|
355
|
-
normalizeTwipsRect(row.textColumn) ??
|
|
468
|
+
normalizeTwipsRect(row.textColumn) ??
|
|
469
|
+
normalizeTwipsRect(runtimeReadback?.textColumn) ??
|
|
470
|
+
normalizeTwipsRect(uiaTargetJoin.textColumn);
|
|
356
471
|
const runtimeFragmentId =
|
|
357
|
-
stringValue(row.runtimeFragmentId) ??
|
|
472
|
+
stringValue(row.runtimeFragmentId) ??
|
|
473
|
+
stringValue(runtimeReadback?.runtimeFragmentId) ??
|
|
474
|
+
stringValue(uiaTargetJoin.runtimeFragmentId);
|
|
475
|
+
const runtimeJoinSource: AdjacentGeometryNumberingRowSummary["runtimeJoinSource"] =
|
|
476
|
+
stringValue(row.runtimeFragmentId) !== undefined
|
|
477
|
+
? "adjacent-live"
|
|
478
|
+
: "l04-numbering-readback";
|
|
358
479
|
const runtimePageIndex =
|
|
359
|
-
numberValue(row.runtimePageIndex) ??
|
|
480
|
+
numberValue(row.runtimePageIndex) ??
|
|
481
|
+
numberValue(runtimeReadback?.pageIndex) ??
|
|
482
|
+
numberValue(uiaTargetJoin.runtimePageIndex);
|
|
360
483
|
const wordStartPage =
|
|
361
484
|
numberValue(record(row.pageSpan).startPage) ??
|
|
362
485
|
numberValue(row.wordStartPage) ??
|
|
363
486
|
numberValue(uiaRow.wordStartPage);
|
|
487
|
+
const normalizedWordPageIndex =
|
|
488
|
+
wordStartPage === undefined ? undefined : wordStartPage - 1;
|
|
489
|
+
const pageIndexStatus = classifyPageIndex(
|
|
490
|
+
normalizedWordPageIndex,
|
|
491
|
+
runtimePageIndex,
|
|
492
|
+
);
|
|
493
|
+
const l04FrameProjection = projectNumberingToL04Frame({
|
|
494
|
+
docId,
|
|
495
|
+
normalizedWordPageIndex,
|
|
496
|
+
runtimePageIndex,
|
|
497
|
+
pageIndexStatus,
|
|
498
|
+
markerLane,
|
|
499
|
+
textColumn,
|
|
500
|
+
pageFramesByDocId,
|
|
501
|
+
});
|
|
364
502
|
const pageLocalGeometry: AdjacentGeometryPageLocalNumberingGeometry = {
|
|
365
503
|
wordPage: wordStartPage,
|
|
504
|
+
normalizedWordPageIndex,
|
|
366
505
|
runtimePageIndex,
|
|
506
|
+
pageIndexStatus,
|
|
367
507
|
runtimeFragmentId,
|
|
368
508
|
markerLane,
|
|
369
509
|
textColumn,
|
|
510
|
+
l04FrameProjection,
|
|
370
511
|
coordinateSpace: "word-page-twips",
|
|
371
512
|
precision: "word-page-local-calibration",
|
|
372
513
|
normalizationStatus:
|
|
373
|
-
|
|
374
|
-
? "
|
|
514
|
+
l04FrameProjection.status === "projected-l04-frame"
|
|
515
|
+
? "l04-frame-twips-projected"
|
|
516
|
+
: markerLane || textColumn
|
|
517
|
+
? "word-page-local-awaiting-l04-frame-projection"
|
|
375
518
|
: "missing-word-page-local-lane",
|
|
376
519
|
};
|
|
377
520
|
return {
|
|
@@ -380,11 +523,20 @@ function summarizeNumberingRows(
|
|
|
380
523
|
canonicalBlockId:
|
|
381
524
|
stringValue(row.canonicalBlockId) ?? stringValue(uiaTargetJoin.canonicalBlockId),
|
|
382
525
|
runtimeBlockId:
|
|
383
|
-
stringValue(row.runtimeBlockId) ??
|
|
526
|
+
stringValue(row.runtimeBlockId) ??
|
|
527
|
+
stringValue(runtimeReadback?.numberingSourceBlockId) ??
|
|
528
|
+
stringValue(runtimeReadback?.sourceBlockId) ??
|
|
529
|
+
stringValue(uiaTargetJoin.runtimeBlockId),
|
|
384
530
|
runtimeFragmentId,
|
|
531
|
+
runtimeNumberingId:
|
|
532
|
+
stringValue(runtimeReadback?.runtimeNumberingId) ??
|
|
533
|
+
stringValue(record(row.runtimeJoinAttempt).runtimeNumberingId),
|
|
534
|
+
layoutObjectId: stringValue(runtimeReadback?.layoutObjectId),
|
|
535
|
+
runtimeJoinSource,
|
|
385
536
|
runtimePageIndex,
|
|
386
537
|
sourceParagraphPath:
|
|
387
538
|
stringValue(row.sourceParagraphPath) ??
|
|
539
|
+
stringValue(runtimeReadback?.sourceBlockPath) ??
|
|
388
540
|
stringValue(uiaTargetJoin.sourceParagraphPath),
|
|
389
541
|
canonicalNumberingInstanceId:
|
|
390
542
|
stringValue(row.canonicalNumberingInstanceId) ??
|
|
@@ -423,6 +575,7 @@ function summarizeNumberingRows(
|
|
|
423
575
|
function summarizeFieldRegionRows(
|
|
424
576
|
runtimeReadback: unknown,
|
|
425
577
|
liveJoinArtifacts: readonly unknown[],
|
|
578
|
+
pageFramesByDocId: ReadonlyMap<string, ReadonlyMap<number, AdjacentGeometryPageFrame>>,
|
|
426
579
|
): readonly AdjacentGeometryFieldRegionRowSummary[] {
|
|
427
580
|
const liveJoinByOrdinalKey = new Map<string, Record<string, unknown>>();
|
|
428
581
|
const uniqueLiveJoinRows: Record<string, unknown>[] = [];
|
|
@@ -500,18 +653,30 @@ function summarizeFieldRegionRows(
|
|
|
500
653
|
const wordPlacement = normalizeWordPlacement(
|
|
501
654
|
record(readbackRow.wordResultPlacement),
|
|
502
655
|
);
|
|
656
|
+
const pageSpanStatus = classifyPageSpan(normalizedWordPageIndexSpan, runtimePageSpan);
|
|
657
|
+
const l04FrameProjection = projectFieldToL04Frame({
|
|
658
|
+
docId,
|
|
659
|
+
normalizedWordPageIndexSpan,
|
|
660
|
+
runtimePageSpan,
|
|
661
|
+
pageSpanStatus,
|
|
662
|
+
wordPlacement,
|
|
663
|
+
pageFramesByDocId,
|
|
664
|
+
});
|
|
503
665
|
const pageLocalGeometry: AdjacentGeometryPageLocalFieldGeometry = {
|
|
504
666
|
expectedPageSpan,
|
|
505
667
|
normalizedWordPageIndexSpan,
|
|
506
668
|
runtimePageSpan,
|
|
507
|
-
pageSpanStatus
|
|
669
|
+
pageSpanStatus,
|
|
508
670
|
startAnchorTwips: wordPlacement?.startXYTwips,
|
|
509
671
|
endAnchorTwips: wordPlacement?.endXYTwips,
|
|
672
|
+
l04FrameProjection,
|
|
510
673
|
coordinateSpace: "word-page-twips",
|
|
511
674
|
precision: "word-page-local-calibration",
|
|
512
675
|
normalizationStatus:
|
|
513
|
-
|
|
514
|
-
? "
|
|
676
|
+
l04FrameProjection.status === "projected-l04-frame"
|
|
677
|
+
? "l04-frame-twips-projected"
|
|
678
|
+
: wordPlacement?.startXYTwips || wordPlacement?.endXYTwips
|
|
679
|
+
? "word-page-local-awaiting-l04-frame-projection"
|
|
515
680
|
: "missing-word-placement",
|
|
516
681
|
};
|
|
517
682
|
return {
|
|
@@ -562,6 +727,9 @@ function summarizeDocument(
|
|
|
562
727
|
numberingRowsWithRuntimeFragment: numberingRows.filter(
|
|
563
728
|
(row) => row.runtimeFragmentId !== undefined,
|
|
564
729
|
).length,
|
|
730
|
+
numberingRowsJoinedFromL04Readback: numberingRows.filter(
|
|
731
|
+
(row) => row.runtimeJoinSource === "l04-numbering-readback",
|
|
732
|
+
).length,
|
|
565
733
|
numberingParagraphLineRects: sum(
|
|
566
734
|
numberingRows,
|
|
567
735
|
(row) => row.paragraphLineRectCount,
|
|
@@ -584,6 +752,19 @@ function summarizeDocument(
|
|
|
584
752
|
numberingRowsWithPageLocalTextColumn: numberingRows.filter(
|
|
585
753
|
(row) => row.pageLocalGeometry.textColumn !== undefined,
|
|
586
754
|
).length,
|
|
755
|
+
numberingRowsWithRuntimePageMatch: numberingRows.filter(
|
|
756
|
+
(row) => row.pageLocalGeometry.pageIndexStatus === "matches-runtime",
|
|
757
|
+
).length,
|
|
758
|
+
numberingUiaRowsWithRuntimePageMatch: numberingRows.filter(
|
|
759
|
+
(row) =>
|
|
760
|
+
hasNumberingUiaCapture(row) &&
|
|
761
|
+
row.pageLocalGeometry.pageIndexStatus === "matches-runtime",
|
|
762
|
+
).length,
|
|
763
|
+
numberingRowsWithL04FrameProjection: numberingRows.filter(hasL04FrameProjection)
|
|
764
|
+
.length,
|
|
765
|
+
numberingUiaRowsWithL04FrameProjection: numberingRows.filter(
|
|
766
|
+
(row) => hasNumberingUiaCapture(row) && hasL04FrameProjection(row),
|
|
767
|
+
).length,
|
|
587
768
|
fieldRegionRows: fieldRegionRows.length,
|
|
588
769
|
fieldRegionRowsWithRuntimeId: fieldRegionRows.filter(
|
|
589
770
|
(row) => row.runtimeFieldRegionId !== undefined,
|
|
@@ -604,9 +785,21 @@ function summarizeDocument(
|
|
|
604
785
|
fieldRegionRowsWithRuntimePageContainment: fieldRegionRows.filter(
|
|
605
786
|
(row) => row.pageLocalGeometry.pageSpanStatus === "contained-in-runtime",
|
|
606
787
|
).length,
|
|
788
|
+
fieldRegionRowsWithL04FrameProjection: fieldRegionRows.filter(
|
|
789
|
+
hasL04FrameProjection,
|
|
790
|
+
).length,
|
|
791
|
+
fieldRegionUiaRowsWithL04FrameProjection: fieldRegionRows.filter(
|
|
792
|
+
(row) => row.resultLineRectCount > 0 && hasL04FrameProjection(row),
|
|
793
|
+
).length,
|
|
607
794
|
};
|
|
608
795
|
}
|
|
609
796
|
|
|
797
|
+
function hasL04FrameProjection(
|
|
798
|
+
row: AdjacentGeometryNumberingRowSummary | AdjacentGeometryFieldRegionRowSummary,
|
|
799
|
+
): boolean {
|
|
800
|
+
return row.pageLocalGeometry.l04FrameProjection.status === "projected-l04-frame";
|
|
801
|
+
}
|
|
802
|
+
|
|
610
803
|
function hasNumberingUiaCapture(row: AdjacentGeometryNumberingRowSummary): boolean {
|
|
611
804
|
return (
|
|
612
805
|
row.paragraphLineRectCount > 0 ||
|
|
@@ -615,6 +808,250 @@ function hasNumberingUiaCapture(row: AdjacentGeometryNumberingRowSummary): boole
|
|
|
615
808
|
);
|
|
616
809
|
}
|
|
617
810
|
|
|
811
|
+
function collectPageFramesByDocId(
|
|
812
|
+
artifacts: readonly unknown[],
|
|
813
|
+
): Map<string, Map<number, AdjacentGeometryPageFrame>> {
|
|
814
|
+
const byDocId = new Map<string, Map<number, AdjacentGeometryPageFrame>>();
|
|
815
|
+
for (const artifact of artifacts) {
|
|
816
|
+
const artifactRecord = record(artifact);
|
|
817
|
+
const docId = stringValue(artifactRecord.docId);
|
|
818
|
+
if (!docId) continue;
|
|
819
|
+
for (const raw of array(artifactRecord.pages)) {
|
|
820
|
+
const page = record(raw);
|
|
821
|
+
const pageIndex = numberValue(page.pageIndex);
|
|
822
|
+
if (pageIndex === undefined) continue;
|
|
823
|
+
const frame = record(page.frame);
|
|
824
|
+
const physicalBoundsTwips = normalizeTwipsRect(frame.physicalBoundsTwips);
|
|
825
|
+
const pageFrame: AdjacentGeometryPageFrame = {
|
|
826
|
+
pageId: stringValue(page.pageId),
|
|
827
|
+
pageIndex,
|
|
828
|
+
frameId: stringValue(frame.frameId),
|
|
829
|
+
completeness: stringValue(frame.completeness),
|
|
830
|
+
physicalBoundsTwips,
|
|
831
|
+
};
|
|
832
|
+
let docFrames = byDocId.get(docId);
|
|
833
|
+
if (!docFrames) {
|
|
834
|
+
docFrames = new Map<number, AdjacentGeometryPageFrame>();
|
|
835
|
+
byDocId.set(docId, docFrames);
|
|
836
|
+
}
|
|
837
|
+
if (!docFrames.has(pageIndex)) docFrames.set(pageIndex, pageFrame);
|
|
838
|
+
}
|
|
839
|
+
}
|
|
840
|
+
return byDocId;
|
|
841
|
+
}
|
|
842
|
+
|
|
843
|
+
function collectNumberingRuntimeReadbacks(
|
|
844
|
+
artifacts: readonly unknown[],
|
|
845
|
+
): Map<string, Record<string, unknown>> {
|
|
846
|
+
const byKey = new Map<string, Record<string, unknown>>();
|
|
847
|
+
for (const artifact of artifacts) {
|
|
848
|
+
const artifactRecord = record(artifact);
|
|
849
|
+
const docId = stringValue(artifactRecord.docId);
|
|
850
|
+
for (const raw of array(artifactRecord.numberingFragments)) {
|
|
851
|
+
const row = record(raw);
|
|
852
|
+
const key = numberingRuntimeReadbackKey(
|
|
853
|
+
docId ?? stringValue(row.docId),
|
|
854
|
+
stringValue(row.numberingKey) ?? stringValue(row.runtimeNumberingId),
|
|
855
|
+
stringValue(row.numberingInstanceId),
|
|
856
|
+
numberValue(row.level),
|
|
857
|
+
);
|
|
858
|
+
if (key && !byKey.has(key)) byKey.set(key, row);
|
|
859
|
+
}
|
|
860
|
+
}
|
|
861
|
+
return byKey;
|
|
862
|
+
}
|
|
863
|
+
|
|
864
|
+
function numberingRuntimeReadbackForRow(
|
|
865
|
+
row: Record<string, unknown>,
|
|
866
|
+
runtimeReadbacksByKey: ReadonlyMap<string, Record<string, unknown>>,
|
|
867
|
+
): Record<string, unknown> | undefined {
|
|
868
|
+
const key = numberingRuntimeReadbackKey(
|
|
869
|
+
stringValue(row.docId),
|
|
870
|
+
stringValue(record(row.canonicalJoinAttempt).numberingKey),
|
|
871
|
+
stringValue(row.canonicalNumberingInstanceId),
|
|
872
|
+
numberValue(row.canonicalLevel),
|
|
873
|
+
);
|
|
874
|
+
return key ? runtimeReadbacksByKey.get(key) : undefined;
|
|
875
|
+
}
|
|
876
|
+
|
|
877
|
+
function projectNumberingToL04Frame(input: {
|
|
878
|
+
readonly docId: string;
|
|
879
|
+
readonly normalizedWordPageIndex: number | undefined;
|
|
880
|
+
readonly runtimePageIndex: number | undefined;
|
|
881
|
+
readonly pageIndexStatus: AdjacentGeometryPageIndexStatus;
|
|
882
|
+
readonly markerLane: AdjacentGeometryTwipsRect | undefined;
|
|
883
|
+
readonly textColumn: AdjacentGeometryTwipsRect | undefined;
|
|
884
|
+
readonly pageFramesByDocId: ReadonlyMap<string, ReadonlyMap<number, AdjacentGeometryPageFrame>>;
|
|
885
|
+
}): AdjacentGeometryL04FrameProjection {
|
|
886
|
+
if (input.pageIndexStatus === "word-page-missing") {
|
|
887
|
+
return baseFrameProjection("word-page-missing");
|
|
888
|
+
}
|
|
889
|
+
if (input.pageIndexStatus === "runtime-missing") {
|
|
890
|
+
return baseFrameProjection("runtime-page-missing", input.normalizedWordPageIndex);
|
|
891
|
+
}
|
|
892
|
+
if (input.pageIndexStatus === "differs-from-runtime") {
|
|
893
|
+
return baseFrameProjection(
|
|
894
|
+
"page-index-differs-from-runtime",
|
|
895
|
+
input.normalizedWordPageIndex,
|
|
896
|
+
);
|
|
897
|
+
}
|
|
898
|
+
if (!input.markerLane && !input.textColumn) {
|
|
899
|
+
return baseFrameProjection(
|
|
900
|
+
"missing-word-page-local-geometry",
|
|
901
|
+
input.normalizedWordPageIndex,
|
|
902
|
+
);
|
|
903
|
+
}
|
|
904
|
+
const frame = pageFrameFor(input.pageFramesByDocId, input.docId, input.runtimePageIndex);
|
|
905
|
+
if (!frame?.physicalBoundsTwips) {
|
|
906
|
+
return baseFrameProjection("missing-l04-page-frame", input.runtimePageIndex);
|
|
907
|
+
}
|
|
908
|
+
return {
|
|
909
|
+
pageIndex: input.runtimePageIndex,
|
|
910
|
+
pageId: frame.pageId,
|
|
911
|
+
frameId: frame.frameId,
|
|
912
|
+
frameCompleteness: frame.completeness,
|
|
913
|
+
physicalBoundsTwips: frame.physicalBoundsTwips,
|
|
914
|
+
markerLane: addFrameOrigin(input.markerLane, frame.physicalBoundsTwips),
|
|
915
|
+
textColumn: addFrameOrigin(input.textColumn, frame.physicalBoundsTwips),
|
|
916
|
+
coordinateSpace: "l04-frame-twips",
|
|
917
|
+
precision: "word-page-local-calibration",
|
|
918
|
+
status: "projected-l04-frame",
|
|
919
|
+
};
|
|
920
|
+
}
|
|
921
|
+
|
|
922
|
+
function projectFieldToL04Frame(input: {
|
|
923
|
+
readonly docId: string;
|
|
924
|
+
readonly normalizedWordPageIndexSpan: AdjacentGeometryPageSpan | undefined;
|
|
925
|
+
readonly runtimePageSpan: AdjacentGeometryPageSpan | undefined;
|
|
926
|
+
readonly pageSpanStatus: AdjacentGeometryPageLocalFieldGeometry["pageSpanStatus"];
|
|
927
|
+
readonly wordPlacement:
|
|
928
|
+
| AdjacentGeometryFieldRegionRowSummary["wordPlacement"]
|
|
929
|
+
| undefined;
|
|
930
|
+
readonly pageFramesByDocId: ReadonlyMap<string, ReadonlyMap<number, AdjacentGeometryPageFrame>>;
|
|
931
|
+
}): AdjacentGeometryL04FrameProjection {
|
|
932
|
+
const normalizedStart = input.normalizedWordPageIndexSpan?.startPage;
|
|
933
|
+
if (normalizedStart == null) return baseFrameProjection("word-page-missing");
|
|
934
|
+
if (!input.runtimePageSpan || input.runtimePageSpan.startPage == null) {
|
|
935
|
+
return baseFrameProjection("runtime-page-missing", normalizedStart);
|
|
936
|
+
}
|
|
937
|
+
if (
|
|
938
|
+
input.pageSpanStatus !== "matches-runtime" &&
|
|
939
|
+
input.pageSpanStatus !== "contained-in-runtime"
|
|
940
|
+
) {
|
|
941
|
+
return baseFrameProjection("page-index-differs-from-runtime", normalizedStart);
|
|
942
|
+
}
|
|
943
|
+
if (!input.wordPlacement?.startXYTwips && !input.wordPlacement?.endXYTwips) {
|
|
944
|
+
return baseFrameProjection("missing-word-page-local-geometry", normalizedStart);
|
|
945
|
+
}
|
|
946
|
+
const frame = pageFrameFor(
|
|
947
|
+
input.pageFramesByDocId,
|
|
948
|
+
input.docId,
|
|
949
|
+
input.runtimePageSpan.startPage,
|
|
950
|
+
);
|
|
951
|
+
if (!frame?.physicalBoundsTwips) {
|
|
952
|
+
return baseFrameProjection("missing-l04-page-frame", input.runtimePageSpan.startPage);
|
|
953
|
+
}
|
|
954
|
+
return {
|
|
955
|
+
pageIndex: input.runtimePageSpan.startPage,
|
|
956
|
+
pageId: frame.pageId,
|
|
957
|
+
frameId: frame.frameId,
|
|
958
|
+
frameCompleteness: frame.completeness,
|
|
959
|
+
physicalBoundsTwips: frame.physicalBoundsTwips,
|
|
960
|
+
fieldStartAnchorTwips: addFrameOriginToPoint(
|
|
961
|
+
input.wordPlacement.startXYTwips,
|
|
962
|
+
frame.physicalBoundsTwips,
|
|
963
|
+
),
|
|
964
|
+
fieldEndAnchorTwips: addFrameOriginToPoint(
|
|
965
|
+
input.wordPlacement.endXYTwips,
|
|
966
|
+
frame.physicalBoundsTwips,
|
|
967
|
+
),
|
|
968
|
+
coordinateSpace: "l04-frame-twips",
|
|
969
|
+
precision: "word-page-local-calibration",
|
|
970
|
+
status: "projected-l04-frame",
|
|
971
|
+
};
|
|
972
|
+
}
|
|
973
|
+
|
|
974
|
+
function baseFrameProjection(
|
|
975
|
+
status: AdjacentGeometryL04FrameProjection["status"],
|
|
976
|
+
pageIndex?: number,
|
|
977
|
+
): AdjacentGeometryL04FrameProjection {
|
|
978
|
+
return {
|
|
979
|
+
pageIndex,
|
|
980
|
+
coordinateSpace: "l04-frame-twips",
|
|
981
|
+
precision: "word-page-local-calibration",
|
|
982
|
+
status,
|
|
983
|
+
};
|
|
984
|
+
}
|
|
985
|
+
|
|
986
|
+
function pageFrameFor(
|
|
987
|
+
pageFramesByDocId: ReadonlyMap<string, ReadonlyMap<number, AdjacentGeometryPageFrame>>,
|
|
988
|
+
docId: string,
|
|
989
|
+
pageIndex: number | undefined,
|
|
990
|
+
): AdjacentGeometryPageFrame | undefined {
|
|
991
|
+
return pageIndex === undefined ? undefined : pageFramesByDocId.get(docId)?.get(pageIndex);
|
|
992
|
+
}
|
|
993
|
+
|
|
994
|
+
function addFrameOrigin(
|
|
995
|
+
rect: AdjacentGeometryTwipsRect | undefined,
|
|
996
|
+
frame: AdjacentGeometryTwipsRect,
|
|
997
|
+
): AdjacentGeometryTwipsRect | undefined {
|
|
998
|
+
if (!rect) return undefined;
|
|
999
|
+
return {
|
|
1000
|
+
xTwips:
|
|
1001
|
+
rect.xTwips === undefined || frame.xTwips === undefined
|
|
1002
|
+
? rect.xTwips
|
|
1003
|
+
: rect.xTwips + frame.xTwips,
|
|
1004
|
+
yTwips:
|
|
1005
|
+
rect.yTwips === undefined || frame.yTwips === undefined
|
|
1006
|
+
? rect.yTwips
|
|
1007
|
+
: rect.yTwips + frame.yTwips,
|
|
1008
|
+
widthTwips: rect.widthTwips,
|
|
1009
|
+
heightTwips: rect.heightTwips,
|
|
1010
|
+
};
|
|
1011
|
+
}
|
|
1012
|
+
|
|
1013
|
+
function addFrameOriginToPoint(
|
|
1014
|
+
point: { readonly x?: number; readonly y?: number } | undefined,
|
|
1015
|
+
frame: AdjacentGeometryTwipsRect,
|
|
1016
|
+
): { readonly x?: number; readonly y?: number } | undefined {
|
|
1017
|
+
if (!point) return undefined;
|
|
1018
|
+
return {
|
|
1019
|
+
x:
|
|
1020
|
+
point.x === undefined || frame.xTwips === undefined
|
|
1021
|
+
? point.x
|
|
1022
|
+
: point.x + frame.xTwips,
|
|
1023
|
+
y:
|
|
1024
|
+
point.y === undefined || frame.yTwips === undefined
|
|
1025
|
+
? point.y
|
|
1026
|
+
: point.y + frame.yTwips,
|
|
1027
|
+
};
|
|
1028
|
+
}
|
|
1029
|
+
|
|
1030
|
+
function classifyPageIndex(
|
|
1031
|
+
normalizedWordPageIndex: number | undefined,
|
|
1032
|
+
runtimePageIndex: number | undefined,
|
|
1033
|
+
): AdjacentGeometryPageIndexStatus {
|
|
1034
|
+
if (normalizedWordPageIndex === undefined) return "word-page-missing";
|
|
1035
|
+
if (runtimePageIndex === undefined) return "runtime-missing";
|
|
1036
|
+
return normalizedWordPageIndex === runtimePageIndex
|
|
1037
|
+
? "matches-runtime"
|
|
1038
|
+
: "differs-from-runtime";
|
|
1039
|
+
}
|
|
1040
|
+
|
|
1041
|
+
function numberingRuntimeReadbackKey(
|
|
1042
|
+
docId: string | undefined,
|
|
1043
|
+
numberingKeyValue: string | undefined,
|
|
1044
|
+
numberingInstanceId: string | undefined,
|
|
1045
|
+
level: number | undefined,
|
|
1046
|
+
): string | undefined {
|
|
1047
|
+
return docId &&
|
|
1048
|
+
numberingKeyValue &&
|
|
1049
|
+
numberingInstanceId &&
|
|
1050
|
+
level !== undefined
|
|
1051
|
+
? `${docId}\0${numberingKeyValue}\0${numberingInstanceId}\0${level}`
|
|
1052
|
+
: undefined;
|
|
1053
|
+
}
|
|
1054
|
+
|
|
618
1055
|
function normalizeRects(raw: unknown): readonly AdjacentGeometryRect[] {
|
|
619
1056
|
if (Array.isArray(raw)) return raw.map(normalizeRect).filter(isRect);
|
|
620
1057
|
const maybeRect = normalizeRect(raw);
|