@mikashboks/capture-intelligence-core 0.1.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.
Files changed (89) hide show
  1. package/dist/cjs/__fixtures__/address-flow.fixtures.d.ts +35 -0
  2. package/dist/cjs/__fixtures__/address-flow.fixtures.d.ts.map +1 -0
  3. package/dist/cjs/__fixtures__/address-flow.fixtures.js +186 -0
  4. package/dist/cjs/__fixtures__/address-flow.fixtures.js.map +1 -0
  5. package/dist/cjs/__fixtures__/metadata-review.fixtures.d.ts +11 -0
  6. package/dist/cjs/__fixtures__/metadata-review.fixtures.d.ts.map +1 -0
  7. package/dist/cjs/__fixtures__/metadata-review.fixtures.js +69 -0
  8. package/dist/cjs/__fixtures__/metadata-review.fixtures.js.map +1 -0
  9. package/dist/cjs/address-proof.d.ts +33 -0
  10. package/dist/cjs/address-proof.d.ts.map +1 -0
  11. package/dist/cjs/address-proof.js +97 -0
  12. package/dist/cjs/address-proof.js.map +1 -0
  13. package/dist/cjs/document-classifier.d.ts +19 -0
  14. package/dist/cjs/document-classifier.d.ts.map +1 -0
  15. package/dist/cjs/document-classifier.js +213 -0
  16. package/dist/cjs/document-classifier.js.map +1 -0
  17. package/dist/cjs/flow-routing.d.ts +7 -0
  18. package/dist/cjs/flow-routing.d.ts.map +1 -0
  19. package/dist/cjs/flow-routing.js +45 -0
  20. package/dist/cjs/flow-routing.js.map +1 -0
  21. package/dist/cjs/index.d.ts +25 -0
  22. package/dist/cjs/index.d.ts.map +1 -0
  23. package/dist/cjs/index.js +83 -0
  24. package/dist/cjs/index.js.map +1 -0
  25. package/dist/cjs/metadata-review.d.ts +10 -0
  26. package/dist/cjs/metadata-review.d.ts.map +1 -0
  27. package/dist/cjs/metadata-review.js +93 -0
  28. package/dist/cjs/metadata-review.js.map +1 -0
  29. package/dist/cjs/metrics.d.ts +115 -0
  30. package/dist/cjs/metrics.d.ts.map +1 -0
  31. package/dist/cjs/metrics.js +302 -0
  32. package/dist/cjs/metrics.js.map +1 -0
  33. package/dist/cjs/quality-checks.d.ts +170 -0
  34. package/dist/cjs/quality-checks.d.ts.map +1 -0
  35. package/dist/cjs/quality-checks.js +417 -0
  36. package/dist/cjs/quality-checks.js.map +1 -0
  37. package/dist/cjs/sobel.d.ts +61 -0
  38. package/dist/cjs/sobel.d.ts.map +1 -0
  39. package/dist/cjs/sobel.js +179 -0
  40. package/dist/cjs/sobel.js.map +1 -0
  41. package/dist/cjs/types.d.ts +98 -0
  42. package/dist/cjs/types.d.ts.map +1 -0
  43. package/dist/cjs/types.js +38 -0
  44. package/dist/cjs/types.js.map +1 -0
  45. package/dist/esm/__fixtures__/address-flow.fixtures.d.ts +35 -0
  46. package/dist/esm/__fixtures__/address-flow.fixtures.d.ts.map +1 -0
  47. package/dist/esm/__fixtures__/address-flow.fixtures.js +183 -0
  48. package/dist/esm/__fixtures__/address-flow.fixtures.js.map +1 -0
  49. package/dist/esm/__fixtures__/metadata-review.fixtures.d.ts +11 -0
  50. package/dist/esm/__fixtures__/metadata-review.fixtures.d.ts.map +1 -0
  51. package/dist/esm/__fixtures__/metadata-review.fixtures.js +66 -0
  52. package/dist/esm/__fixtures__/metadata-review.fixtures.js.map +1 -0
  53. package/dist/esm/address-proof.d.ts +33 -0
  54. package/dist/esm/address-proof.d.ts.map +1 -0
  55. package/dist/esm/address-proof.js +86 -0
  56. package/dist/esm/address-proof.js.map +1 -0
  57. package/dist/esm/document-classifier.d.ts +19 -0
  58. package/dist/esm/document-classifier.d.ts.map +1 -0
  59. package/dist/esm/document-classifier.js +209 -0
  60. package/dist/esm/document-classifier.js.map +1 -0
  61. package/dist/esm/flow-routing.d.ts +7 -0
  62. package/dist/esm/flow-routing.d.ts.map +1 -0
  63. package/dist/esm/flow-routing.js +41 -0
  64. package/dist/esm/flow-routing.js.map +1 -0
  65. package/dist/esm/index.d.ts +25 -0
  66. package/dist/esm/index.d.ts.map +1 -0
  67. package/dist/esm/index.js +19 -0
  68. package/dist/esm/index.js.map +1 -0
  69. package/dist/esm/metadata-review.d.ts +10 -0
  70. package/dist/esm/metadata-review.d.ts.map +1 -0
  71. package/dist/esm/metadata-review.js +90 -0
  72. package/dist/esm/metadata-review.js.map +1 -0
  73. package/dist/esm/metrics.d.ts +115 -0
  74. package/dist/esm/metrics.d.ts.map +1 -0
  75. package/dist/esm/metrics.js +291 -0
  76. package/dist/esm/metrics.js.map +1 -0
  77. package/dist/esm/quality-checks.d.ts +170 -0
  78. package/dist/esm/quality-checks.d.ts.map +1 -0
  79. package/dist/esm/quality-checks.js +400 -0
  80. package/dist/esm/quality-checks.js.map +1 -0
  81. package/dist/esm/sobel.d.ts +61 -0
  82. package/dist/esm/sobel.d.ts.map +1 -0
  83. package/dist/esm/sobel.js +173 -0
  84. package/dist/esm/sobel.js.map +1 -0
  85. package/dist/esm/types.d.ts +98 -0
  86. package/dist/esm/types.d.ts.map +1 -0
  87. package/dist/esm/types.js +35 -0
  88. package/dist/esm/types.js.map +1 -0
  89. package/package.json +65 -0
@@ -0,0 +1,213 @@
1
+ "use strict";
2
+ /**
3
+ * Document likelihood classifier -- 5-signal Bayesian heuristic.
4
+ *
5
+ * DOM-free: operates on raw greyscale (Uint8Array) and RGBA (Uint8ClampedArray)
6
+ * pixel data. No Canvas, no HTMLImageElement.
7
+ */
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.getDocumentReviewProfile = getDocumentReviewProfile;
10
+ exports.checkDocumentLikelihood = checkDocumentLikelihood;
11
+ /* -- Document type normaliser (mirrors host normalizeDocType) ------------- */
12
+ function normalizeDocType(docType) {
13
+ if (!docType)
14
+ return null;
15
+ const raw = String(docType).trim().toLowerCase().replace(/[\s-]+/g, '_');
16
+ switch (raw) {
17
+ case 'national_id':
18
+ case 'sierraleone_national_id':
19
+ return 'id_card';
20
+ case 'sierraleone_voter_id':
21
+ case 'voter':
22
+ return 'voter_id';
23
+ case 'driver_license':
24
+ case 'driver_licence':
25
+ case 'drivers_licence':
26
+ case 'sierraleone_driver_license':
27
+ case 'sierraleone_drivers_license':
28
+ return 'drivers_license';
29
+ case 'sierraleone_passport':
30
+ return 'passport';
31
+ default:
32
+ return raw;
33
+ }
34
+ }
35
+ /* -- Per-document-type aspect ratio profiles ------------------------------ */
36
+ function getDocumentReviewProfile(documentType) {
37
+ const normalizedType = normalizeDocType(documentType);
38
+ // Passports -- biodata page is taller (~1.42:1 or portrait)
39
+ if (normalizedType === 'passport') {
40
+ return {
41
+ aspectTargets: [1.42],
42
+ threshold: 58,
43
+ expectedOrientation: 'portrait',
44
+ };
45
+ }
46
+ // ID card, voter ID, driver's licence -- standard card-shaped documents
47
+ if (normalizedType === 'id_card' ||
48
+ normalizedType === 'voter_id' ||
49
+ normalizedType === 'voter_card' ||
50
+ normalizedType === 'drivers_license' ||
51
+ normalizedType === 'driving_license' ||
52
+ normalizedType === 'driving_licence') {
53
+ return {
54
+ aspectTargets: [1.585],
55
+ threshold: 62,
56
+ expectedOrientation: 'landscape',
57
+ };
58
+ }
59
+ // Address proof / utility bills -- A4/letter shaped documents
60
+ if (normalizedType === 'address_proof' ||
61
+ normalizedType === 'utility_bill' ||
62
+ normalizedType === 'proof_of_address' ||
63
+ normalizedType === 'bank_statement') {
64
+ return {
65
+ aspectTargets: [1.414, 1.294],
66
+ threshold: 55,
67
+ expectedOrientation: 'either',
68
+ };
69
+ }
70
+ return {
71
+ aspectTargets: [1.585, 1.42],
72
+ threshold: 60,
73
+ expectedOrientation: 'either',
74
+ };
75
+ }
76
+ /* -- 5-signal document likelihood classifier ------------------------------ */
77
+ /**
78
+ * Determine whether a greyscale + RGBA image looks like a document.
79
+ *
80
+ * @param grey - Greyscale pixel array (w * h, one byte per pixel)
81
+ * @param imgData - RGBA pixel array (w * h * 4 bytes)
82
+ * @param w - Image width in pixels
83
+ * @param h - Image height in pixels
84
+ * @param documentType - Optional document type hint for aspect-ratio matching
85
+ */
86
+ function checkDocumentLikelihood(grey, imgData, w, h, documentType) {
87
+ const reviewProfile = getDocumentReviewProfile(documentType);
88
+ let score = 0;
89
+ // Single-pass Sobel: build edge map AND track gradient direction for
90
+ // horizontal-edge-dominance (text signature) detection.
91
+ const totalPixels = (w - 2) * (h - 2);
92
+ const edgeMap = new Uint8Array(w * h);
93
+ let edgePixels = 0;
94
+ let hEdgeSum = 0;
95
+ let vEdgeSum = 0;
96
+ for (let ey = 1; ey < h - 1; ey++) {
97
+ for (let ex = 1; ex < w - 1; ex++) {
98
+ const gx = -grey[(ey - 1) * w + (ex - 1)] +
99
+ grey[(ey - 1) * w + (ex + 1)] -
100
+ 2 * grey[ey * w + (ex - 1)] +
101
+ 2 * grey[ey * w + (ex + 1)] -
102
+ grey[(ey + 1) * w + (ex - 1)] +
103
+ grey[(ey + 1) * w + (ex + 1)];
104
+ const gy = -grey[(ey - 1) * w + (ex - 1)] -
105
+ 2 * grey[(ey - 1) * w + ex] -
106
+ grey[(ey - 1) * w + (ex + 1)] +
107
+ grey[(ey + 1) * w + (ex - 1)] +
108
+ 2 * grey[(ey + 1) * w + ex] +
109
+ grey[(ey + 1) * w + (ex + 1)];
110
+ const mag = Math.sqrt(gx * gx + gy * gy);
111
+ if (mag > 30) {
112
+ edgeMap[ey * w + ex] = 1;
113
+ edgePixels++;
114
+ }
115
+ hEdgeSum += Math.abs(gy);
116
+ vEdgeSum += Math.abs(gx);
117
+ }
118
+ }
119
+ // 1. Edge density (widened for worn/faded Sierra Leone national IDs)
120
+ const edgeDensity = totalPixels > 0 ? edgePixels / totalPixels : 0;
121
+ if (edgeDensity >= 0.05 && edgeDensity <= 0.22)
122
+ score += 25;
123
+ else if (edgeDensity >= 0.03 && edgeDensity <= 0.28)
124
+ score += 10;
125
+ // E10: Widened penalty threshold -- textured SL surfaces inflate edge density
126
+ else if (edgeDensity > 0.3)
127
+ score -= 10;
128
+ // 2. Aspect ratio -- match against the nearest supported document profile
129
+ const aspect = w > h ? w / h : h / w;
130
+ let bestAspectDiff = Number.POSITIVE_INFINITY;
131
+ for (let aspectIdx = 0; aspectIdx < reviewProfile.aspectTargets.length; aspectIdx++) {
132
+ bestAspectDiff = Math.min(bestAspectDiff, Math.abs(aspect - reviewProfile.aspectTargets[aspectIdx]));
133
+ }
134
+ if (bestAspectDiff < 0.1)
135
+ score += 25;
136
+ else if (bestAspectDiff < 0.25)
137
+ score += 15;
138
+ else if (bestAspectDiff < 0.45)
139
+ score += 5;
140
+ // 3. Color channel variance
141
+ let rSum = 0, gSum = 0, bSum = 0;
142
+ let rSq = 0, gSq = 0, bSq = 0;
143
+ const px = imgData.length / 4;
144
+ for (let ci = 0; ci < imgData.length; ci += 4) {
145
+ rSum += imgData[ci];
146
+ gSum += imgData[ci + 1];
147
+ bSum += imgData[ci + 2];
148
+ rSq += imgData[ci] * imgData[ci];
149
+ gSq += imgData[ci + 1] * imgData[ci + 1];
150
+ bSq += imgData[ci + 2] * imgData[ci + 2];
151
+ }
152
+ const rVar = rSq / px - (rSum / px) * (rSum / px);
153
+ const gVar = gSq / px - (gSum / px) * (gSum / px);
154
+ const bVar = bSq / px - (bSum / px) * (bSum / px);
155
+ const avgVar = (rVar + gVar + bVar) / 3;
156
+ if (avgVar >= 400 && avgVar <= 4000)
157
+ score += 20;
158
+ else if (avgVar >= 200 && avgVar <= 5500)
159
+ score += 10;
160
+ // E11: Removed penalty for low color variance -- faded/BW SL documents are legitimate
161
+ // 4. Rectangular structure -- center 3x3 grid edge density + glare detection
162
+ const gridW = Math.floor(w / 3);
163
+ const gridH = Math.floor(h / 3);
164
+ let centerEdges = 0, centerTotal = 0;
165
+ let maxBrightness = 0;
166
+ for (let ry = 1; ry < h - 1; ry++) {
167
+ const rowZone = ry < gridH ? 0 : ry >= gridH * 2 ? 2 : 1;
168
+ if (rowZone !== 1)
169
+ continue;
170
+ for (let rx = 1; rx < w - 1; rx++) {
171
+ const colZone = rx < gridW ? 0 : rx >= gridW * 2 ? 2 : 1;
172
+ if (colZone !== 1)
173
+ continue;
174
+ centerEdges += edgeMap[ry * w + rx];
175
+ centerTotal++;
176
+ // Track max brightness in center region for glare detection
177
+ const pixBrightness = grey[ry * w + rx];
178
+ if (pixBrightness > maxBrightness)
179
+ maxBrightness = pixBrightness;
180
+ }
181
+ }
182
+ const centerDensity = centerTotal > 0 ? centerEdges / centerTotal : 0;
183
+ const hasGlare = maxBrightness > 245;
184
+ if (centerDensity >= 0.06 && centerDensity <= 0.2)
185
+ score += 15;
186
+ else if (centerDensity >= 0.03 && centerDensity <= 0.18)
187
+ score += 5;
188
+ else if (centerDensity > 0.2)
189
+ score -= 10;
190
+ // 5. Horizontal-edge dominance (text signature)
191
+ const edgeTotal = hEdgeSum + vEdgeSum;
192
+ if (edgeTotal > 0) {
193
+ const hRatio = hEdgeSum / edgeTotal;
194
+ if (hRatio >= 0.56)
195
+ score += 15;
196
+ else if (hRatio >= 0.52)
197
+ score += 5;
198
+ else if (hRatio < 0.46)
199
+ score -= 10;
200
+ }
201
+ // Rescue path: if aspect ratio matches strongly and some edges exist,
202
+ // set a minimum score -- handles clearly card-shaped objects that are too
203
+ // faded to score well on texture (worn Sierra Leone national IDs).
204
+ if (bestAspectDiff < 0.1 && edgeDensity > 0.03 && score < 15) {
205
+ score = 15;
206
+ }
207
+ return {
208
+ isLikelyDoc: score >= reviewProfile.threshold,
209
+ confidence: score,
210
+ glareDetected: hasGlare,
211
+ };
212
+ }
213
+ //# sourceMappingURL=document-classifier.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"document-classifier.js","sourceRoot":"","sources":["../../src/document-classifier.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ export interface FlowStepDefinition {
2
+ id: string;
3
+ type?: string | null;
4
+ }
5
+ export declare function getNextFlowStepId(steps: FlowStepDefinition[], currentStepId: string, skipType?: string): string | undefined;
6
+ export declare function getPreviousFlowStepId(steps: FlowStepDefinition[], currentStepId: string, skipType?: string): string | undefined;
7
+ //# sourceMappingURL=flow-routing.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"flow-routing.d.ts","sourceRoot":"","sources":["../../src/flow-routing.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,kBAAkB;IACjC,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACtB;AAoCD,wBAAgB,iBAAiB,CAC/B,KAAK,EAAE,kBAAkB,EAAE,EAC3B,aAAa,EAAE,MAAM,EACrB,QAAQ,CAAC,EAAE,MAAM,GAChB,MAAM,GAAG,SAAS,CAcpB;AAED,wBAAgB,qBAAqB,CACnC,KAAK,EAAE,kBAAkB,EAAE,EAC3B,aAAa,EAAE,MAAM,EACrB,QAAQ,CAAC,EAAE,MAAM,GAChB,MAAM,GAAG,SAAS,CAcpB"}
@@ -0,0 +1,45 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getNextFlowStepId = getNextFlowStepId;
4
+ exports.getPreviousFlowStepId = getPreviousFlowStepId;
5
+ function filterFlowStepsByType(steps, skipType) {
6
+ if (!skipType) {
7
+ return steps;
8
+ }
9
+ return steps.filter(step => step.type !== skipType);
10
+ }
11
+ function findCompatibleStepId(steps, fromIndex, direction, skipType) {
12
+ for (let stepIndex = fromIndex + direction; stepIndex >= 0 && stepIndex < steps.length; stepIndex += direction) {
13
+ const step = steps[stepIndex];
14
+ if (!step || (skipType && step.type === skipType)) {
15
+ continue;
16
+ }
17
+ return step.id;
18
+ }
19
+ return undefined;
20
+ }
21
+ function getNextFlowStepId(steps, currentStepId, skipType) {
22
+ const filteredSteps = filterFlowStepsByType(steps, skipType);
23
+ const filteredIndex = filteredSteps.findIndex(step => step.id === currentStepId);
24
+ if (filteredIndex === -1 && skipType) {
25
+ const sourceIndex = steps.findIndex(step => step.id === currentStepId);
26
+ return sourceIndex === -1 ? undefined : findCompatibleStepId(steps, sourceIndex, 1, skipType);
27
+ }
28
+ if (filteredIndex === -1) {
29
+ return undefined;
30
+ }
31
+ return filteredSteps[filteredIndex + 1]?.id;
32
+ }
33
+ function getPreviousFlowStepId(steps, currentStepId, skipType) {
34
+ const filteredSteps = filterFlowStepsByType(steps, skipType);
35
+ const filteredIndex = filteredSteps.findIndex(step => step.id === currentStepId);
36
+ if (filteredIndex === -1 && skipType) {
37
+ const sourceIndex = steps.findIndex(step => step.id === currentStepId);
38
+ return sourceIndex === -1 ? undefined : findCompatibleStepId(steps, sourceIndex, -1, skipType);
39
+ }
40
+ if (filteredIndex <= 0) {
41
+ return undefined;
42
+ }
43
+ return filteredSteps[filteredIndex - 1]?.id;
44
+ }
45
+ //# sourceMappingURL=flow-routing.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"flow-routing.js","sourceRoot":"","sources":["../../src/flow-routing.ts"],"names":[],"mappings":";;AAuCA,8CAkBC;AAED,sDAkBC;AAxED,SAAS,qBAAqB,CAC5B,KAA2B,EAC3B,QAAiB;IAEjB,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,OAAO,KAAK,CAAC;IACf,CAAC;IAED,OAAO,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC;AACtD,CAAC;AAED,SAAS,oBAAoB,CAC3B,KAA2B,EAC3B,SAAiB,EACjB,SAAiB,EACjB,QAAiB;IAEjB,KACE,IAAI,SAAS,GAAG,SAAS,GAAG,SAAS,EACrC,SAAS,IAAI,CAAC,IAAI,SAAS,GAAG,KAAK,CAAC,MAAM,EAC1C,SAAS,IAAI,SAAS,EACtB,CAAC;QACD,MAAM,IAAI,GAAG,KAAK,CAAC,SAAS,CAAC,CAAC;QAE9B,IAAI,CAAC,IAAI,IAAI,CAAC,QAAQ,IAAI,IAAI,CAAC,IAAI,KAAK,QAAQ,CAAC,EAAE,CAAC;YAClD,SAAS;QACX,CAAC;QAED,OAAO,IAAI,CAAC,EAAE,CAAC;IACjB,CAAC;IAED,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,SAAgB,iBAAiB,CAC/B,KAA2B,EAC3B,aAAqB,EACrB,QAAiB;IAEjB,MAAM,aAAa,GAAG,qBAAqB,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;IAC7D,MAAM,aAAa,GAAG,aAAa,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,KAAK,aAAa,CAAC,CAAC;IAEjF,IAAI,aAAa,KAAK,CAAC,CAAC,IAAI,QAAQ,EAAE,CAAC;QACrC,MAAM,WAAW,GAAG,KAAK,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,KAAK,aAAa,CAAC,CAAC;QACvE,OAAO,WAAW,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,oBAAoB,CAAC,KAAK,EAAE,WAAW,EAAE,CAAC,EAAE,QAAQ,CAAC,CAAC;IAChG,CAAC;IAED,IAAI,aAAa,KAAK,CAAC,CAAC,EAAE,CAAC;QACzB,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,OAAO,aAAa,CAAC,aAAa,GAAG,CAAC,CAAC,EAAE,EAAE,CAAC;AAC9C,CAAC;AAED,SAAgB,qBAAqB,CACnC,KAA2B,EAC3B,aAAqB,EACrB,QAAiB;IAEjB,MAAM,aAAa,GAAG,qBAAqB,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;IAC7D,MAAM,aAAa,GAAG,aAAa,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,KAAK,aAAa,CAAC,CAAC;IAEjF,IAAI,aAAa,KAAK,CAAC,CAAC,IAAI,QAAQ,EAAE,CAAC;QACrC,MAAM,WAAW,GAAG,KAAK,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,KAAK,aAAa,CAAC,CAAC;QACvE,OAAO,WAAW,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,oBAAoB,CAAC,KAAK,EAAE,WAAW,EAAE,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC;IACjG,CAAC;IAED,IAAI,aAAa,IAAI,CAAC,EAAE,CAAC;QACvB,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,OAAO,aAAa,CAAC,aAAa,GAAG,CAAC,CAAC,EAAE,EAAE,CAAC;AAC9C,CAAC"}
@@ -0,0 +1,25 @@
1
+ /**
2
+ * @mikashboks/capture-intelligence-core
3
+ *
4
+ * DOM-free algorithmic core for capture intelligence: document classification,
5
+ * Sobel edge detection, frame metrics computation, and quality checks.
6
+ *
7
+ * All exports operate on raw data (Uint8Array pixel arrays, FrameMetrics
8
+ * objects, numeric values). Zero browser dependencies.
9
+ */
10
+ export type { CamStateValue, FrameMetrics, DocumentReviewProfile, DocumentLikelihoodResult, CropRect, DocumentCropResult, OverlayRegion, OverlayVariant, QualityCheckResults, FaceBoundingBox, DetectedFace, MetadataReviewIssue, MetadataReviewResult, ReviewOrientation, ReviewMode, QualityBucket, ReviewDecisionOptions, } from './types.js';
11
+ export { CamState, CAM_ANALYSIS_W, CAM_ANALYSIS_H, CAM_BRIGHTNESS_MIN, CAM_BRIGHTNESS_MAX, CAM_BLUR_THRESHOLD, CAM_EDGE_THRESHOLD, CAM_STABLE_FRAMES_NEEDED, CAM_FRAME_DIFF_THRESHOLD, CAM_EDGE_PIXEL_THRESHOLD, CAM_EDGE_COVERAGE_THRESHOLD, CAM_DOC_CENTER_OFFSET_MAX, DOC_GALLERY_FAILURE_THRESHOLD, DOC_SUBMIT_ANYWAY_FAILURE_THRESHOLD, SELFIE_SUBMIT_ANYWAY_FAILURE_THRESHOLD, ADDRESS_SUBMIT_ANYWAY_FAILURE_THRESHOLD, PICO_ANALYSIS_W, PICO_ANALYSIS_H, } from './types.js';
12
+ export type { AddressMethod, AddressProofMode, AddressCoordinatesLike, AddressStepState, AddressMethodStartBehavior, } from './address-proof.js';
13
+ export { ADDRESS_METHOD_ORDER, isAddressMethod, sanitizeAllowedAddressMethods, getRecommendedAddressMethod, getAddressMethodStartBehavior, getEffectiveAddressMethod, hasAddressProofCoordinates, hasStructuredAddress, isAddressStepComplete, } from './address-proof.js';
14
+ export type { FlowStepDefinition } from './flow-routing.js';
15
+ export { getNextFlowStepId, getPreviousFlowStepId } from './flow-routing.js';
16
+ export { getDocumentReviewProfile, checkDocumentLikelihood, } from './document-classifier.js';
17
+ export type { MetadataReviewInput } from './metadata-review.js';
18
+ export { analyzeImageMetadata } from './metadata-review.js';
19
+ export type { EdgeEnergyProfile } from './sobel.js';
20
+ export { rgbaToGreyscale, rgbaToGreyscalePico, computeEdgeEnergyProfile, detectDocumentCropFromGrey, } from './sobel.js';
21
+ export type { EdgeAnalysisResult } from './metrics.js';
22
+ export { rgbaToGreyInPlace, computeBrightness, computeLaplacianVariance, computeLaplacianVarianceFloat, computeEdgeEnergy, detectDocumentRect, computeFrameDiff, analyzeFrame, looksLikeDocument, } from './metrics.js';
23
+ export type { QualityFailureState, DocumentQualityInput, DocumentQualityResult, SelfieQualityInput, } from './quality-checks.js';
24
+ export { getQualityBucket, getSubmitAnywayThreshold, createQualityFailureState, countFailedReview, shouldShowSubmitAnyway, runDocumentQualityChecks, runSelfieQualityChecks, checkFaceInImage, isFaceCentered, evaluateDocumentFailure, evaluateSelfieFailure, evaluateReviewFailure, getNextButtonDisabledReason, getOverrideButtonText, getOverrideBannerMessage, } from './quality-checks.js';
25
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAGH,YAAY,EACV,aAAa,EACb,YAAY,EACZ,qBAAqB,EACrB,wBAAwB,EACxB,QAAQ,EACR,kBAAkB,EAClB,aAAa,EACb,cAAc,EACd,mBAAmB,EACnB,eAAe,EACf,YAAY,EACZ,mBAAmB,EACnB,oBAAoB,EACpB,iBAAiB,EACjB,UAAU,EACV,aAAa,EACb,qBAAqB,GACtB,MAAM,YAAY,CAAC;AAEpB,OAAO,EACL,QAAQ,EACR,cAAc,EACd,cAAc,EACd,kBAAkB,EAClB,kBAAkB,EAClB,kBAAkB,EAClB,kBAAkB,EAClB,wBAAwB,EACxB,wBAAwB,EACxB,wBAAwB,EACxB,2BAA2B,EAC3B,yBAAyB,EACzB,6BAA6B,EAC7B,mCAAmC,EACnC,sCAAsC,EACtC,uCAAuC,EACvC,eAAe,EACf,eAAe,GAChB,MAAM,YAAY,CAAC;AAGpB,YAAY,EACV,aAAa,EACb,gBAAgB,EAChB,sBAAsB,EACtB,gBAAgB,EAChB,0BAA0B,GAC3B,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EACL,oBAAoB,EACpB,eAAe,EACf,6BAA6B,EAC7B,2BAA2B,EAC3B,6BAA6B,EAC7B,yBAAyB,EACzB,0BAA0B,EAC1B,oBAAoB,EACpB,qBAAqB,GACtB,MAAM,oBAAoB,CAAC;AAG5B,YAAY,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAC5D,OAAO,EAAE,iBAAiB,EAAE,qBAAqB,EAAE,MAAM,mBAAmB,CAAC;AAG7E,OAAO,EACL,wBAAwB,EACxB,uBAAuB,GACxB,MAAM,0BAA0B,CAAC;AAGlC,YAAY,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AAChE,OAAO,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAG5D,YAAY,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AACpD,OAAO,EACL,eAAe,EACf,mBAAmB,EACnB,wBAAwB,EACxB,0BAA0B,GAC3B,MAAM,YAAY,CAAC;AAGpB,YAAY,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AACvD,OAAO,EACL,iBAAiB,EACjB,iBAAiB,EACjB,wBAAwB,EACxB,6BAA6B,EAC7B,iBAAiB,EACjB,kBAAkB,EAClB,gBAAgB,EAChB,YAAY,EACZ,iBAAiB,GAClB,MAAM,cAAc,CAAC;AAGtB,YAAY,EACV,mBAAmB,EACnB,oBAAoB,EACpB,qBAAqB,EACrB,kBAAkB,GACnB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EACL,gBAAgB,EAChB,wBAAwB,EACxB,yBAAyB,EACzB,iBAAiB,EACjB,sBAAsB,EACtB,wBAAwB,EACxB,sBAAsB,EACtB,gBAAgB,EAChB,cAAc,EACd,uBAAuB,EACvB,qBAAqB,EACrB,qBAAqB,EACrB,2BAA2B,EAC3B,qBAAqB,EACrB,wBAAwB,GACzB,MAAM,qBAAqB,CAAC"}
@@ -0,0 +1,83 @@
1
+ "use strict";
2
+ /**
3
+ * @mikashboks/capture-intelligence-core
4
+ *
5
+ * DOM-free algorithmic core for capture intelligence: document classification,
6
+ * Sobel edge detection, frame metrics computation, and quality checks.
7
+ *
8
+ * All exports operate on raw data (Uint8Array pixel arrays, FrameMetrics
9
+ * objects, numeric values). Zero browser dependencies.
10
+ */
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.shouldShowSubmitAnyway = exports.countFailedReview = exports.createQualityFailureState = exports.getSubmitAnywayThreshold = exports.getQualityBucket = exports.looksLikeDocument = exports.analyzeFrame = exports.computeFrameDiff = exports.detectDocumentRect = exports.computeEdgeEnergy = exports.computeLaplacianVarianceFloat = exports.computeLaplacianVariance = exports.computeBrightness = exports.rgbaToGreyInPlace = exports.detectDocumentCropFromGrey = exports.computeEdgeEnergyProfile = exports.rgbaToGreyscalePico = exports.rgbaToGreyscale = exports.analyzeImageMetadata = exports.checkDocumentLikelihood = exports.getDocumentReviewProfile = exports.getPreviousFlowStepId = exports.getNextFlowStepId = exports.isAddressStepComplete = exports.hasStructuredAddress = exports.hasAddressProofCoordinates = exports.getEffectiveAddressMethod = exports.getAddressMethodStartBehavior = exports.getRecommendedAddressMethod = exports.sanitizeAllowedAddressMethods = exports.isAddressMethod = exports.ADDRESS_METHOD_ORDER = exports.PICO_ANALYSIS_H = exports.PICO_ANALYSIS_W = exports.ADDRESS_SUBMIT_ANYWAY_FAILURE_THRESHOLD = exports.SELFIE_SUBMIT_ANYWAY_FAILURE_THRESHOLD = exports.DOC_SUBMIT_ANYWAY_FAILURE_THRESHOLD = exports.DOC_GALLERY_FAILURE_THRESHOLD = exports.CAM_DOC_CENTER_OFFSET_MAX = exports.CAM_EDGE_COVERAGE_THRESHOLD = exports.CAM_EDGE_PIXEL_THRESHOLD = exports.CAM_FRAME_DIFF_THRESHOLD = exports.CAM_STABLE_FRAMES_NEEDED = exports.CAM_EDGE_THRESHOLD = exports.CAM_BLUR_THRESHOLD = exports.CAM_BRIGHTNESS_MAX = exports.CAM_BRIGHTNESS_MIN = exports.CAM_ANALYSIS_H = exports.CAM_ANALYSIS_W = exports.CamState = void 0;
13
+ exports.getOverrideBannerMessage = exports.getOverrideButtonText = exports.getNextButtonDisabledReason = exports.evaluateReviewFailure = exports.evaluateSelfieFailure = exports.evaluateDocumentFailure = exports.isFaceCentered = exports.checkFaceInImage = exports.runSelfieQualityChecks = exports.runDocumentQualityChecks = void 0;
14
+ var types_js_1 = require("./types.js");
15
+ Object.defineProperty(exports, "CamState", { enumerable: true, get: function () { return types_js_1.CamState; } });
16
+ Object.defineProperty(exports, "CAM_ANALYSIS_W", { enumerable: true, get: function () { return types_js_1.CAM_ANALYSIS_W; } });
17
+ Object.defineProperty(exports, "CAM_ANALYSIS_H", { enumerable: true, get: function () { return types_js_1.CAM_ANALYSIS_H; } });
18
+ Object.defineProperty(exports, "CAM_BRIGHTNESS_MIN", { enumerable: true, get: function () { return types_js_1.CAM_BRIGHTNESS_MIN; } });
19
+ Object.defineProperty(exports, "CAM_BRIGHTNESS_MAX", { enumerable: true, get: function () { return types_js_1.CAM_BRIGHTNESS_MAX; } });
20
+ Object.defineProperty(exports, "CAM_BLUR_THRESHOLD", { enumerable: true, get: function () { return types_js_1.CAM_BLUR_THRESHOLD; } });
21
+ Object.defineProperty(exports, "CAM_EDGE_THRESHOLD", { enumerable: true, get: function () { return types_js_1.CAM_EDGE_THRESHOLD; } });
22
+ Object.defineProperty(exports, "CAM_STABLE_FRAMES_NEEDED", { enumerable: true, get: function () { return types_js_1.CAM_STABLE_FRAMES_NEEDED; } });
23
+ Object.defineProperty(exports, "CAM_FRAME_DIFF_THRESHOLD", { enumerable: true, get: function () { return types_js_1.CAM_FRAME_DIFF_THRESHOLD; } });
24
+ Object.defineProperty(exports, "CAM_EDGE_PIXEL_THRESHOLD", { enumerable: true, get: function () { return types_js_1.CAM_EDGE_PIXEL_THRESHOLD; } });
25
+ Object.defineProperty(exports, "CAM_EDGE_COVERAGE_THRESHOLD", { enumerable: true, get: function () { return types_js_1.CAM_EDGE_COVERAGE_THRESHOLD; } });
26
+ Object.defineProperty(exports, "CAM_DOC_CENTER_OFFSET_MAX", { enumerable: true, get: function () { return types_js_1.CAM_DOC_CENTER_OFFSET_MAX; } });
27
+ Object.defineProperty(exports, "DOC_GALLERY_FAILURE_THRESHOLD", { enumerable: true, get: function () { return types_js_1.DOC_GALLERY_FAILURE_THRESHOLD; } });
28
+ Object.defineProperty(exports, "DOC_SUBMIT_ANYWAY_FAILURE_THRESHOLD", { enumerable: true, get: function () { return types_js_1.DOC_SUBMIT_ANYWAY_FAILURE_THRESHOLD; } });
29
+ Object.defineProperty(exports, "SELFIE_SUBMIT_ANYWAY_FAILURE_THRESHOLD", { enumerable: true, get: function () { return types_js_1.SELFIE_SUBMIT_ANYWAY_FAILURE_THRESHOLD; } });
30
+ Object.defineProperty(exports, "ADDRESS_SUBMIT_ANYWAY_FAILURE_THRESHOLD", { enumerable: true, get: function () { return types_js_1.ADDRESS_SUBMIT_ANYWAY_FAILURE_THRESHOLD; } });
31
+ Object.defineProperty(exports, "PICO_ANALYSIS_W", { enumerable: true, get: function () { return types_js_1.PICO_ANALYSIS_W; } });
32
+ Object.defineProperty(exports, "PICO_ANALYSIS_H", { enumerable: true, get: function () { return types_js_1.PICO_ANALYSIS_H; } });
33
+ var address_proof_js_1 = require("./address-proof.js");
34
+ Object.defineProperty(exports, "ADDRESS_METHOD_ORDER", { enumerable: true, get: function () { return address_proof_js_1.ADDRESS_METHOD_ORDER; } });
35
+ Object.defineProperty(exports, "isAddressMethod", { enumerable: true, get: function () { return address_proof_js_1.isAddressMethod; } });
36
+ Object.defineProperty(exports, "sanitizeAllowedAddressMethods", { enumerable: true, get: function () { return address_proof_js_1.sanitizeAllowedAddressMethods; } });
37
+ Object.defineProperty(exports, "getRecommendedAddressMethod", { enumerable: true, get: function () { return address_proof_js_1.getRecommendedAddressMethod; } });
38
+ Object.defineProperty(exports, "getAddressMethodStartBehavior", { enumerable: true, get: function () { return address_proof_js_1.getAddressMethodStartBehavior; } });
39
+ Object.defineProperty(exports, "getEffectiveAddressMethod", { enumerable: true, get: function () { return address_proof_js_1.getEffectiveAddressMethod; } });
40
+ Object.defineProperty(exports, "hasAddressProofCoordinates", { enumerable: true, get: function () { return address_proof_js_1.hasAddressProofCoordinates; } });
41
+ Object.defineProperty(exports, "hasStructuredAddress", { enumerable: true, get: function () { return address_proof_js_1.hasStructuredAddress; } });
42
+ Object.defineProperty(exports, "isAddressStepComplete", { enumerable: true, get: function () { return address_proof_js_1.isAddressStepComplete; } });
43
+ var flow_routing_js_1 = require("./flow-routing.js");
44
+ Object.defineProperty(exports, "getNextFlowStepId", { enumerable: true, get: function () { return flow_routing_js_1.getNextFlowStepId; } });
45
+ Object.defineProperty(exports, "getPreviousFlowStepId", { enumerable: true, get: function () { return flow_routing_js_1.getPreviousFlowStepId; } });
46
+ /* -- Document classifier -------------------------------------------------- */
47
+ var document_classifier_js_1 = require("./document-classifier.js");
48
+ Object.defineProperty(exports, "getDocumentReviewProfile", { enumerable: true, get: function () { return document_classifier_js_1.getDocumentReviewProfile; } });
49
+ Object.defineProperty(exports, "checkDocumentLikelihood", { enumerable: true, get: function () { return document_classifier_js_1.checkDocumentLikelihood; } });
50
+ var metadata_review_js_1 = require("./metadata-review.js");
51
+ Object.defineProperty(exports, "analyzeImageMetadata", { enumerable: true, get: function () { return metadata_review_js_1.analyzeImageMetadata; } });
52
+ var sobel_js_1 = require("./sobel.js");
53
+ Object.defineProperty(exports, "rgbaToGreyscale", { enumerable: true, get: function () { return sobel_js_1.rgbaToGreyscale; } });
54
+ Object.defineProperty(exports, "rgbaToGreyscalePico", { enumerable: true, get: function () { return sobel_js_1.rgbaToGreyscalePico; } });
55
+ Object.defineProperty(exports, "computeEdgeEnergyProfile", { enumerable: true, get: function () { return sobel_js_1.computeEdgeEnergyProfile; } });
56
+ Object.defineProperty(exports, "detectDocumentCropFromGrey", { enumerable: true, get: function () { return sobel_js_1.detectDocumentCropFromGrey; } });
57
+ var metrics_js_1 = require("./metrics.js");
58
+ Object.defineProperty(exports, "rgbaToGreyInPlace", { enumerable: true, get: function () { return metrics_js_1.rgbaToGreyInPlace; } });
59
+ Object.defineProperty(exports, "computeBrightness", { enumerable: true, get: function () { return metrics_js_1.computeBrightness; } });
60
+ Object.defineProperty(exports, "computeLaplacianVariance", { enumerable: true, get: function () { return metrics_js_1.computeLaplacianVariance; } });
61
+ Object.defineProperty(exports, "computeLaplacianVarianceFloat", { enumerable: true, get: function () { return metrics_js_1.computeLaplacianVarianceFloat; } });
62
+ Object.defineProperty(exports, "computeEdgeEnergy", { enumerable: true, get: function () { return metrics_js_1.computeEdgeEnergy; } });
63
+ Object.defineProperty(exports, "detectDocumentRect", { enumerable: true, get: function () { return metrics_js_1.detectDocumentRect; } });
64
+ Object.defineProperty(exports, "computeFrameDiff", { enumerable: true, get: function () { return metrics_js_1.computeFrameDiff; } });
65
+ Object.defineProperty(exports, "analyzeFrame", { enumerable: true, get: function () { return metrics_js_1.analyzeFrame; } });
66
+ Object.defineProperty(exports, "looksLikeDocument", { enumerable: true, get: function () { return metrics_js_1.looksLikeDocument; } });
67
+ var quality_checks_js_1 = require("./quality-checks.js");
68
+ Object.defineProperty(exports, "getQualityBucket", { enumerable: true, get: function () { return quality_checks_js_1.getQualityBucket; } });
69
+ Object.defineProperty(exports, "getSubmitAnywayThreshold", { enumerable: true, get: function () { return quality_checks_js_1.getSubmitAnywayThreshold; } });
70
+ Object.defineProperty(exports, "createQualityFailureState", { enumerable: true, get: function () { return quality_checks_js_1.createQualityFailureState; } });
71
+ Object.defineProperty(exports, "countFailedReview", { enumerable: true, get: function () { return quality_checks_js_1.countFailedReview; } });
72
+ Object.defineProperty(exports, "shouldShowSubmitAnyway", { enumerable: true, get: function () { return quality_checks_js_1.shouldShowSubmitAnyway; } });
73
+ Object.defineProperty(exports, "runDocumentQualityChecks", { enumerable: true, get: function () { return quality_checks_js_1.runDocumentQualityChecks; } });
74
+ Object.defineProperty(exports, "runSelfieQualityChecks", { enumerable: true, get: function () { return quality_checks_js_1.runSelfieQualityChecks; } });
75
+ Object.defineProperty(exports, "checkFaceInImage", { enumerable: true, get: function () { return quality_checks_js_1.checkFaceInImage; } });
76
+ Object.defineProperty(exports, "isFaceCentered", { enumerable: true, get: function () { return quality_checks_js_1.isFaceCentered; } });
77
+ Object.defineProperty(exports, "evaluateDocumentFailure", { enumerable: true, get: function () { return quality_checks_js_1.evaluateDocumentFailure; } });
78
+ Object.defineProperty(exports, "evaluateSelfieFailure", { enumerable: true, get: function () { return quality_checks_js_1.evaluateSelfieFailure; } });
79
+ Object.defineProperty(exports, "evaluateReviewFailure", { enumerable: true, get: function () { return quality_checks_js_1.evaluateReviewFailure; } });
80
+ Object.defineProperty(exports, "getNextButtonDisabledReason", { enumerable: true, get: function () { return quality_checks_js_1.getNextButtonDisabledReason; } });
81
+ Object.defineProperty(exports, "getOverrideButtonText", { enumerable: true, get: function () { return quality_checks_js_1.getOverrideButtonText; } });
82
+ Object.defineProperty(exports, "getOverrideBannerMessage", { enumerable: true, get: function () { return quality_checks_js_1.getOverrideBannerMessage; } });
83
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":";AAAA;;;;;;;;GAQG;;;;AAuBH,uCAmBoB;AAlBlB,oGAAA,QAAQ,OAAA;AACR,0GAAA,cAAc,OAAA;AACd,0GAAA,cAAc,OAAA;AACd,8GAAA,kBAAkB,OAAA;AAClB,8GAAA,kBAAkB,OAAA;AAClB,8GAAA,kBAAkB,OAAA;AAClB,8GAAA,kBAAkB,OAAA;AAClB,oHAAA,wBAAwB,OAAA;AACxB,oHAAA,wBAAwB,OAAA;AACxB,oHAAA,wBAAwB,OAAA;AACxB,uHAAA,2BAA2B,OAAA;AAC3B,qHAAA,yBAAyB,OAAA;AACzB,yHAAA,6BAA6B,OAAA;AAC7B,+HAAA,mCAAmC,OAAA;AACnC,kIAAA,sCAAsC,OAAA;AACtC,mIAAA,uCAAuC,OAAA;AACvC,2GAAA,eAAe,OAAA;AACf,2GAAA,eAAe,OAAA;AAWjB,uDAU4B;AAT1B,wHAAA,oBAAoB,OAAA;AACpB,mHAAA,eAAe,OAAA;AACf,iIAAA,6BAA6B,OAAA;AAC7B,+HAAA,2BAA2B,OAAA;AAC3B,iIAAA,6BAA6B,OAAA;AAC7B,6HAAA,yBAAyB,OAAA;AACzB,8HAAA,0BAA0B,OAAA;AAC1B,wHAAA,oBAAoB,OAAA;AACpB,yHAAA,qBAAqB,OAAA;AAKvB,qDAA6E;AAApE,oHAAA,iBAAiB,OAAA;AAAE,wHAAA,qBAAqB,OAAA;AAEjD,+EAA+E;AAC/E,mEAGkC;AAFhC,kIAAA,wBAAwB,OAAA;AACxB,iIAAA,uBAAuB,OAAA;AAKzB,2DAA4D;AAAnD,0HAAA,oBAAoB,OAAA;AAI7B,uCAKoB;AAJlB,2GAAA,eAAe,OAAA;AACf,+GAAA,mBAAmB,OAAA;AACnB,oHAAA,wBAAwB,OAAA;AACxB,sHAAA,0BAA0B,OAAA;AAK5B,2CAUsB;AATpB,+GAAA,iBAAiB,OAAA;AACjB,+GAAA,iBAAiB,OAAA;AACjB,sHAAA,wBAAwB,OAAA;AACxB,2HAAA,6BAA6B,OAAA;AAC7B,+GAAA,iBAAiB,OAAA;AACjB,gHAAA,kBAAkB,OAAA;AAClB,8GAAA,gBAAgB,OAAA;AAChB,0GAAA,YAAY,OAAA;AACZ,+GAAA,iBAAiB,OAAA;AAUnB,yDAgB6B;AAf3B,qHAAA,gBAAgB,OAAA;AAChB,6HAAA,wBAAwB,OAAA;AACxB,8HAAA,yBAAyB,OAAA;AACzB,sHAAA,iBAAiB,OAAA;AACjB,2HAAA,sBAAsB,OAAA;AACtB,6HAAA,wBAAwB,OAAA;AACxB,2HAAA,sBAAsB,OAAA;AACtB,qHAAA,gBAAgB,OAAA;AAChB,mHAAA,cAAc,OAAA;AACd,4HAAA,uBAAuB,OAAA;AACvB,0HAAA,qBAAqB,OAAA;AACrB,0HAAA,qBAAqB,OAAA;AACrB,gIAAA,2BAA2B,OAAA;AAC3B,0HAAA,qBAAqB,OAAA;AACrB,6HAAA,wBAAwB,OAAA"}
@@ -0,0 +1,10 @@
1
+ import type { MetadataReviewResult } from './types.js';
2
+ export interface MetadataReviewInput {
3
+ type: 'document' | 'selfie';
4
+ width: number;
5
+ height: number;
6
+ fileSize?: number | null;
7
+ documentType?: string | null;
8
+ }
9
+ export declare function analyzeImageMetadata(input: MetadataReviewInput): MetadataReviewResult;
10
+ //# sourceMappingURL=metadata-review.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"metadata-review.d.ts","sourceRoot":"","sources":["../../src/metadata-review.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAEV,oBAAoB,EAErB,MAAM,YAAY,CAAC;AAGpB,MAAM,WAAW,mBAAmB;IAClC,IAAI,EAAE,UAAU,GAAG,QAAQ,CAAC;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC9B;AA4BD,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,mBAAmB,GAAG,oBAAoB,CAoFrF"}
@@ -0,0 +1,93 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.analyzeImageMetadata = analyzeImageMetadata;
4
+ const document_classifier_js_1 = require("./document-classifier.js");
5
+ const MIN_WIDTH = 200;
6
+ const MIN_HEIGHT = 150;
7
+ const COMPRESSION_WARNING_MIN_PIXELS = 640 * 480;
8
+ const LOW_DETAIL_BYTES_PER_PIXEL = 0.04;
9
+ function getOrientation(width, height) {
10
+ const ratio = width / Math.max(1, height);
11
+ if (ratio > 1.08)
12
+ return 'landscape';
13
+ if (ratio < 0.92)
14
+ return 'portrait';
15
+ return 'square';
16
+ }
17
+ function buildResult(type, orientation, issues, isDocument = type === 'document') {
18
+ return {
19
+ passed: issues.every(issue => issue.severity !== 'error'),
20
+ issues,
21
+ orientation,
22
+ isDocument,
23
+ };
24
+ }
25
+ function analyzeImageMetadata(input) {
26
+ const orientation = getOrientation(input.width, input.height);
27
+ const issues = [];
28
+ if (input.width < MIN_WIDTH || input.height < MIN_HEIGHT) {
29
+ issues.push({
30
+ key: 'too_small',
31
+ message: 'Image is too small. Please take a new photo.',
32
+ severity: 'error',
33
+ });
34
+ return buildResult(input.type, orientation, issues, false);
35
+ }
36
+ if (input.type === 'document') {
37
+ const reviewProfile = (0, document_classifier_js_1.getDocumentReviewProfile)(input.documentType);
38
+ const normalizedAspect = input.width > input.height
39
+ ? input.width / input.height
40
+ : input.height / input.width;
41
+ const bestAspectDiff = Math.min(...reviewProfile.aspectTargets.map(target => Math.abs(normalizedAspect - target)));
42
+ if (bestAspectDiff > 0.33) {
43
+ issues.push({
44
+ key: 'bad_aspect',
45
+ message: "This doesn't match the selected document shape. Retake with the full document visible.",
46
+ severity: 'error',
47
+ });
48
+ }
49
+ else if (bestAspectDiff > 0.2) {
50
+ issues.push({
51
+ key: 'document_shape_warning',
52
+ message: 'Make sure the full document is visible and not tilted too much.',
53
+ severity: 'warning',
54
+ });
55
+ }
56
+ if (reviewProfile.expectedOrientation === 'landscape' &&
57
+ orientation === 'portrait') {
58
+ issues.push({
59
+ key: 'document_rotated',
60
+ message: 'Rotate the document so it is wider than it is tall.',
61
+ severity: 'warning',
62
+ });
63
+ }
64
+ if (reviewProfile.expectedOrientation === 'portrait' &&
65
+ orientation === 'landscape') {
66
+ issues.push({
67
+ key: 'document_rotated',
68
+ message: 'Rotate the document so the page is upright before retaking.',
69
+ severity: 'warning',
70
+ });
71
+ }
72
+ }
73
+ else if (orientation === 'landscape') {
74
+ issues.push({
75
+ key: 'selfie_landscape',
76
+ message: 'Use portrait orientation so the full face and shoulders fit in frame.',
77
+ severity: 'warning',
78
+ });
79
+ }
80
+ if (input.fileSize &&
81
+ input.width * input.height >= COMPRESSION_WARNING_MIN_PIXELS &&
82
+ input.fileSize / (input.width * input.height) < LOW_DETAIL_BYTES_PER_PIXEL) {
83
+ issues.push({
84
+ key: 'low_detail',
85
+ message: 'Photo looks heavily compressed. Retake it without zooming or screenshots.',
86
+ severity: 'warning',
87
+ });
88
+ }
89
+ const isDocument = input.type === 'document' &&
90
+ !issues.some(issue => issue.key === 'bad_aspect');
91
+ return buildResult(input.type, orientation, issues, isDocument);
92
+ }
93
+ //# sourceMappingURL=metadata-review.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"metadata-review.js","sourceRoot":"","sources":["../../src/metadata-review.ts"],"names":[],"mappings":"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"}