smartcomply-web-sdk 1.0.99 → 1.0.101

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 (55) hide show
  1. package/dist/client/Smartcomply.d.ts +1 -1
  2. package/dist/client/Smartcomply.d.ts.map +1 -1
  3. package/dist/client/Smartcomply.js +1 -1
  4. package/dist/client/Smartcomply.js.map +1 -1
  5. package/dist/esm/client/Smartcomply.d.ts +1 -1
  6. package/dist/esm/client/Smartcomply.d.ts.map +1 -1
  7. package/dist/esm/client/Smartcomply.js +1 -1
  8. package/dist/esm/client/Smartcomply.js.map +1 -1
  9. package/dist/esm/flow/DocumentCapture.d.ts +3 -19
  10. package/dist/esm/flow/DocumentCapture.d.ts.map +1 -1
  11. package/dist/esm/flow/DocumentCapture.js +22 -170
  12. package/dist/esm/flow/DocumentCapture.js.map +1 -1
  13. package/dist/esm/flow/SmartComplyFlow.d.ts +0 -1
  14. package/dist/esm/flow/SmartComplyFlow.d.ts.map +1 -1
  15. package/dist/esm/flow/SmartComplyFlow.js +67 -94
  16. package/dist/esm/flow/SmartComplyFlow.js.map +1 -1
  17. package/dist/esm/types/onboarding.d.ts +2 -0
  18. package/dist/esm/types/onboarding.d.ts.map +1 -1
  19. package/dist/esm/utils/channels.d.ts +15 -0
  20. package/dist/esm/utils/channels.d.ts.map +1 -1
  21. package/dist/esm/utils/channels.js +41 -0
  22. package/dist/esm/utils/channels.js.map +1 -1
  23. package/dist/esm/utils/constants.d.ts +9 -8
  24. package/dist/esm/utils/constants.d.ts.map +1 -1
  25. package/dist/esm/utils/constants.js +10 -9
  26. package/dist/esm/utils/constants.js.map +1 -1
  27. package/dist/esm/utils/documentRules.d.ts +1 -2
  28. package/dist/esm/utils/documentRules.d.ts.map +1 -1
  29. package/dist/esm/utils/documentRules.js +1 -2
  30. package/dist/esm/utils/documentRules.js.map +1 -1
  31. package/dist/flow/DocumentCapture.d.ts +3 -19
  32. package/dist/flow/DocumentCapture.d.ts.map +1 -1
  33. package/dist/flow/DocumentCapture.js +22 -170
  34. package/dist/flow/DocumentCapture.js.map +1 -1
  35. package/dist/flow/SmartComplyFlow.d.ts +0 -1
  36. package/dist/flow/SmartComplyFlow.d.ts.map +1 -1
  37. package/dist/flow/SmartComplyFlow.js +65 -92
  38. package/dist/flow/SmartComplyFlow.js.map +1 -1
  39. package/dist/smartcomply.browser.js +94 -256
  40. package/dist/smartcomply.browser.js.map +3 -3
  41. package/dist/types/onboarding.d.ts +2 -0
  42. package/dist/types/onboarding.d.ts.map +1 -1
  43. package/dist/utils/channels.d.ts +15 -0
  44. package/dist/utils/channels.d.ts.map +1 -1
  45. package/dist/utils/channels.js +44 -0
  46. package/dist/utils/channels.js.map +1 -1
  47. package/dist/utils/constants.d.ts +9 -8
  48. package/dist/utils/constants.d.ts.map +1 -1
  49. package/dist/utils/constants.js +10 -9
  50. package/dist/utils/constants.js.map +1 -1
  51. package/dist/utils/documentRules.d.ts +1 -2
  52. package/dist/utils/documentRules.d.ts.map +1 -1
  53. package/dist/utils/documentRules.js +1 -2
  54. package/dist/utils/documentRules.js.map +1 -1
  55. package/package.json +1 -1
@@ -293,7 +293,7 @@ var SmartComplySDK = (() => {
293
293
  var SESSION_WARN_BEFORE_MS = 2 * 60 * 1e3;
294
294
  var MAX_RETRIES = 2;
295
295
  var RETRY_DELAY_MS = 1e3;
296
- var MAX_DOCUMENT_BYTES = 5 * 1024 * 1024;
296
+ var MAX_DOCUMENT_BYTES = 10 * 1024 * 1024;
297
297
  var MAX_VIDEO_BYTES = 50 * 1024 * 1024;
298
298
  var MAX_SNAPSHOT_BYTES = 2 * 1024 * 1024;
299
299
  var DEFAULT_CHALLENGE_ACTIONS = ["BLINK", "TURN_HEAD"];
@@ -5760,10 +5760,29 @@ var SmartComplySDK = (() => {
5760
5760
  data_verification: isChannelList(byCategory.data_verification) ? byCategory.data_verification : [],
5761
5761
  document_verification: isChannelList(byCategory.document_verification) ? byCategory.document_verification : []
5762
5762
  };
5763
+ if (typeof byCategory.code === "string") grouped[country].code = byCategory.code;
5764
+ if (typeof byCategory.name === "string") grouped[country].name = byCategory.name;
5763
5765
  }
5764
5766
  }
5765
5767
  return grouped;
5766
5768
  }
5769
+ var NO_COUNTRY = "global";
5770
+ function countryCodeFor(channels, country) {
5771
+ if (!country || country === NO_COUNTRY) return NO_COUNTRY;
5772
+ return channels[country]?.code || country;
5773
+ }
5774
+ function countryLabel(channels, country) {
5775
+ const name = channels[country]?.name;
5776
+ if (name) return name;
5777
+ return country.replace(/\b\w/g, (letter) => letter.toUpperCase());
5778
+ }
5779
+ function searchable(text) {
5780
+ return text.normalize("NFD").replace(/[̀-ͯ]/g, "").toLowerCase().trim();
5781
+ }
5782
+ function filterCountries(channels, query) {
5783
+ const needle = searchable(query);
5784
+ return Object.keys(channels).map((country) => ({ country, label: countryLabel(channels, country) })).filter(({ country, label }) => !needle || searchable(label).includes(needle) || searchable(country).includes(needle)).sort((a2, b2) => a2.label.localeCompare(b2.label)).map(({ country }) => country);
5785
+ }
5767
5786
 
5768
5787
  // src/client/Smartcomply.ts
5769
5788
  var _SmartComply = class _SmartComply {
@@ -5886,7 +5905,7 @@ var SmartComplySDK = (() => {
5886
5905
  * CDN tag they installed with (e.g. @1, which floats to the latest
5887
5906
  * matching release) actually resolved to the version they expect.
5888
5907
  */
5889
- _SmartComply.VERSION = "1.0.99";
5908
+ _SmartComply.VERSION = "1.0.101";
5890
5909
  var SmartComply = _SmartComply;
5891
5910
 
5892
5911
  // src/flow/theme.ts
@@ -6566,7 +6585,7 @@ var SmartComplySDK = (() => {
6566
6585
  this.showPdfPreview(container, theme, file, documentType);
6567
6586
  return;
6568
6587
  }
6569
- this.ensureUnderUploadLimit(file).then((c2) => this.handleFileUploadComplete(c2, container, theme, documentType));
6588
+ this.handleFileUploadComplete(file, container, theme, documentType);
6570
6589
  }
6571
6590
  });
6572
6591
  this.root.appendChild(fileInput);
@@ -6980,7 +6999,14 @@ var SmartComplySDK = (() => {
6980
6999
  useBtn.textContent = "Confirming photo…";
6981
7000
  useBtn.disabled = true;
6982
7001
  rotateBtn.disabled = true;
6983
- this.ensureUnderUploadLimit(currentBlob).then((c2) => this.handleCaptureComplete(c2, container, theme, documentType, viaCamera));
7002
+ if (currentBlob.size > MAX_DOCUMENT_BYTES) {
7003
+ useBtn.textContent = "Use Photo ✓";
7004
+ useBtn.disabled = false;
7005
+ rotateBtn.disabled = false;
7006
+ this.showError(this.tooLargeMessage());
7007
+ return;
7008
+ }
7009
+ this.handleCaptureComplete(currentBlob, container, theme, documentType, viaCamera);
6984
7010
  });
6985
7011
  btnRow.appendChild(retakeBtn);
6986
7012
  btnRow.appendChild(useBtn);
@@ -7063,9 +7089,8 @@ var SmartComplySDK = (() => {
7063
7089
  /**
7064
7090
  * Rotate an image blob by a multiple of 90° and re-encode it — used by the
7065
7091
  * preview screen's rotate control for a document photographed or uploaded
7066
- * sideways/upside-down. EXIF auto-rotation (see compressImage) only fixes
7067
- * phone photos that embed correct orientation metadata; it can't help a
7068
- * document whose actual pixel content is sideways (e.g. the phone itself
7092
+ * sideways/upside-down. Orientation metadata can't help a document
7093
+ * whose actual pixel content is sideways (e.g. the phone itself
7069
7094
  * was held rotated relative to the document, or a pre-cropped/scanned
7070
7095
  * upload with no EXIF at all) — that needs the user to say so directly.
7071
7096
  */
@@ -7199,29 +7224,15 @@ var SmartComplySDK = (() => {
7199
7224
  return "Invalid file type. Please upload a JPEG or PNG photo, or a PDF.";
7200
7225
  }
7201
7226
  if (file.size > MAX_DOCUMENT_BYTES) {
7202
- return `File is too large. Please upload a file smaller than ${Math.round(MAX_DOCUMENT_BYTES / (1024 * 1024))}MB.`;
7227
+ return this.tooLargeMessage();
7203
7228
  }
7204
7229
  if (file.size < 1024) {
7205
7230
  return "File is too small. Please upload a valid photo or PDF.";
7206
7231
  }
7207
7232
  return null;
7208
7233
  }
7209
- /**
7210
- * Only shrinks/re-encodes when the file exceeds the backend's real upload
7211
- * ceiling — otherwise returns the original bytes completely untouched.
7212
- * Document photos become the face-comparison reference image later
7213
- * (see backend _crop_and_save_face), so any avoidable re-encode is a
7214
- * quality loss with no upside; compression here exists solely to keep
7215
- * oversized captures under MAX_DOCUMENT_BYTES, not to "optimize" images
7216
- * that already fit.
7217
- */
7218
- async ensureUnderUploadLimit(source) {
7219
- if (source.size <= MAX_DOCUMENT_BYTES) return source;
7220
- try {
7221
- return await this.compressImage(source, DOC_CAMERA_IDEAL_WIDTH, DOC_CAMERA_IDEAL_HEIGHT, 0.92);
7222
- } catch {
7223
- return source;
7224
- }
7234
+ tooLargeMessage() {
7235
+ return `File is too large. Please upload a file smaller than ${Math.round(MAX_DOCUMENT_BYTES / (1024 * 1024))}MB.`;
7225
7236
  }
7226
7237
  handleFileUpload(container, theme) {
7227
7238
  const input = this.root?.querySelector("#sc-doc-file-input");
@@ -7299,141 +7310,6 @@ var SmartComplySDK = (() => {
7299
7310
  });
7300
7311
  return btn;
7301
7312
  }
7302
- compressImage(source, maxWidth, maxHeight, quality) {
7303
- return new Promise((resolve, reject) => {
7304
- this._readExifOrientation(source).then((orientation) => {
7305
- const url = URL.createObjectURL(source);
7306
- const imgEl = document.createElement("img");
7307
- imgEl.onload = () => {
7308
- URL.revokeObjectURL(url);
7309
- let { naturalWidth: w2, naturalHeight: h2 } = imgEl;
7310
- const swapped = orientation >= 5 && orientation <= 8;
7311
- const srcW = swapped ? h2 : w2;
7312
- const srcH = swapped ? w2 : h2;
7313
- const ratio = computeScaleRatio(srcW, srcH, maxWidth, maxHeight);
7314
- const outW = Math.round(srcW * ratio);
7315
- const outH = Math.round(srcH * ratio);
7316
- const canvas = document.createElement("canvas");
7317
- canvas.width = outW;
7318
- canvas.height = outH;
7319
- const ctx = canvas.getContext("2d");
7320
- if (!ctx) {
7321
- reject(new Error("Canvas unavailable"));
7322
- return;
7323
- }
7324
- ctx.save();
7325
- if (orientation === 2) {
7326
- ctx.transform(-1, 0, 0, 1, outW, 0);
7327
- } else if (orientation === 3) {
7328
- ctx.transform(-1, 0, 0, -1, outW, outH);
7329
- } else if (orientation === 4) {
7330
- ctx.transform(1, 0, 0, -1, 0, outH);
7331
- } else if (orientation === 5) {
7332
- ctx.transform(0, 1, 1, 0, 0, 0);
7333
- } else if (orientation === 6) {
7334
- ctx.transform(0, 1, -1, 0, outH, 0);
7335
- } else if (orientation === 7) {
7336
- ctx.transform(0, -1, -1, 0, outH, outW);
7337
- } else if (orientation === 8) {
7338
- ctx.transform(0, -1, 1, 0, 0, outW);
7339
- }
7340
- ctx.drawImage(imgEl, 0, 0, swapped ? outH : outW, swapped ? outW : outH);
7341
- ctx.restore();
7342
- canvas.toBlob(
7343
- (blob) => {
7344
- blob ? resolve(blob) : reject(new Error("Compression failed"));
7345
- },
7346
- "image/jpeg",
7347
- quality
7348
- );
7349
- };
7350
- imgEl.onerror = () => {
7351
- URL.revokeObjectURL(url);
7352
- reject(new Error("Image load failed"));
7353
- };
7354
- imgEl.src = url;
7355
- }).catch(() => {
7356
- const url = URL.createObjectURL(source);
7357
- const imgEl = document.createElement("img");
7358
- imgEl.onload = () => {
7359
- URL.revokeObjectURL(url);
7360
- let { naturalWidth: w2, naturalHeight: h2 } = imgEl;
7361
- const ratio = computeScaleRatio(w2, h2, maxWidth, maxHeight);
7362
- const canvas = document.createElement("canvas");
7363
- canvas.width = Math.round(w2 * ratio);
7364
- canvas.height = Math.round(h2 * ratio);
7365
- const ctx = canvas.getContext("2d");
7366
- if (!ctx) {
7367
- reject(new Error("Canvas unavailable"));
7368
- return;
7369
- }
7370
- ctx.drawImage(imgEl, 0, 0, canvas.width, canvas.height);
7371
- canvas.toBlob(
7372
- (blob) => {
7373
- blob ? resolve(blob) : reject(new Error("Compression failed"));
7374
- },
7375
- "image/jpeg",
7376
- quality
7377
- );
7378
- };
7379
- imgEl.onerror = () => {
7380
- URL.revokeObjectURL(url);
7381
- reject(new Error("Image load failed"));
7382
- };
7383
- imgEl.src = url;
7384
- });
7385
- });
7386
- }
7387
- /**
7388
- * Read JPEG EXIF orientation tag (1–8) from a Blob/File.
7389
- * Returns 1 (no rotation) if EXIF is absent or unreadable.
7390
- */
7391
- _readExifOrientation(source) {
7392
- return new Promise((resolve) => {
7393
- const reader = new FileReader();
7394
- reader.onload = (e2) => {
7395
- try {
7396
- const buf = e2.target?.result;
7397
- const view = new DataView(buf);
7398
- if (view.getUint16(0, false) !== 65496) {
7399
- resolve(1);
7400
- return;
7401
- }
7402
- let offset = 2;
7403
- while (offset < view.byteLength) {
7404
- const marker = view.getUint16(offset, false);
7405
- offset += 2;
7406
- if (marker === 65505) {
7407
- if (view.getUint32(offset + 2, false) !== 1165519206) {
7408
- resolve(1);
7409
- return;
7410
- }
7411
- const little = view.getUint16(offset + 8, false) === 18761;
7412
- const ifdOff = offset + 8 + view.getUint32(offset + 12, little);
7413
- const tags = view.getUint16(ifdOff, little);
7414
- for (let i2 = 0; i2 < tags; i2++) {
7415
- if (view.getUint16(ifdOff + 2 + 12 * i2, little) === 274) {
7416
- resolve(view.getUint16(ifdOff + 2 + 12 * i2 + 8, little));
7417
- return;
7418
- }
7419
- }
7420
- resolve(1);
7421
- return;
7422
- } else if ((marker & 65280) !== 65280) {
7423
- break;
7424
- } else {
7425
- offset += view.getUint16(offset, false);
7426
- }
7427
- }
7428
- resolve(1);
7429
- } catch {
7430
- resolve(1);
7431
- }
7432
- };
7433
- reader.onerror = () => resolve(1);
7434
- reader.readAsArrayBuffer(source.slice(0, 65536));
7435
- });
7436
- }
7437
7313
  getDocumentLabel(type) {
7438
7314
  const t2 = type.toLowerCase();
7439
7315
  if (t2.includes("passport")) return "passport";
@@ -7470,15 +7346,7 @@ var SmartComplySDK = (() => {
7470
7346
  }
7471
7347
  return err?.message || "We couldn't verify your face. Please try again.";
7472
7348
  }
7473
- var COUNTRY_LABELS = {
7474
- nigeria: "🇳🇬 Nigeria",
7475
- global: "🌍 Other Countries",
7476
- ghana: "🇬🇭 Ghana",
7477
- kenya: "🇰🇪 Kenya",
7478
- south_africa: "🇿🇦 South Africa",
7479
- united_states: "🇺🇸 United States",
7480
- united_kingdom: "🇬🇧 United Kingdom"
7481
- };
7349
+ var COUNTRY_SEARCH_MIN = 7;
7482
7350
  function isChannelDocumentFlow(idType, globalDocFlow) {
7483
7351
  if (typeof idType === "string") return globalDocFlow;
7484
7352
  return (idType.fields || []).some((f2) => isUploadFieldType(f2.type));
@@ -7618,24 +7486,6 @@ var SmartComplySDK = (() => {
7618
7486
  const d2 = new Date(s2);
7619
7487
  return isNaN(d2.getTime()) ? null : d2;
7620
7488
  }
7621
- async function _compressImage(blob, maxWidth = 1600, quality = 0.85) {
7622
- try {
7623
- const bmp = await createImageBitmap(blob);
7624
- const scale = Math.min(1, maxWidth / bmp.width);
7625
- const w2 = Math.round(bmp.width * scale);
7626
- const h2 = Math.round(bmp.height * scale);
7627
- const canvas = document.createElement("canvas");
7628
- canvas.width = w2;
7629
- canvas.height = h2;
7630
- canvas.getContext("2d").drawImage(bmp, 0, 0, w2, h2);
7631
- bmp.close();
7632
- return await new Promise(
7633
- (res, rej) => canvas.toBlob((b2) => b2 ? res(b2) : rej(new Error("Compression failed")), "image/jpeg", quality)
7634
- );
7635
- } catch {
7636
- return blob;
7637
- }
7638
- }
7639
7489
  function _formatDocType(code) {
7640
7490
  const map = {
7641
7491
  passport: "Passport",
@@ -8321,18 +8171,50 @@ var SmartComplySDK = (() => {
8321
8171
  subtitle.style.cssText = `color:${this.theme.textSecondary};font-size:13px;margin-top:-8px;`;
8322
8172
  subtitle.textContent = "Choose the country that issued your ID";
8323
8173
  container.appendChild(subtitle);
8324
- for (const country of countries) {
8325
- const count = channels[country].data_verification.length + channels[country].document_verification.length;
8326
- const card = this.createOptionCard(
8327
- COUNTRY_LABELS[country] || country,
8328
- `${count} ID type${count > 1 ? "s" : ""} available`,
8329
- () => {
8330
- this.selectedCountry = country;
8331
- this.showStep("id_type");
8332
- }
8333
- );
8334
- container.appendChild(card);
8174
+ const list = document.createElement("div");
8175
+ list.setAttribute("role", "list");
8176
+ list.style.cssText = "display:flex;flex-direction:column;gap:10px;max-height:min(52vh,420px);overflow-y:auto;padding:2px;";
8177
+ const renderList = (query) => {
8178
+ list.innerHTML = "";
8179
+ const matches = filterCountries(channels, query);
8180
+ if (matches.length === 0) {
8181
+ const empty = document.createElement("div");
8182
+ empty.setAttribute("role", "status");
8183
+ empty.style.cssText = `color:${this.theme.textSecondary};font-size:13px;line-height:1.6;padding:8px 2px;`;
8184
+ empty.textContent = `No country matches "${query.trim()}". Check the spelling or try another name.`;
8185
+ list.appendChild(empty);
8186
+ return;
8187
+ }
8188
+ for (const country of matches) {
8189
+ const count = channels[country].data_verification.length + channels[country].document_verification.length;
8190
+ const card = this.createOptionCard(
8191
+ countryLabel(channels, country),
8192
+ `${count} ID type${count > 1 ? "s" : ""} available`,
8193
+ () => {
8194
+ this.selectedCountry = country;
8195
+ this.showStep("id_type");
8196
+ }
8197
+ );
8198
+ card.setAttribute("role", "listitem");
8199
+ list.appendChild(card);
8200
+ }
8201
+ };
8202
+ if (countries.length >= COUNTRY_SEARCH_MIN) {
8203
+ const search = document.createElement("input");
8204
+ search.type = "search";
8205
+ search.placeholder = "Search countries";
8206
+ search.setAttribute("aria-label", "Search countries");
8207
+ search.autocomplete = "off";
8208
+ search.style.cssText = `
8209
+ width:100%;box-sizing:border-box;padding:11px 14px;border-radius:${RADIUS.md}px;
8210
+ background:${this.theme.cardBg};color:${this.theme.text};
8211
+ border:1.5px solid ${this.theme.border};font-size:14px;outline-offset:2px;
8212
+ `;
8213
+ search.addEventListener("input", () => renderList(search.value));
8214
+ container.appendChild(search);
8335
8215
  }
8216
+ renderList("");
8217
+ container.appendChild(list);
8336
8218
  }
8337
8219
  // ── ID Type Select ──────────────────────────────────────────────
8338
8220
  renderIdTypeSelect(container) {
@@ -8820,7 +8702,13 @@ var SmartComplySDK = (() => {
8820
8702
  faceWrap.appendChild(faceImg);
8821
8703
  container.appendChild(faceWrap);
8822
8704
  }
8823
- if (this._ocrExpirySoon && !this._ocrIsExpired) {
8705
+ if (this._ocrIsExpired) {
8706
+ const expired = document.createElement("div");
8707
+ expired.setAttribute("role", "alert");
8708
+ expired.style.cssText = `width:100%;padding:10px 14px;border-radius:10px;background:${this.theme.errorBg};border:1px solid ${this.theme.error}40;color:${this.theme.error};font-size:12px;text-align:left;line-height:1.5;`;
8709
+ expired.textContent = "⚠️ This document has expired. You can continue, but a check with an expired document won't be approved. Use a valid document if you have one.";
8710
+ container.appendChild(expired);
8711
+ } else if (this._ocrExpirySoon) {
8824
8712
  const warn = document.createElement("div");
8825
8713
  warn.style.cssText = `width:100%;padding:10px 14px;border-radius:10px;background:${this.theme.warning}18;border:1px solid ${this.theme.warning}40;color:${this.theme.warning};font-size:12px;text-align:left;line-height:1.5;`;
8826
8714
  warn.textContent = "⚠️ Your document expires soon. Some services may not accept it, but you can still continue.";
@@ -8903,11 +8791,6 @@ var SmartComplySDK = (() => {
8903
8791
  polls++;
8904
8792
  try {
8905
8793
  const result = await this.sdk.liveness.pollResult(entryId);
8906
- if (result.is_expired === true) {
8907
- container.innerHTML = "";
8908
- this._renderExpiredDocument(container);
8909
- return;
8910
- }
8911
8794
  if (result.ocr_quality_failed === true) {
8912
8795
  container.innerHTML = "";
8913
8796
  this._renderOcrQualityFail(container, result.ocr_rejection_reason);
@@ -8956,35 +8839,6 @@ var SmartComplySDK = (() => {
8956
8839
  };
8957
8840
  this._ocrPollTimer = setTimeout(poll, 3e3);
8958
8841
  }
8959
- _renderExpiredDocument(container) {
8960
- container.style.cssText += "display:flex;flex-direction:column;align-items:center;text-align:center;gap:14px;padding:20px 0;";
8961
- const icon2 = document.createElement("div");
8962
- icon2.style.cssText = `width:72px;height:72px;border-radius:50%;background:${this.theme.errorBg};border:3px solid ${this.theme.error};display:flex;align-items:center;justify-content:center;font-size:28px;`;
8963
- icon2.textContent = "📅";
8964
- container.appendChild(icon2);
8965
- const t2 = document.createElement("h2");
8966
- t2.style.cssText = `color:${this.theme.text};font-size:${TYPE.heading}px;font-weight:700;margin:0;`;
8967
- t2.textContent = "Document Expired";
8968
- container.appendChild(t2);
8969
- const d2 = document.createElement("p");
8970
- d2.style.cssText = `color:${this.theme.textSecondary};font-size:13px;margin:0;max-width:280px;line-height:1.6;`;
8971
- d2.textContent = "The document you submitted has expired. Please use a valid, current ID.";
8972
- container.appendChild(d2);
8973
- const retryBtn = this.createPrimaryButton("Try a different document");
8974
- retryBtn.addEventListener("click", () => {
8975
- this.livenessEntryId = null;
8976
- this.documentBlob = null;
8977
- this.documentBackBlob = null;
8978
- this.showStep("document_capture");
8979
- });
8980
- container.appendChild(retryBtn);
8981
- const endBtn = this.createSecondaryButton("End session");
8982
- endBtn.addEventListener("click", () => {
8983
- this.options.onError?.(new Error("Document expired"));
8984
- this.close();
8985
- });
8986
- container.appendChild(endBtn);
8987
- }
8988
8842
  _renderOcrQualityFail(container, reason) {
8989
8843
  container.style.cssText += "display:flex;flex-direction:column;align-items:center;text-align:center;gap:14px;padding:20px 0;";
8990
8844
  const icon2 = document.createElement("div");
@@ -9148,8 +9002,8 @@ var SmartComplySDK = (() => {
9148
9002
  * Process document capture result with front/back support
9149
9003
  */
9150
9004
  async processDocumentCaptureResult(result, captureContainer, container) {
9151
- this.documentBlob = isPdf(result.front) ? result.front : await _compressImage(result.front, 1600, 0.85);
9152
- this.documentBackBlob = !result.back ? null : isPdf(result.back) ? result.back : await _compressImage(result.back, 1600, 0.85);
9005
+ this.documentBlob = result.front;
9006
+ this.documentBackBlob = result.back || null;
9153
9007
  this._documentViaCamera = result.viaCamera;
9154
9008
  await this.processDocumentBlob(this.documentBlob, captureContainer, container);
9155
9009
  }
@@ -9164,8 +9018,10 @@ var SmartComplySDK = (() => {
9164
9018
  if (!blob || blob.size === 0) {
9165
9019
  throw new Error("Failed to capture document. Please try again.");
9166
9020
  }
9167
- if (blob.size > 5 * 1024 * 1024) {
9168
- throw new Error("Document image is too large. Please retake in better lighting or use a clearer photo.");
9021
+ if (blob.size > MAX_DOCUMENT_BYTES) {
9022
+ throw new Error(
9023
+ `Document is too large. Please use a file smaller than ${Math.round(MAX_DOCUMENT_BYTES / (1024 * 1024))}MB.`
9024
+ );
9169
9025
  }
9170
9026
  this.documentBlob = blob;
9171
9027
  captureContainer.innerHTML = "";
@@ -9175,16 +9031,7 @@ var SmartComplySDK = (() => {
9175
9031
  <div style="color:${this.theme.text};font-size:14px;font-weight:600;">Scanning document...</div>
9176
9032
  <div style="color:${this.theme.textSecondary};font-size:12px;text-align:center;max-width:200px;line-height:1.5;">Running OCR and verifying your identity</div>`);
9177
9033
  const identifier = Object.values(this.collectedFields)[0] || this.idNumber || this.selectedIdType || `DOC-${Date.now()}`;
9178
- const COUNTRY_CODES = {
9179
- nigeria: "NG",
9180
- ghana: "GH",
9181
- kenya: "KE",
9182
- south_africa: "ZA",
9183
- united_states: "US",
9184
- united_kingdom: "GB",
9185
- global: "US"
9186
- };
9187
- const country = COUNTRY_CODES[this.selectedCountry] || this.selectedCountry.toUpperCase().slice(0, 2);
9034
+ const country = countryCodeFor(this.sdkConfig?.channels || {}, this.selectedCountry);
9188
9035
  const deviceMeta = collectDeviceMetadata();
9189
9036
  let createResult;
9190
9037
  try {
@@ -9331,16 +9178,7 @@ var SmartComplySDK = (() => {
9331
9178
  const isDataVerification = !!this.identityCheckId;
9332
9179
  const identifier = isDataVerification ? "" : this.idNumber || Object.values(this.collectedFields)[0] || this.selectedIdType || `DOC-${Date.now()}`;
9333
9180
  const identifierType = isDataVerification ? "" : this.selectedIdType;
9334
- const COUNTRY_CODES = {
9335
- nigeria: "NG",
9336
- ghana: "GH",
9337
- kenya: "KE",
9338
- south_africa: "ZA",
9339
- united_states: "US",
9340
- united_kingdom: "GB",
9341
- global: "US"
9342
- };
9343
- const country = COUNTRY_CODES[this.selectedCountry] || this.selectedCountry.toUpperCase().slice(0, 2);
9181
+ const country = countryCodeFor(this.sdkConfig?.channels || {}, this.selectedCountry);
9344
9182
  this.sdk.liveness.startCheck(
9345
9183
  livenessContainer,
9346
9184
  {