@claritylabs/cl-sdk 3.0.8 → 3.0.9

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.mjs CHANGED
@@ -9101,6 +9101,12 @@ function looksLikeEndorsementStart(node) {
9101
9101
  if (/^endorsement\s+(?:no\.?|number|#)\s*[A-Z0-9][A-Z0-9.-]*\b/i.test(start)) return true;
9102
9102
  return /^endorsement\s+(?:no\.?|number|#)\s*[A-Z0-9][A-Z0-9.-]*\b/i.test(title) && /\bthis endorsement changes the policy\b/i.test(body);
9103
9103
  }
9104
+ function looksLikeEndorsementContinuation(node) {
9105
+ if (looksLikeEndorsementStart(node)) return false;
9106
+ const title = cleanText(node.title, "");
9107
+ const text = sourceNodeText(node);
9108
+ return /\bendorsement\b/i.test(text) || /\bcontinuation\b/i.test(title) || /\ball\s+other\s+terms\s+and\s+conditions\b/i.test(text);
9109
+ }
9104
9110
  function endorsementStartTitle(node) {
9105
9111
  return looksLikeEndorsementStart(node) ? endorsementTitle(sourceNodeText(node)) : void 0;
9106
9112
  }
@@ -9261,6 +9267,124 @@ function endorsementGroupNodeId(documentId, parentId) {
9261
9267
  parentId?.replace(/[^a-zA-Z0-9_.:-]/g, "_").slice(0, 48) ?? "root"
9262
9268
  ].join(":");
9263
9269
  }
9270
+ function isPolicyFormNode(node) {
9271
+ return node.title === "Policy Form" && (node.kind === "form" || node.kind === "page_group");
9272
+ }
9273
+ function isDeclarationsNode(node) {
9274
+ return node.kind === "page_group" && node.title === "Declarations";
9275
+ }
9276
+ function normalizePolicyFormStructure(sourceTree) {
9277
+ let nextTree = sourceTree;
9278
+ const byParent = nodesByParent(nextTree);
9279
+ const nodesToRemove = /* @__PURE__ */ new Set();
9280
+ for (const form of nextTree.filter((node) => node.kind === "form" && node.title === "Policy Form")) {
9281
+ const children = byParent.get(form.id) ?? [];
9282
+ const declarationsChildren = children.filter(isDeclarationsNode);
9283
+ const nestedPolicyForm = children.find((child) => child.id !== form.id && isPolicyFormNode(child));
9284
+ if (declarationsChildren.length === 0 && !nestedPolicyForm) continue;
9285
+ const declarationIds = new Set(declarationsChildren.map((child) => child.id));
9286
+ nextTree = nextTree.map((node) => {
9287
+ if (declarationIds.has(node.id)) {
9288
+ return {
9289
+ ...node,
9290
+ parentId: form.parentId,
9291
+ metadata: {
9292
+ ...node.metadata,
9293
+ organizerRepair: "promote_declarations_from_policy_form"
9294
+ }
9295
+ };
9296
+ }
9297
+ if (nestedPolicyForm && node.parentId === nestedPolicyForm.id) {
9298
+ return {
9299
+ ...node,
9300
+ parentId: form.id,
9301
+ metadata: {
9302
+ ...node.metadata,
9303
+ organizerRepair: "collapse_nested_policy_form"
9304
+ }
9305
+ };
9306
+ }
9307
+ return node;
9308
+ });
9309
+ if (nestedPolicyForm) nodesToRemove.add(nestedPolicyForm.id);
9310
+ }
9311
+ if (nodesToRemove.size > 0) {
9312
+ nextTree = nextTree.filter((node) => !nodesToRemove.has(node.id));
9313
+ }
9314
+ return nextTree;
9315
+ }
9316
+ function nestEndorsementContinuationPages(sourceTree) {
9317
+ const byParent = nodesByParent(sourceTree);
9318
+ const continuationParentById = /* @__PURE__ */ new Map();
9319
+ for (const group of sourceTree.filter(isEndorsementGroup)) {
9320
+ const children = byParent.get(group.id) ?? [];
9321
+ let currentEndorsement;
9322
+ for (const child of children) {
9323
+ if (child.kind === "endorsement" && endorsementStartTitle(child)) {
9324
+ currentEndorsement = child;
9325
+ continue;
9326
+ }
9327
+ if (!currentEndorsement || child.kind !== "page") continue;
9328
+ continuationParentById.set(child.id, currentEndorsement.id);
9329
+ }
9330
+ }
9331
+ if (continuationParentById.size === 0) return sourceTree;
9332
+ return sourceTree.map((node) => {
9333
+ const parentId = continuationParentById.get(node.id);
9334
+ if (!parentId) return node;
9335
+ return {
9336
+ ...node,
9337
+ parentId,
9338
+ metadata: {
9339
+ ...node.metadata,
9340
+ organizerRepair: "nest_endorsement_continuation"
9341
+ }
9342
+ };
9343
+ });
9344
+ }
9345
+ function nodeDepth(node) {
9346
+ return node.path ? node.path.split("/").filter(Boolean).length : 0;
9347
+ }
9348
+ function shouldUseOwnEvidenceForContainer(node) {
9349
+ return node.kind === "endorsement" || node.kind === "page" || node.kind === "table" || node.kind === "table_row" || node.kind === "table_cell" || node.kind === "text";
9350
+ }
9351
+ function normalizeContainerEvidenceFromChildren(sourceTree) {
9352
+ const byParent = nodesByParent(sourceTree);
9353
+ const byId = new Map(sourceTree.map((node) => [node.id, node]));
9354
+ const sorted = [...sourceTree].sort((left, right) => nodeDepth(right) - nodeDepth(left));
9355
+ for (const originalNode of sorted) {
9356
+ const children = (byParent.get(originalNode.id) ?? []).map((child) => byId.get(child.id)).filter((child) => Boolean(child));
9357
+ if (children.length === 0) continue;
9358
+ const currentNode = byId.get(originalNode.id) ?? originalNode;
9359
+ const evidenceNodes = shouldUseOwnEvidenceForContainer(currentNode) ? [currentNode, ...children] : children;
9360
+ const pageStarts = evidenceNodes.map((node) => node.pageStart).filter((page) => typeof page === "number");
9361
+ const pageEnds = evidenceNodes.map((node) => node.pageEnd ?? node.pageStart).filter((page) => typeof page === "number");
9362
+ const sourceSpanIds = [...new Set(evidenceNodes.flatMap((node) => node.sourceSpanIds))];
9363
+ const bbox = evidenceNodes.flatMap((node) => node.bbox ?? []).slice(0, 12);
9364
+ const childText = children.map((child) => child.textExcerpt ?? child.description).filter(Boolean).join("\n\n").slice(0, 1600);
9365
+ byId.set(currentNode.id, {
9366
+ ...currentNode,
9367
+ sourceSpanIds,
9368
+ pageStart: pageStarts.length ? Math.min(...pageStarts) : currentNode.pageStart,
9369
+ pageEnd: pageEnds.length ? Math.max(...pageEnds) : currentNode.pageEnd,
9370
+ bbox,
9371
+ order: Math.min(currentNode.order, ...children.map((child) => child.order)),
9372
+ textExcerpt: shouldUseOwnEvidenceForContainer(currentNode) ? currentNode.textExcerpt : childText || currentNode.textExcerpt
9373
+ });
9374
+ }
9375
+ return sourceTree.map((node) => byId.get(node.id) ?? node);
9376
+ }
9377
+ function normalizeSemanticHierarchy(sourceTree) {
9378
+ return normalizeDocumentSourceTreePaths(
9379
+ normalizeContainerEvidenceFromChildren(
9380
+ nestEndorsementContinuationPages(
9381
+ normalizePolicyFormStructure(
9382
+ normalizeDocumentSourceTreePaths(sourceTree)
9383
+ )
9384
+ )
9385
+ )
9386
+ );
9387
+ }
9264
9388
  function applyEndorsementGrouping(sourceTree) {
9265
9389
  const relabeledTree = sourceTree.map((node) => {
9266
9390
  if (node.kind === "document" || isEndorsementGroup(node)) return node;
@@ -9335,9 +9459,21 @@ function applyEndorsementGrouping(sourceTree) {
9335
9459
  if (endorsementGroupIds.has(parentId ?? "")) continue;
9336
9460
  const endorsementChildren = children.filter((child) => child.kind === "endorsement" && !isEndorsementGroup(child));
9337
9461
  if (endorsementChildren.length < 2) continue;
9462
+ const endorsementGroupChildren = [];
9463
+ let hasSeenEndorsementStart = false;
9464
+ for (const child of children) {
9465
+ if (child.kind === "endorsement" && !isEndorsementGroup(child)) {
9466
+ hasSeenEndorsementStart = true;
9467
+ endorsementGroupChildren.push(child);
9468
+ continue;
9469
+ }
9470
+ if (hasSeenEndorsementStart && child.kind === "page" && looksLikeEndorsementContinuation(child)) {
9471
+ endorsementGroupChildren.push(child);
9472
+ }
9473
+ }
9338
9474
  const documentId = endorsementChildren[0].documentId;
9339
- const pageStarts = endorsementChildren.map((child) => child.pageStart).filter((page) => typeof page === "number");
9340
- const pageEnds = endorsementChildren.map((child) => child.pageEnd ?? child.pageStart).filter((page) => typeof page === "number");
9475
+ const pageStarts = endorsementGroupChildren.map((child) => child.pageStart).filter((page) => typeof page === "number");
9476
+ const pageEnds = endorsementGroupChildren.map((child) => child.pageEnd ?? child.pageStart).filter((page) => typeof page === "number");
9341
9477
  const order = Math.min(...endorsementChildren.map((child) => child.order));
9342
9478
  const existingGroup = groupsByParent.get(parentId);
9343
9479
  const groupId = existingGroup?.id ?? endorsementGroupNodeId(documentId, parentId);
@@ -9352,12 +9488,12 @@ function applyEndorsementGrouping(sourceTree) {
9352
9488
  sourceSpanIds: [],
9353
9489
  pageStart: pageStarts.length ? Math.min(...pageStarts) : void 0,
9354
9490
  pageEnd: pageEnds.length ? Math.max(...pageEnds) : void 0,
9355
- bbox: endorsementChildren.flatMap((child) => child.bbox ?? []).slice(0, 12),
9491
+ bbox: endorsementGroupChildren.flatMap((child) => child.bbox ?? []).slice(0, 12),
9356
9492
  order,
9357
9493
  path: "",
9358
9494
  metadata: { sourceTreeVersion: "v3", organizer: "endorsement_grouping" }
9359
9495
  };
9360
- const childSpanIds = [...new Set(endorsementChildren.flatMap((child) => child.sourceSpanIds))];
9496
+ const childSpanIds = [...new Set(endorsementGroupChildren.flatMap((child) => child.sourceSpanIds))];
9361
9497
  const normalizedGroup = {
9362
9498
  ...groupNode,
9363
9499
  sourceSpanIds: groupNode.sourceSpanIds.length ? groupNode.sourceSpanIds : childSpanIds,
@@ -9368,11 +9504,12 @@ function applyEndorsementGrouping(sourceTree) {
9368
9504
  groupsByParent.set(parentId, normalizedGroup);
9369
9505
  if (!existingGroup) nextTree.push(normalizedGroup);
9370
9506
  else nextTree = nextTree.map((node) => node.id === normalizedGroup.id ? normalizedGroup : node);
9507
+ const endorsementGroupChildIds = new Set(endorsementGroupChildren.map((child) => child.id));
9371
9508
  nextTree = nextTree.map(
9372
- (node) => endorsementChildren.some((child) => child.id === node.id) ? { ...node, parentId: groupId, order: node.order + 1e-3 } : node
9509
+ (node) => endorsementGroupChildIds.has(node.id) ? { ...node, parentId: groupId, order: node.order + 1e-3 } : node
9373
9510
  );
9374
9511
  }
9375
- return normalizeDocumentSourceTreePaths(nextTree);
9512
+ return normalizeSemanticHierarchy(nextTree);
9376
9513
  }
9377
9514
  function compactNode(node, maxText = 700) {
9378
9515
  return {