@claritylabs/cl-sdk 3.1.11 → 3.1.13

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/index.js CHANGED
@@ -11256,7 +11256,7 @@ function appendDistinctText(base, addition) {
11256
11256
  if (!current) return next || void 0;
11257
11257
  if (!next) return current;
11258
11258
  if (current.toLowerCase().includes(next.toLowerCase())) return current;
11259
- const delimiter = /(?:[/(:;-]|,\s*)$/.test(current) ? " " : " / ";
11259
+ const delimiter = /(?:[/(:;-]|,\s*)$/.test(current) || /^[a-z]+$/i.test(next) ? " " : " / ";
11260
11260
  return cleanText(`${current}${delimiter}${next}`, current);
11261
11261
  }
11262
11262
  function mergedBbox(nodes) {
@@ -11285,12 +11285,65 @@ function findCellForContinuation(params) {
11285
11285
  }
11286
11286
  return params.cells[1] ?? params.cells[params.cells.length - 1];
11287
11287
  }
11288
+ function bboxCenterX(node) {
11289
+ const box = node.bbox?.[0];
11290
+ if (!box) return void 0;
11291
+ return box.x + box.width / 2;
11292
+ }
11293
+ function findCellByVisualPosition(sourceCell, targetCells) {
11294
+ const sourceX = bboxCenterX(sourceCell);
11295
+ if (sourceX === void 0) return void 0;
11296
+ const positioned = targetCells.map((cell) => ({ cell, centerX: bboxCenterX(cell) })).filter(
11297
+ (entry) => entry.centerX !== void 0
11298
+ );
11299
+ if (positioned.length === 0) return void 0;
11300
+ positioned.sort(
11301
+ (left, right) => Math.abs(left.centerX - sourceX) - Math.abs(right.centerX - sourceX)
11302
+ );
11303
+ return positioned[0]?.cell;
11304
+ }
11288
11305
  function columnLabelStartIndex(rows) {
11289
11306
  const headerIndex = rows.findIndex(
11290
11307
  ({ row, cells }) => isSourceTreeHeaderRow(row) && cells.length > 1
11291
11308
  );
11292
11309
  return headerIndex >= 0 ? headerIndex : 0;
11293
11310
  }
11311
+ function startsNewVisualTableItem(cells) {
11312
+ const firstText = tableCellText(cells[0]);
11313
+ return /^(?:item\s+\d+\b|[A-Z][.)]\s+|coverage\s+part\b|endorsement\s+(?:no\.?|number|#|\d+)\b)/i.test(firstText);
11314
+ }
11315
+ function rowMatchesColumnLabels(cells, columnLabels) {
11316
+ if (columnLabels.size === 0 || cells.length < columnLabels.size) return false;
11317
+ return cells.every((cell, index) => {
11318
+ const label = columnLabels.get(tableCellColumnIndex(cell, index));
11319
+ return !label || tableCellText(cell).toLowerCase() === label.toLowerCase();
11320
+ });
11321
+ }
11322
+ function implicitContinuationRows(rows, columnLabels, firstLabelRowIndex) {
11323
+ const continuations = [];
11324
+ let targetRowId;
11325
+ const targetColumnLabel = columnLabels.get(1);
11326
+ for (const [rowIndex, { row, cells }] of rows.entries()) {
11327
+ if (rowIndex < firstLabelRowIndex) continue;
11328
+ if (rowIndex === firstLabelRowIndex && rowMatchesColumnLabels(cells, columnLabels)) continue;
11329
+ if (startsNewVisualTableItem(cells)) {
11330
+ targetRowId = row.id;
11331
+ continue;
11332
+ }
11333
+ if (!targetRowId || cells.length === 0) continue;
11334
+ const isSpuriousHeader = isSourceTreeHeaderRow(row) && !rowMatchesColumnLabels(cells, columnLabels);
11335
+ const isShortContinuation = !isSourceTreeHeaderRow(row) && cells.length < Math.max(2, columnLabels.size);
11336
+ if (!isSpuriousHeader && !isShortContinuation) continue;
11337
+ continuations.push({
11338
+ sourceRowNodeId: row.id,
11339
+ targetRowNodeId: targetRowId,
11340
+ targetColumnIndex: 1,
11341
+ targetColumnLabel,
11342
+ reason: "Continuation row inferred from repaired table header."
11343
+ });
11344
+ }
11345
+ return continuations;
11346
+ }
11294
11347
  function metadataWithColumnLabel(metadata, label) {
11295
11348
  const next = {
11296
11349
  ...metadata ?? {},
@@ -11331,8 +11384,8 @@ function applyVisualTableRepair(sourceTree, repair) {
11331
11384
  const normalized = normalizedRepairLabel(label.label);
11332
11385
  if (normalized) columnLabels.set(label.columnIndex, normalized);
11333
11386
  }
11387
+ const firstLabelRowIndex = columnLabelStartIndex(rows);
11334
11388
  if (columnLabels.size > 0) {
11335
- const firstLabelRowIndex = columnLabelStartIndex(rows);
11336
11389
  const normalizedLabels = new Set([...columnLabels.values()].map((label) => label.toLowerCase()));
11337
11390
  for (const [rowIndex, { row, cells }] of rows.entries()) {
11338
11391
  if (removeIds.has(row.id)) continue;
@@ -11370,7 +11423,15 @@ function applyVisualTableRepair(sourceTree, repair) {
11370
11423
  if (cells.length > 0) rowsToRebuildText.add(row.id);
11371
11424
  }
11372
11425
  }
11373
- for (const continuation of tableRepair.continuationRows) {
11426
+ const continuationRows = [
11427
+ ...tableRepair.continuationRows,
11428
+ ...implicitContinuationRows(rows, columnLabels, firstLabelRowIndex)
11429
+ ];
11430
+ const seenContinuationRows = /* @__PURE__ */ new Set();
11431
+ for (const continuation of continuationRows) {
11432
+ const continuationKey = `${continuation.sourceRowNodeId}:${continuation.targetRowNodeId}`;
11433
+ if (seenContinuationRows.has(continuationKey)) continue;
11434
+ seenContinuationRows.add(continuationKey);
11374
11435
  if (!rowIds.has(continuation.sourceRowNodeId) || !rowIds.has(continuation.targetRowNodeId)) continue;
11375
11436
  if (continuation.sourceRowNodeId === continuation.targetRowNodeId) continue;
11376
11437
  const sourceIndex = rowOrder.get(continuation.sourceRowNodeId);
@@ -11392,7 +11453,41 @@ function applyVisualTableRepair(sourceTree, repair) {
11392
11453
  });
11393
11454
  const sourceNodes = [sourceRow, ...sourceCells];
11394
11455
  const sourceSpanIds = sourceSpanIdsForNodes(sourceNodes);
11395
- if (targetCell) {
11456
+ let mergedIntoCells = false;
11457
+ if (sourceCells.length > 0 && targetCells.length > 0) {
11458
+ for (const sourceCell of sourceCells) {
11459
+ const cellText = tableCellValueText(sourceCell);
11460
+ if (!cellText) continue;
11461
+ const visualTargetCell = findCellByVisualPosition(sourceCell, targetCells) ?? targetCell;
11462
+ if (!visualTargetCell) continue;
11463
+ const currentTargetCell = currentNode(visualTargetCell.id) ?? visualTargetCell;
11464
+ const nextCellText = appendDistinctText(tableCellText(currentTargetCell), cellText);
11465
+ if (!nextCellText) continue;
11466
+ updates.set(visualTargetCell.id, {
11467
+ ...currentTargetCell,
11468
+ textExcerpt: nextCellText,
11469
+ description: cleanText(
11470
+ [currentTargetCell.title, nextCellText].filter(Boolean).join(" | "),
11471
+ currentTargetCell.description
11472
+ ),
11473
+ sourceSpanIds: [
11474
+ .../* @__PURE__ */ new Set([
11475
+ ...currentTargetCell.sourceSpanIds,
11476
+ ...sourceRow.sourceSpanIds,
11477
+ ...sourceCell.sourceSpanIds
11478
+ ])
11479
+ ],
11480
+ bbox: mergedBbox([currentTargetCell, sourceCell]),
11481
+ metadata: {
11482
+ ...currentTargetCell.metadata ?? {},
11483
+ visualTableRepair: "merged_continuation"
11484
+ }
11485
+ });
11486
+ mergedIntoCells = true;
11487
+ }
11488
+ if (mergedIntoCells) rowsToRebuildText.add(targetRow.id);
11489
+ }
11490
+ if (!mergedIntoCells && targetCell) {
11396
11491
  const nextCellText = appendDistinctText(tableCellText(targetCell), sourceText);
11397
11492
  if (nextCellText) {
11398
11493
  const mergedNodes = [targetCell, ...sourceNodes];
@@ -11410,11 +11505,16 @@ function applyVisualTableRepair(sourceTree, repair) {
11410
11505
  rowsToRebuildText.add(targetRow.id);
11411
11506
  }
11412
11507
  }
11413
- const nextRowText = appendDistinctText(targetRow.textExcerpt ?? targetRow.description, sourceText);
11508
+ const fallbackRowText = mergedIntoCells ? void 0 : appendDistinctText(targetRow.textExcerpt ?? targetRow.description, sourceText);
11414
11509
  updates.set(targetRow.id, {
11415
11510
  ...currentNode(targetRow.id) ?? targetRow,
11416
- textExcerpt: nextRowText,
11417
- description: cleanText([targetRow.title, nextRowText].filter(Boolean).join(" | "), targetRow.description),
11511
+ ...mergedIntoCells ? {} : {
11512
+ textExcerpt: fallbackRowText,
11513
+ description: cleanText(
11514
+ [targetRow.title, fallbackRowText].filter(Boolean).join(" | "),
11515
+ targetRow.description
11516
+ )
11517
+ },
11418
11518
  sourceSpanIds: [.../* @__PURE__ */ new Set([...targetRow.sourceSpanIds, ...sourceSpanIds])],
11419
11519
  bbox: mergedBbox([targetRow, ...sourceNodes]),
11420
11520
  metadata: {