@claritylabs/cl-sdk 3.0.32 → 3.0.33
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 +123 -7
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +123 -7
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -2981,6 +2981,14 @@ function valueFromNode(node, value, confidence = "medium") {
|
|
|
2981
2981
|
sourceSpanIds: node.sourceSpanIds
|
|
2982
2982
|
};
|
|
2983
2983
|
}
|
|
2984
|
+
function valueFromNodes(nodes, value, confidence = "medium", normalizedValue) {
|
|
2985
|
+
return {
|
|
2986
|
+
value,
|
|
2987
|
+
...normalizedValue ? { normalizedValue } : {},
|
|
2988
|
+
confidence,
|
|
2989
|
+
...sourceIds(nodes)
|
|
2990
|
+
};
|
|
2991
|
+
}
|
|
2984
2992
|
function firstMatch(nodes, patterns) {
|
|
2985
2993
|
for (const node of nodes) {
|
|
2986
2994
|
const text = nodeText(node);
|
|
@@ -3057,8 +3065,65 @@ function cleanNamedInsured(value) {
|
|
|
3057
3065
|
}
|
|
3058
3066
|
return clean;
|
|
3059
3067
|
}
|
|
3068
|
+
var PARTY_LABEL_PATTERNS = {
|
|
3069
|
+
namedInsured: /^(?:item\s*\d+[.)]?\s*)?(?:named insured(?:\s+and\s+address)?|insured name)$/i,
|
|
3070
|
+
insurer: /^(?:carrier|insurer|security)$/i,
|
|
3071
|
+
broker: /^(?:broker(?:\s+of\s+record)?|producer|agent)$/i
|
|
3072
|
+
};
|
|
3073
|
+
function partyLabelKind(value) {
|
|
3074
|
+
const clean = cleanValue(value.replace(/^\s*column\s+\d+\s*:\s*/i, ""));
|
|
3075
|
+
if (!clean) return void 0;
|
|
3076
|
+
if (PARTY_LABEL_PATTERNS.namedInsured.test(clean)) return "namedInsured";
|
|
3077
|
+
if (PARTY_LABEL_PATTERNS.insurer.test(clean)) return "insurer";
|
|
3078
|
+
if (PARTY_LABEL_PATTERNS.broker.test(clean)) return "broker";
|
|
3079
|
+
return void 0;
|
|
3080
|
+
}
|
|
3081
|
+
function isRejectedPartyValue(value) {
|
|
3082
|
+
const clean = normalizeWhitespace3(value);
|
|
3083
|
+
return /^(?:and address|of record|insurer|carrier|security|broker|producer|agent|the|a|an|is|are|was|were|agrees?|means?|includes?|shall|will)\b/i.test(clean);
|
|
3084
|
+
}
|
|
3085
|
+
function identityWithoutAddress(value) {
|
|
3086
|
+
const clean = cleanValue(value.replace(/\b(?:phone|tel|telephone|email|e-mail)\b.*$/i, "").replace(/\b[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}\b.*$/i, ""));
|
|
3087
|
+
if (!clean) return void 0;
|
|
3088
|
+
const beforeStreet = clean.match(/^(.+?)\s+\d{1,6}\s+[A-Za-z0-9.'-]+(?:\s+[A-Za-z0-9.'-]+){0,5}\s+(?:street|st\.?|avenue|ave\.?|road|rd\.?|drive|dr\.?|lane|ln\.?|boulevard|blvd\.?|suite|ste\.?|floor|fl\.?|way|court|ct\.?)\b/i)?.[1];
|
|
3089
|
+
const beforeCityState = clean.match(/^(.+?)\s+[A-Z][A-Za-z.'-]+(?:\s+[A-Z][A-Za-z.'-]+)*,\s*[A-Z]{2}\s+\d{5}(?:-\d{4})?\b/)?.[1];
|
|
3090
|
+
return cleanValue(beforeStreet ?? beforeCityState ?? clean);
|
|
3091
|
+
}
|
|
3092
|
+
function cleanPartyIdentity(value, clean) {
|
|
3093
|
+
const raw = cleanValue(value);
|
|
3094
|
+
if (!raw || isRejectedPartyValue(raw)) return void 0;
|
|
3095
|
+
const identity = identityWithoutAddress(raw);
|
|
3096
|
+
const cleaned = identity ? clean(identity) : void 0;
|
|
3097
|
+
if (!cleaned || isRejectedPartyValue(cleaned)) return void 0;
|
|
3098
|
+
return {
|
|
3099
|
+
value: cleaned,
|
|
3100
|
+
...cleaned !== raw ? { normalizedValue: cleaned } : {}
|
|
3101
|
+
};
|
|
3102
|
+
}
|
|
3103
|
+
function partyFromTableRows(nodes, wanted, clean) {
|
|
3104
|
+
const children = childMap(nodes);
|
|
3105
|
+
for (const row of compactFactNodes(nodes).filter((node) => node.kind === "table_row")) {
|
|
3106
|
+
const cells = cellRows(row, children);
|
|
3107
|
+
for (const [index, cell] of cells.entries()) {
|
|
3108
|
+
const labelKind = partyLabelKind(cell.value) ?? partyLabelKind(cell.label);
|
|
3109
|
+
if (labelKind !== wanted) continue;
|
|
3110
|
+
const valueCell = cells.slice(index + 1).find((candidate) => !partyLabelKind(candidate.value) && !partyLabelKind(candidate.label));
|
|
3111
|
+
if (!valueCell) continue;
|
|
3112
|
+
const cleaned = cleanPartyIdentity(valueCell.value, clean);
|
|
3113
|
+
if (cleaned) return valueFromNodes([row, valueCell.node], cleaned.value, "high", cleaned.normalizedValue);
|
|
3114
|
+
}
|
|
3115
|
+
const parts = normalizeWhitespace3(row.textExcerpt ?? row.description ?? nodeText(row)).split(/\s+\|\s+|\t/).map(cleanValue).filter((part) => Boolean(part));
|
|
3116
|
+
for (const [index, part] of parts.entries()) {
|
|
3117
|
+
const labelKind = partyLabelKind(part);
|
|
3118
|
+
if (labelKind !== wanted) continue;
|
|
3119
|
+
const cleaned = cleanPartyIdentity(parts[index + 1] ?? "", clean);
|
|
3120
|
+
if (cleaned) return valueFromNodes([row], cleaned.value, "high", cleaned.normalizedValue);
|
|
3121
|
+
}
|
|
3122
|
+
}
|
|
3123
|
+
return void 0;
|
|
3124
|
+
}
|
|
3060
3125
|
function namedInsuredFromNodes(nodes) {
|
|
3061
|
-
return firstCleanMatch(nodes, [
|
|
3126
|
+
return partyFromTableRows(nodes, "namedInsured", cleanNamedInsured) ?? firstCleanMatch(nodes, [
|
|
3062
3127
|
/\b(?:named insured|insured name)\s*:?\s*(.+?)(?=\s+(?:insurance amount|benefit amount|policy number|policy date|owner|beneficiary|premium|coverage|risk classification|date this)\b|[|;\n]|$)/i,
|
|
3063
3128
|
/\b(?:insured persons?|insured person)\s*:\s*(.+?)(?=\s+(?:insurance amount|benefit amount|policy number|policy date|owner|beneficiary|premium|coverage|risk classification|date this)\b|[|;\n]|$)/i,
|
|
3064
3129
|
/\b(?:applicant|policyholder)\s*:?\s*(.+?)(?=\s+(?:coverage|policy number|insurer|carrier|premium|effective|expiration)\b|[|;\n]|$)/i
|
|
@@ -3067,12 +3132,19 @@ function namedInsuredFromNodes(nodes) {
|
|
|
3067
3132
|
function cleanInsurer(value) {
|
|
3068
3133
|
const clean = cleanValue(value);
|
|
3069
3134
|
if (!clean || clean.length > 140) return void 0;
|
|
3070
|
-
if (/^(mean|means|we|us|our)\b/i.test(clean)) return void 0;
|
|
3135
|
+
if (/^(mean|means|we|us|our|the|a|an|agrees?|shall|will)\b/i.test(clean)) return void 0;
|
|
3071
3136
|
if (/\b(table of contents|policy wording|provided solely|convenience)\b/i.test(clean)) return void 0;
|
|
3072
3137
|
const known = clean.match(/\b(Sun Life Assurance Company of Canada|Manulife|The Manufacturers Life Insurance Company)\b/i)?.[1];
|
|
3073
3138
|
return known ?? clean;
|
|
3074
3139
|
}
|
|
3075
3140
|
function insurerFromNodes(nodes) {
|
|
3141
|
+
const tableValue = partyFromTableRows(nodes, "insurer", cleanInsurer);
|
|
3142
|
+
if (tableValue) return tableValue;
|
|
3143
|
+
for (const node of compactFactNodes(nodes)) {
|
|
3144
|
+
const text = nodeText(node);
|
|
3145
|
+
const value = cleanInsurer(text.match(/\b([A-Z][A-Za-z&.,' -]{2,120}?(?:Insurance|Assurance|Indemnity|Casualty|Underwriting|Mutual|Risk|Reinsurance)\s+Company(?:\s+of\s+[A-Z][A-Za-z .'-]+)?)\s*\(\s*the\s+["']?Insurer["']?\s*\)/i)?.[1] ?? "");
|
|
3146
|
+
if (value) return valueFromNode(node, value, "high");
|
|
3147
|
+
}
|
|
3076
3148
|
return firstCleanMatch(nodes, [
|
|
3077
3149
|
/\bunderwritten by\s+([^|;\n.]{3,160})/i,
|
|
3078
3150
|
/\b(?:insurer|carrier|company|security)\s*:?\s*([^|;\n]{3,120})/i,
|
|
@@ -3118,6 +3190,19 @@ function coverageNameFromRow(text) {
|
|
|
3118
3190
|
);
|
|
3119
3191
|
return cleanCoverageLabel(first);
|
|
3120
3192
|
}
|
|
3193
|
+
function isDeclarationLimitLabel(value) {
|
|
3194
|
+
const label = normalizeLabel(value);
|
|
3195
|
+
return /\bitem\s*\d+[.)]?\s*limits?\s+of\s+liability\b/.test(label) || /^limits?\s+of\s+liability$/.test(label) || /^policy\s+limits?$/.test(label);
|
|
3196
|
+
}
|
|
3197
|
+
function declarationCoverageNameFromRow(row, children) {
|
|
3198
|
+
const cells = cellRows(row, children);
|
|
3199
|
+
const candidates = [
|
|
3200
|
+
row.title,
|
|
3201
|
+
...cells.flatMap((cell) => [cell.label, cell.value])
|
|
3202
|
+
];
|
|
3203
|
+
if (!candidates.some(isDeclarationLimitLabel)) return void 0;
|
|
3204
|
+
return candidates.some((candidate) => /\blimits?\s+of\s+liability\b/i.test(candidate ?? "")) ? "Limits of Liability" : "Policy Limits";
|
|
3205
|
+
}
|
|
3121
3206
|
function limitFromText(text) {
|
|
3122
3207
|
return moneyValue(
|
|
3123
3208
|
text.match(/\b(?:limit|liability|aggregate|occurrence|claim)\s*:?\s*(\$?\d[\d,]*(?:\.\d{2})?|\$?\d[\d,]*\s*(?:each|per|aggregate)[^|;]*)/i)?.[1] ?? text.match(/(\$\s?\d[\d,]*(?:\.\d{2})?)(?=.*\b(limit|aggregate|occurrence|claim|liability)\b)/i)?.[1]
|
|
@@ -3137,7 +3222,12 @@ function premiumFromNodes(nodes) {
|
|
|
3137
3222
|
return void 0;
|
|
3138
3223
|
}
|
|
3139
3224
|
function moneyAmount(value) {
|
|
3140
|
-
const
|
|
3225
|
+
const clean = cleanValue(value);
|
|
3226
|
+
if (!clean) return void 0;
|
|
3227
|
+
const currency = clean.match(/\$\s*([0-9][0-9,]*(?:\.\d+)?)/);
|
|
3228
|
+
const percent = clean.match(/\b([0-9][0-9,]*(?:\.\d+)?)\s*%/);
|
|
3229
|
+
const explicitNumeric = !/\bitem\s*\d+\b/i.test(clean) && /\b(?:limit|aggregate|claim|occurrence|loss|retention|deductible|sir|premium|amount)\b/i.test(clean) ? clean.match(/\b([0-9][0-9,]*(?:\.\d+)?)\b/) : void 0;
|
|
3230
|
+
const match = currency ?? percent ?? explicitNumeric;
|
|
3141
3231
|
if (!match) return void 0;
|
|
3142
3232
|
const amount = Number(match[1].replace(/,/g, ""));
|
|
3143
3233
|
return Number.isFinite(amount) ? amount : void 0;
|
|
@@ -3183,6 +3273,10 @@ function isValueCell(label, value) {
|
|
|
3183
3273
|
}
|
|
3184
3274
|
return /\b(limit|aggregate|retention|deductible|sir|retroactive|premium|amount)\b/.test(normalizedLabel) || moneyAmount(value) !== void 0 || /\b(full prior acts|none|included|not included|as stated)\b/.test(normalizedValue);
|
|
3185
3275
|
}
|
|
3276
|
+
function isCoverageTermLabel(value) {
|
|
3277
|
+
const label = normalizeLabel(value);
|
|
3278
|
+
return /\b(limit|aggregate|retention|deductible|sir|retroactive|premium|amount|sub[-\s]?limit)\b/.test(label);
|
|
3279
|
+
}
|
|
3186
3280
|
function isNameCell(label, value) {
|
|
3187
3281
|
const normalizedLabel = normalizeLabel(label);
|
|
3188
3282
|
const normalizedValue = normalizeLabel(value);
|
|
@@ -3284,6 +3378,16 @@ function termFromCell(params) {
|
|
|
3284
3378
|
function termsFromRow(row, children) {
|
|
3285
3379
|
const cells = cellRows(row, children);
|
|
3286
3380
|
if (cells.length > 0) {
|
|
3381
|
+
const pairedTerms = [];
|
|
3382
|
+
for (const [index, cell] of cells.entries()) {
|
|
3383
|
+
const next = cells[index + 1];
|
|
3384
|
+
if (!next) continue;
|
|
3385
|
+
if (!isCoverageTermLabel(cell.value)) continue;
|
|
3386
|
+
if (isCoverageTermLabel(next.value) && moneyAmount(next.value) === void 0) continue;
|
|
3387
|
+
const term = termFromCell({ row, cell: next.node, label: cell.value, value: next.value });
|
|
3388
|
+
if (term) pairedTerms.push(term);
|
|
3389
|
+
}
|
|
3390
|
+
if (pairedTerms.length > 0) return pairedTerms;
|
|
3287
3391
|
return cells.filter((cell) => isValueCell(cell.label, cell.value)).map((cell) => termFromCell({ row, cell: cell.node, label: cell.label, value: cell.value })).filter((term) => Boolean(term));
|
|
3288
3392
|
}
|
|
3289
3393
|
const text = normalizeWhitespace3(row.textExcerpt ?? row.description ?? nodeText(row));
|
|
@@ -3310,6 +3414,8 @@ function termsFromRow(row, children) {
|
|
|
3310
3414
|
return terms;
|
|
3311
3415
|
}
|
|
3312
3416
|
function nameFromRow(row, children) {
|
|
3417
|
+
const declarationName = declarationCoverageNameFromRow(row, children);
|
|
3418
|
+
if (declarationName) return declarationName;
|
|
3313
3419
|
const cells = cellRows(row, children);
|
|
3314
3420
|
const named = cells.find((cell) => isNameCell(cell.label, cell.value));
|
|
3315
3421
|
if (named) return cleanValue(named.value);
|
|
@@ -3487,7 +3593,7 @@ function buildParties(profile) {
|
|
|
3487
3593
|
if (profile.namedInsured) {
|
|
3488
3594
|
parties.push({
|
|
3489
3595
|
role: "named_insured",
|
|
3490
|
-
name: profile.namedInsured.value,
|
|
3596
|
+
name: profile.namedInsured.normalizedValue ?? profile.namedInsured.value,
|
|
3491
3597
|
sourceNodeIds: profile.namedInsured.sourceNodeIds,
|
|
3492
3598
|
sourceSpanIds: profile.namedInsured.sourceSpanIds
|
|
3493
3599
|
});
|
|
@@ -3495,7 +3601,7 @@ function buildParties(profile) {
|
|
|
3495
3601
|
if (profile.insurer) {
|
|
3496
3602
|
parties.push({
|
|
3497
3603
|
role: "insurer",
|
|
3498
|
-
name: profile.insurer.value,
|
|
3604
|
+
name: profile.insurer.normalizedValue ?? profile.insurer.value,
|
|
3499
3605
|
sourceNodeIds: profile.insurer.sourceNodeIds,
|
|
3500
3606
|
sourceSpanIds: profile.insurer.sourceSpanIds
|
|
3501
3607
|
});
|
|
@@ -3503,7 +3609,7 @@ function buildParties(profile) {
|
|
|
3503
3609
|
if (profile.broker) {
|
|
3504
3610
|
parties.push({
|
|
3505
3611
|
role: "broker",
|
|
3506
|
-
name: profile.broker.value,
|
|
3612
|
+
name: profile.broker.normalizedValue ?? profile.broker.value,
|
|
3507
3613
|
sourceNodeIds: profile.broker.sourceNodeIds,
|
|
3508
3614
|
sourceSpanIds: profile.broker.sourceSpanIds
|
|
3509
3615
|
});
|
|
@@ -10948,9 +11054,19 @@ function sourceTreeToOutline(sourceTree) {
|
|
|
10948
11054
|
});
|
|
10949
11055
|
return (byParent.get(root?.id) ?? []).map(visit);
|
|
10950
11056
|
}
|
|
11057
|
+
var NORMALIZED_COMPATIBILITY_FIELDS = /* @__PURE__ */ new Set([
|
|
11058
|
+
"policyNumber",
|
|
11059
|
+
"namedInsured",
|
|
11060
|
+
"insurer",
|
|
11061
|
+
"broker"
|
|
11062
|
+
]);
|
|
10951
11063
|
function valueOf(profile, key) {
|
|
10952
11064
|
const value = profile[key];
|
|
10953
|
-
|
|
11065
|
+
if (!value || typeof value !== "object" || Array.isArray(value) || !("value" in value)) return void 0;
|
|
11066
|
+
if (NORMALIZED_COMPATIBILITY_FIELDS.has(key) && "normalizedValue" in value && typeof value.normalizedValue === "string" && value.normalizedValue.trim()) {
|
|
11067
|
+
return value.normalizedValue;
|
|
11068
|
+
}
|
|
11069
|
+
return String(value.value);
|
|
10954
11070
|
}
|
|
10955
11071
|
function materializeDocument(params) {
|
|
10956
11072
|
const profile = params.operationalProfile;
|