smartcomply-web-sdk 1.0.51 → 1.0.52

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 (35) hide show
  1. package/dist/camera/ActionDetector.d.ts +0 -5
  2. package/dist/camera/ActionDetector.d.ts.map +1 -1
  3. package/dist/camera/ActionDetector.js +1 -12
  4. package/dist/camera/ActionDetector.js.map +1 -1
  5. package/dist/esm/camera/ActionDetector.d.ts +0 -5
  6. package/dist/esm/camera/ActionDetector.d.ts.map +1 -1
  7. package/dist/esm/camera/ActionDetector.js +1 -12
  8. package/dist/esm/camera/ActionDetector.js.map +1 -1
  9. package/dist/esm/flow/SmartComplyFlow.js +144 -144
  10. package/dist/esm/flow/SmartComplyFlow.js.map +1 -1
  11. package/dist/esm/modules/liveness/LivenessUI.d.ts +0 -2
  12. package/dist/esm/modules/liveness/LivenessUI.d.ts.map +1 -1
  13. package/dist/esm/modules/liveness/LivenessUI.js.map +1 -1
  14. package/dist/esm/modules/liveness/liveness.d.ts.map +1 -1
  15. package/dist/esm/modules/liveness/liveness.js +1 -3
  16. package/dist/esm/modules/liveness/liveness.js.map +1 -1
  17. package/dist/esm/utils/constants.d.ts +0 -2
  18. package/dist/esm/utils/constants.d.ts.map +1 -1
  19. package/dist/esm/utils/constants.js +0 -2
  20. package/dist/esm/utils/constants.js.map +1 -1
  21. package/dist/flow/SmartComplyFlow.js +144 -144
  22. package/dist/flow/SmartComplyFlow.js.map +1 -1
  23. package/dist/modules/liveness/LivenessUI.d.ts +0 -2
  24. package/dist/modules/liveness/LivenessUI.d.ts.map +1 -1
  25. package/dist/modules/liveness/LivenessUI.js.map +1 -1
  26. package/dist/modules/liveness/liveness.d.ts.map +1 -1
  27. package/dist/modules/liveness/liveness.js +1 -3
  28. package/dist/modules/liveness/liveness.js.map +1 -1
  29. package/dist/smartcomply.browser.js +86 -100
  30. package/dist/smartcomply.browser.js.map +2 -2
  31. package/dist/utils/constants.d.ts +0 -2
  32. package/dist/utils/constants.d.ts.map +1 -1
  33. package/dist/utils/constants.js +1 -3
  34. package/dist/utils/constants.js.map +1 -1
  35. package/package.json +1 -1
@@ -4460,8 +4460,7 @@ var SmartComplySDK = (() => {
4460
4460
  var BLINK_HOLD_FRAMES = 2;
4461
4461
  var YAW_MOTION_THRESHOLD_DEG = 6;
4462
4462
  var ActionDetector = class {
4463
- /** Kept for API compatibility with callers that still pass a list in. Unused internally. */
4464
- constructor(_requiredActions) {
4463
+ constructor() {
4465
4464
  this.blinkHoldCount = 0;
4466
4465
  this.blinkDetected = false;
4467
4466
  this.motionDetected = false;
@@ -4498,24 +4497,13 @@ var SmartComplySDK = (() => {
4498
4497
  faceDetected,
4499
4498
  blinkDetected: this.blinkDetected,
4500
4499
  motionDetected: this.motionDetected,
4501
- livenessConfirmed: this.blinkDetected || this.motionDetected,
4502
- progress: 0
4503
- // caller fills in time-based progress
4500
+ livenessConfirmed: this.blinkDetected || this.motionDetected
4504
4501
  };
4505
4502
  }
4506
4503
  getHeadYaw(matrix) {
4507
4504
  if (!matrix || matrix.length < 16) return 0;
4508
4505
  return Math.atan2(-matrix[2], matrix[0]) * (180 / Math.PI);
4509
4506
  }
4510
- livenessConfirmed() {
4511
- return this.blinkDetected || this.motionDetected;
4512
- }
4513
- reset() {
4514
- this.blinkHoldCount = 0;
4515
- this.blinkDetected = false;
4516
- this.motionDetected = false;
4517
- this.baselineYaw = null;
4518
- }
4519
4507
  };
4520
4508
 
4521
4509
  // src/modules/liveness/LivenessUI.ts
@@ -4970,7 +4958,7 @@ var SmartComplySDK = (() => {
4970
4958
  tempVideo.muted = true;
4971
4959
  tempVideo.playsInline = true;
4972
4960
  await tempVideo.play();
4973
- ui2.mount(container, { actions: [], time_limit_seconds: 0, instruction: "Centre your face in the oval" });
4961
+ ui2.mount(container, { time_limit_seconds: 0, instruction: "Centre your face in the oval" });
4974
4962
  const uiVideo = ui2.getVideoElement();
4975
4963
  if (uiVideo) {
4976
4964
  uiVideo.srcObject = stream;
@@ -4983,7 +4971,6 @@ var SmartComplySDK = (() => {
4983
4971
  ui2.updateInstruction("Centre your face in the oval");
4984
4972
  const videoForDetection = uiVideo || tempVideo;
4985
4973
  await new Promise((resolve) => {
4986
- let attempts = 0;
4987
4974
  let stableFrames = 0;
4988
4975
  let missedFrames = 0;
4989
4976
  const STABLE_REQUIRED = 4;
@@ -5045,7 +5032,6 @@ var SmartComplySDK = (() => {
5045
5032
  tempVideo.srcObject = null;
5046
5033
  tempVideo.remove();
5047
5034
  const uiChallenge = {
5048
- actions: entry.challenge_actions,
5049
5035
  time_limit_seconds: LIVENESS_TIME_LIMIT_SECONDS,
5050
5036
  instruction: "Blink and look around naturally"
5051
5037
  };
@@ -6347,13 +6333,13 @@ var SmartComplySDK = (() => {
6347
6333
 
6348
6334
  // src/flow/SmartComplyFlow.ts
6349
6335
  var COUNTRY_LABELS = {
6350
- nigeria: "🇳🇬 Nigeria",
6351
- global: "🌍 Other Countries",
6352
- ghana: "🇬🇭 Ghana",
6353
- kenya: "🇰🇪 Kenya",
6354
- south_africa: "🇿🇦 South Africa",
6355
- united_states: "🇺🇸 United States",
6356
- united_kingdom: "🇬🇧 United Kingdom"
6336
+ nigeria: "🇳🇬 Nigeria",
6337
+ global: "🌍 Other Countries",
6338
+ ghana: "🇬🇭 Ghana",
6339
+ kenya: "🇰🇪 Kenya",
6340
+ south_africa: "🇿🇦 South Africa",
6341
+ united_states: "🇺🇸 United States",
6342
+ united_kingdom: "🇬🇧 United Kingdom"
6357
6343
  };
6358
6344
  function isUploadFieldType(type) {
6359
6345
  return type === "upload" || type === "image" || type === "file";
@@ -6367,37 +6353,37 @@ var SmartComplySDK = (() => {
6367
6353
  return t2.includes("voter") || t2.includes("driver") || t2.includes("license") || t2.includes("national id") || t2.includes("national id card");
6368
6354
  };
6369
6355
  if (u2.includes("BVN") || u2.includes("BANK VERIFICATION")) {
6370
- return { icon: "🏦", desc: "Enter your 11-digit Bank Verification Number (BVN)", requiresBack: false };
6356
+ return { icon: "🏦", desc: "Enter your 11-digit Bank Verification Number (BVN)", requiresBack: false };
6371
6357
  }
6372
6358
  if (u2.includes("NIN") || u2.includes("NATIONAL IDENTITY NUMBER")) {
6373
- return { icon: "🆔", desc: "Enter your 11-digit National Identification Number (NIN)", requiresBack: false };
6359
+ return { icon: "🆔", desc: "Enter your 11-digit National Identification Number (NIN)", requiresBack: false };
6374
6360
  }
6375
6361
  if (u2.includes("GHANA")) {
6376
- if (isDocumentFlow) return { icon: "🪪", desc: "Capture or upload your Ghana Card", requiresBack: true };
6377
- return { icon: "🪪", desc: "Enter your Ghana Card number", requiresBack: false };
6362
+ if (isDocumentFlow) return { icon: "🪪", desc: "Capture or upload your Ghana Card", requiresBack: true };
6363
+ return { icon: "🪪", desc: "Enter your Ghana Card number", requiresBack: false };
6378
6364
  }
6379
6365
  if (u2.includes("SSNIT"))
6380
- return { icon: "🏛️", desc: "Enter your SSNIT number", requiresBack: false };
6366
+ return { icon: "🏛️", desc: "Enter your SSNIT number", requiresBack: false };
6381
6367
  if (u2.includes("KENYA") || u2.includes("NATIONAL") && u2.includes("KENYA"))
6382
- return { icon: "🆔", desc: "Enter your Kenya National ID number", requiresBack: false };
6368
+ return { icon: "🆔", desc: "Enter your Kenya National ID number", requiresBack: false };
6383
6369
  if (u2.includes("TIN") || u2.includes("TAX IDENTIFICATION"))
6384
- return { icon: "🧾", desc: "Enter your Tax Identification Number (TIN)", requiresBack: false };
6370
+ return { icon: "🧾", desc: "Enter your Tax Identification Number (TIN)", requiresBack: false };
6385
6371
  if (u2.includes("CAC") || u2.includes("CORPORATE AFFAIRS") || u2.includes("COMPANY"))
6386
- return { icon: "🏢", desc: advanced ? "Enter RC number, company name & type" : "Enter your company registration number", requiresBack: false };
6372
+ return { icon: "🏢", desc: advanced ? "Enter RC number, company name & type" : "Enter your company registration number", requiresBack: false };
6387
6373
  if (u2.includes("VOTER") || u2.includes("PVC")) {
6388
6374
  const requiresBack = requiresBackSide(typeName);
6389
6375
  return {
6390
- icon: "🗳️",
6376
+ icon: "🗳️",
6391
6377
  desc: isDocumentFlow ? `Capture or upload your voter's card${requiresBack ? " (front & back)" : ""}` : "Enter your voter ID number",
6392
6378
  requiresBack: isDocumentFlow ? requiresBack : false
6393
6379
  };
6394
6380
  }
6395
6381
  if (u2.includes("PASSPORT"))
6396
- return { icon: "📘", desc: isDocumentFlow ? "Capture or upload your passport" : "Enter your passport number", requiresBack: false };
6382
+ return { icon: "📘", desc: isDocumentFlow ? "Capture or upload your passport" : "Enter your passport number", requiresBack: false };
6397
6383
  if (u2.includes("DRIVER") || u2.includes("LICENSE") || u2.includes("LICENCE")) {
6398
6384
  const requiresBack = requiresBackSide(typeName);
6399
6385
  return {
6400
- icon: "🚗",
6386
+ icon: "🚗",
6401
6387
  desc: isDocumentFlow ? `Capture or upload your driver's license${requiresBack ? " (front & back)" : ""}` : "Enter your driver's license number",
6402
6388
  requiresBack: isDocumentFlow ? requiresBack : false
6403
6389
  };
@@ -6405,15 +6391,15 @@ var SmartComplySDK = (() => {
6405
6391
  if (u2.includes("NATIONAL ID") || u2.includes("NATIONAL") && u2.includes("CARD")) {
6406
6392
  const requiresBack = requiresBackSide(typeName);
6407
6393
  return {
6408
- icon: "🪪",
6394
+ icon: "🪪",
6409
6395
  desc: isDocumentFlow ? `Capture or upload your ID card${requiresBack ? " (front & back)" : ""}` : "Enter your National ID number",
6410
6396
  requiresBack: isDocumentFlow ? requiresBack : false
6411
6397
  };
6412
6398
  }
6413
6399
  if (u2.includes("LIVENESS") || u2.includes("FACE COMPARISON") || u2.includes("FACE MATCH"))
6414
- return { icon: "🤳", desc: "We'll capture a short selfie video to verify you", requiresBack: false };
6400
+ return { icon: "🤳", desc: "We'll capture a short selfie video to verify you", requiresBack: false };
6415
6401
  return {
6416
- icon: isDocumentFlow ? "📄" : "🆔",
6402
+ icon: isDocumentFlow ? "📄" : "🆔",
6417
6403
  desc: isDocumentFlow ? "Capture or upload your document" : "Enter your ID number",
6418
6404
  requiresBack: false
6419
6405
  };
@@ -6551,7 +6537,7 @@ var SmartComplySDK = (() => {
6551
6537
  this.livenessEntryId = null;
6552
6538
  this.isDestroyed = false;
6553
6539
  this.headerBackBtn = null;
6554
- // Retry safety — max 3 confirmation rejections or liveness failures per session
6540
+ // Retry safety — max 3 confirmation rejections or liveness failures per session
6555
6541
  this._confirmRetries = 0;
6556
6542
  this._livenessFailures = 0;
6557
6543
  // IVS result stored for confirm_identity screen
@@ -6566,9 +6552,9 @@ var SmartComplySDK = (() => {
6566
6552
  this._ocrExpirySoon = false;
6567
6553
  // Camera pre-warm stream (created during confirmation screen, used in liveness)
6568
6554
  this._prewarmedStream = null;
6569
- // OCR gate poll timer — stored so it can be cancelled on navigation or close
6555
+ // OCR gate poll timer — stored so it can be cancelled on navigation or close
6570
6556
  this._ocrPollTimer = null;
6571
- // UI timeout from _startStatusPolling — stored so close() can cancel it
6557
+ // UI timeout from _startStatusPolling — stored so close() can cancel it
6572
6558
  this._uiTimeoutId = null;
6573
6559
  // Session expiry
6574
6560
  this.sessionExpiryTimer = null;
@@ -6643,9 +6629,9 @@ var SmartComplySDK = (() => {
6643
6629
  }
6644
6630
  this.options.onClose?.();
6645
6631
  }
6646
- // ─────────────────────────────────────────────────────────────────
6632
+ // ─────────────────────────────────────────────────────────────────
6647
6633
  // Initialization
6648
- // ─────────────────────────────────────────────────────────────────
6634
+ // ─────────────────────────────────────────────────────────────────
6649
6635
  mount() {
6650
6636
  this.injectStyles();
6651
6637
  this.overlay = document.createElement("div");
@@ -6730,9 +6716,9 @@ var SmartComplySDK = (() => {
6730
6716
  this.showErrorStep(err.message || "Failed to initialize. Please try again.");
6731
6717
  }
6732
6718
  }
6733
- // ─────────────────────────────────────────────────────────────────
6719
+ // ─────────────────────────────────────────────────────────────────
6734
6720
  // Step rendering
6735
- // ─────────────────────────────────────────────────────────────────
6721
+ // ─────────────────────────────────────────────────────────────────
6736
6722
  showStep(step) {
6737
6723
  this.currentStep = step;
6738
6724
  if (!this.contentArea) return;
@@ -6807,7 +6793,7 @@ var SmartComplySDK = (() => {
6807
6793
  wrapper.style.transform = "translateX(0)";
6808
6794
  });
6809
6795
  }
6810
- // ── Loading ─────────────────────────────────────────────────────
6796
+ // ── Loading ─────────────────────────────────────────────────────
6811
6797
  renderLoading(container) {
6812
6798
  container.style.cssText += "display:flex;flex-direction:column;align-items:center;justify-content:center;min-height:300px;gap:16px;";
6813
6799
  const spinnerWrap = document.createElement("div");
@@ -6838,7 +6824,7 @@ var SmartComplySDK = (() => {
6838
6824
  sub.textContent = "Connecting to the verification service...";
6839
6825
  container.appendChild(sub);
6840
6826
  }
6841
- // ── Welcome ────────────────────────────────────────────────────
6827
+ // ── Welcome ────────────────────────────────────────────────────
6842
6828
  renderWelcome(container) {
6843
6829
  container.style.cssText += "display:flex;flex-direction:column;align-items:center;text-align:center;gap:12px;";
6844
6830
  const isDocFlow = this.isDocumentFlow();
@@ -6852,7 +6838,7 @@ var SmartComplySDK = (() => {
6852
6838
  background:linear-gradient(135deg,${this.theme.primary}22,${this.theme.primaryGlow});
6853
6839
  border:1.5px solid ${this.theme.primary}33;
6854
6840
  `;
6855
- iconWrap.textContent = isDocFlow ? "🪪" : "🛡️";
6841
+ iconWrap.textContent = isDocFlow ? "🪪" : "🛡️";
6856
6842
  topRow.appendChild(iconWrap);
6857
6843
  const badge = document.createElement("div");
6858
6844
  badge.style.cssText = `
@@ -6863,7 +6849,7 @@ var SmartComplySDK = (() => {
6863
6849
  color:${this.theme.primary};
6864
6850
  border:1px solid ${this.theme.primary}30;
6865
6851
  `;
6866
- badge.textContent = isDocFlow ? "📄 Document Verification" : "🔍 Data Verification";
6852
+ badge.textContent = isDocFlow ? "📄 Document Verification" : "🔍 Data Verification";
6867
6853
  topRow.appendChild(badge);
6868
6854
  container.appendChild(topRow);
6869
6855
  const titleWrap = document.createElement("div");
@@ -6885,13 +6871,13 @@ var SmartComplySDK = (() => {
6885
6871
  titleWrap.appendChild(desc);
6886
6872
  container.appendChild(titleWrap);
6887
6873
  const steps = isDocFlow ? [
6888
- { icon: "🪪", text: "Choose your document type", sub: "Passport, National ID, Driver License" },
6889
- { icon: "📷", text: "Scan your document", sub: "Upload or capture a photo of your ID" },
6890
- { icon: "🤳", text: "Face check", sub: "Quick selfie to confirm it's you" }
6874
+ { icon: "🪪", text: "Choose your document type", sub: "Passport, National ID, Driver License" },
6875
+ { icon: "📷", text: "Scan your document", sub: "Upload or capture a photo of your ID" },
6876
+ { icon: "🤳", text: "Face check", sub: "Quick selfie to confirm it's you" }
6891
6877
  ] : [
6892
- { icon: "🆔", text: "Choose your ID type", sub: "NIN, BVN, Voter's Card and more" },
6893
- { icon: "📝", text: "Enter your ID details", sub: "Exactly as shown on your ID" },
6894
- { icon: "🤳", text: "Face check", sub: "Quick selfie to confirm it's you" }
6878
+ { icon: "🆔", text: "Choose your ID type", sub: "NIN, BVN, Voter's Card and more" },
6879
+ { icon: "📝", text: "Enter your ID details", sub: "Exactly as shown on your ID" },
6880
+ { icon: "🤳", text: "Face check", sub: "Quick selfie to confirm it's you" }
6895
6881
  ];
6896
6882
  const stepsWrap = document.createElement("div");
6897
6883
  stepsWrap.style.cssText = `
@@ -6931,7 +6917,7 @@ var SmartComplySDK = (() => {
6931
6917
  stepsWrap.appendChild(row);
6932
6918
  });
6933
6919
  container.appendChild(stepsWrap);
6934
- const btn = this.createPrimaryButton("Get Started →");
6920
+ const btn = this.createPrimaryButton("Get Started →");
6935
6921
  btn.style.cssText += "margin-top:2px;";
6936
6922
  btn.addEventListener("click", () => this.showStep("country"));
6937
6923
  container.appendChild(btn);
@@ -6940,10 +6926,10 @@ var SmartComplySDK = (() => {
6940
6926
  display:flex;align-items:center;gap:6px;
6941
6927
  color:${this.theme.textMuted};font-size:10.5px;
6942
6928
  `;
6943
- trust.textContent = "🔒 End-to-end encrypted";
6929
+ trust.textContent = "🔒 End-to-end encrypted";
6944
6930
  container.appendChild(trust);
6945
6931
  }
6946
- // ── Country Select ──────────────────────────────────────────────
6932
+ // ── Country Select ──────────────────────────────────────────────
6947
6933
  renderCountrySelect(container) {
6948
6934
  container.style.cssText += "display:flex;flex-direction:column;gap:14px;";
6949
6935
  const channels = this.sdkConfig?.channels || {};
@@ -6971,7 +6957,7 @@ var SmartComplySDK = (() => {
6971
6957
  container.appendChild(card);
6972
6958
  }
6973
6959
  }
6974
- // ── ID Type Select ──────────────────────────────────────────────
6960
+ // ── ID Type Select ──────────────────────────────────────────────
6975
6961
  renderIdTypeSelect(container) {
6976
6962
  container.style.cssText += "display:flex;flex-direction:column;gap:14px;";
6977
6963
  const globalDocFlow = this.isDocumentFlow();
@@ -6993,7 +6979,7 @@ var SmartComplySDK = (() => {
6993
6979
  const requiresBack = requiresBackFromBackend ?? info.requiresBack;
6994
6980
  let subtitle2 = info.desc;
6995
6981
  if (requiresBack && isThisDocFlow) {
6996
- subtitle2 += " ⚠️ Both sides required";
6982
+ subtitle2 += " ⚠️ Both sides required";
6997
6983
  }
6998
6984
  const displayName = typeName.replace(/\s*with\s+face\s*/gi, " ").replace(/\s*\(NIN\)\s*/gi, " ").replace(/\s*\(BVN\)\s*/gi, " ").replace(/\s{2,}/g, " ").trim();
6999
6985
  const card = this.createOptionCard(
@@ -7026,7 +7012,7 @@ var SmartComplySDK = (() => {
7026
7012
  container.appendChild(card);
7027
7013
  }
7028
7014
  }
7029
- // ── ID Input (data verification — dynamic fields) ─────────────
7015
+ // ── ID Input (data verification — dynamic fields) ─────────────
7030
7016
  renderIdInput(container) {
7031
7017
  container.style.cssText += "display:flex;flex-direction:column;gap:14px;";
7032
7018
  const dataFields = this.selectedChannelFields.filter((f2) => f2.type !== "upload");
@@ -7056,13 +7042,13 @@ var SmartComplySDK = (() => {
7056
7042
  { match: "BVN", rule: { minLen: 11, maxLen: 11, numeric: true, hint: "BVN must be exactly 11 digits" } },
7057
7043
  { match: "NIN", rule: { minLen: 11, maxLen: 11, numeric: true, hint: "NIN must be exactly 11 digits" } },
7058
7044
  { match: "NATIONAL IDENTITY", rule: { minLen: 11, maxLen: 11, numeric: true, hint: "NIN must be exactly 11 digits" } },
7059
- { match: "PASSPORT", rule: { minLen: 6, maxLen: 20, alphanumeric: true, hint: "Passport number must be 6–20 alphanumeric characters" } },
7060
- { match: "DRIVER", rule: { minLen: 3, maxLen: 30, alphanumeric: true, hint: "Licence number must be 3–30 alphanumeric characters" } },
7061
- { match: "VOTER", rule: { minLen: 6, maxLen: 30, alphanumeric: true, hint: "Voter ID must be 6–30 alphanumeric characters" } },
7062
- { match: "GHANA", rule: { minLen: 8, maxLen: 20, alphanumeric: true, hint: "Ghana Card number must be 8–20 alphanumeric characters" } },
7063
- { match: "SSNIT", rule: { minLen: 7, maxLen: 15, alphanumeric: true, hint: "SSNIT number must be 7–15 alphanumeric characters" } },
7064
- { match: "TIN", rule: { minLen: 8, maxLen: 20, alphanumeric: true, hint: "TIN must be 8–20 characters" } },
7065
- { match: "KRA", rule: { minLen: 10, maxLen: 12, alphanumeric: true, hint: "KRA PIN must be 10–12 characters" } }
7045
+ { match: "PASSPORT", rule: { minLen: 6, maxLen: 20, alphanumeric: true, hint: "Passport number must be 6–20 alphanumeric characters" } },
7046
+ { match: "DRIVER", rule: { minLen: 3, maxLen: 30, alphanumeric: true, hint: "Licence number must be 3–30 alphanumeric characters" } },
7047
+ { match: "VOTER", rule: { minLen: 6, maxLen: 30, alphanumeric: true, hint: "Voter ID must be 6–30 alphanumeric characters" } },
7048
+ { match: "GHANA", rule: { minLen: 8, maxLen: 20, alphanumeric: true, hint: "Ghana Card number must be 8–20 alphanumeric characters" } },
7049
+ { match: "SSNIT", rule: { minLen: 7, maxLen: 15, alphanumeric: true, hint: "SSNIT number must be 7–15 alphanumeric characters" } },
7050
+ { match: "TIN", rule: { minLen: 8, maxLen: 20, alphanumeric: true, hint: "TIN must be 8–20 characters" } },
7051
+ { match: "KRA", rule: { minLen: 10, maxLen: 12, alphanumeric: true, hint: "KRA PIN must be 10–12 characters" } }
7066
7052
  ];
7067
7053
  function getFieldRule(label) {
7068
7054
  const upper = label.toUpperCase();
@@ -7302,7 +7288,7 @@ var SmartComplySDK = (() => {
7302
7288
  setTimeout(() => firstInput.focus(), 350);
7303
7289
  }
7304
7290
  }
7305
- // ── Document Capture ────────────────────────────────────────────
7291
+ // ── Document Capture ────────────────────────────────────────────
7306
7292
  renderDocumentCapture(container) {
7307
7293
  container.style.cssText += "display:flex;flex-direction:column;gap:14px;";
7308
7294
  const rawName = this.selectedIdTypeName || this.selectedIdType || "your document";
@@ -7338,7 +7324,7 @@ var SmartComplySDK = (() => {
7338
7324
  this.showErrorStep(err.message || "Document capture failed. Please try again.");
7339
7325
  });
7340
7326
  }
7341
- // ── W3: Identity Confirmation (data verification) ───────────────
7327
+ // ── W3: Identity Confirmation (data verification) ───────────────
7342
7328
  renderConfirmIdentity(container) {
7343
7329
  container.style.cssText += "display:flex;flex-direction:column;align-items:center;text-align:center;gap:16px;padding:8px 0;";
7344
7330
  if (this._confirmRetries >= _SmartComplyFlow.MAX_RETRIES) {
@@ -7348,7 +7334,7 @@ var SmartComplySDK = (() => {
7348
7334
  this._prewarmCamera();
7349
7335
  const iconWrap = document.createElement("div");
7350
7336
  iconWrap.style.cssText = `width:64px;height:64px;border-radius:50%;background:${this.theme.primary}15;border:2px solid ${this.theme.primary}30;display:flex;align-items:center;justify-content:center;font-size:28px;`;
7351
- iconWrap.textContent = "🛡️";
7337
+ iconWrap.textContent = "🛡️";
7352
7338
  container.appendChild(iconWrap);
7353
7339
  const title = document.createElement("h2");
7354
7340
  title.style.cssText = `color:${this.theme.text};font-size:18px;font-weight:700;margin:0;`;
@@ -7385,7 +7371,7 @@ var SmartComplySDK = (() => {
7385
7371
  sub.textContent = "Your details have been confirmed. Please continue to the face check.";
7386
7372
  container.appendChild(sub);
7387
7373
  }
7388
- const yesBtn = this.createPrimaryButton("Yes, that's me — continue");
7374
+ const yesBtn = this.createPrimaryButton("Yes, that's me — continue");
7389
7375
  yesBtn.addEventListener("click", () => {
7390
7376
  this._confirmRetries = 0;
7391
7377
  this.showStep("liveness");
@@ -7402,7 +7388,7 @@ var SmartComplySDK = (() => {
7402
7388
  });
7403
7389
  container.appendChild(noBtn);
7404
7390
  }
7405
- // ── W4: Document Confirmation (document verification) ────────────
7391
+ // ── W4: Document Confirmation (document verification) ────────────
7406
7392
  renderDocumentConfirm(container) {
7407
7393
  container.style.cssText += "display:flex;flex-direction:column;align-items:center;text-align:center;gap:14px;padding:8px 0;";
7408
7394
  if (this._confirmRetries >= _SmartComplyFlow.MAX_RETRIES) {
@@ -7412,7 +7398,7 @@ var SmartComplySDK = (() => {
7412
7398
  this._prewarmCamera();
7413
7399
  const iconWrap = document.createElement("div");
7414
7400
  iconWrap.style.cssText = `width:64px;height:64px;border-radius:50%;background:${this.theme.primary}15;border:2px solid ${this.theme.primary}30;display:flex;align-items:center;justify-content:center;font-size:28px;`;
7415
- iconWrap.textContent = "📄";
7401
+ iconWrap.textContent = "📄";
7416
7402
  container.appendChild(iconWrap);
7417
7403
  const title = document.createElement("h2");
7418
7404
  title.style.cssText = `color:${this.theme.text};font-size:18px;font-weight:700;margin:0;`;
@@ -7435,7 +7421,7 @@ var SmartComplySDK = (() => {
7435
7421
  if (this._ocrExpirySoon && !this._ocrIsExpired) {
7436
7422
  const warn = document.createElement("div");
7437
7423
  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;`;
7438
- warn.textContent = "⚠️ Your document expires soon. Some services may not accept it, but you can still continue.";
7424
+ warn.textContent = "⚠️ Your document expires soon. Some services may not accept it, but you can still continue.";
7439
7425
  container.appendChild(warn);
7440
7426
  }
7441
7427
  const card = document.createElement("div");
@@ -7489,7 +7475,7 @@ var SmartComplySDK = (() => {
7489
7475
  });
7490
7476
  container.appendChild(noBtn);
7491
7477
  }
7492
- // ── W6+W7+W8: OCR Gate (document verification) ───────────────────
7478
+ // ── W6+W7+W8: OCR Gate (document verification) ───────────────────
7493
7479
  renderOcrGate(container) {
7494
7480
  container.style.cssText += "display:flex;flex-direction:column;align-items:center;gap:14px;padding:20px 0;text-align:center;";
7495
7481
  const spinnerWrap = document.createElement("div");
@@ -7498,18 +7484,18 @@ var SmartComplySDK = (() => {
7498
7484
  ring.style.cssText = `position:absolute;inset:0;border-radius:50%;border:3px solid ${this.theme.border};border-top-color:${this.theme.primary};animation:sc-spin 0.9s linear infinite;`;
7499
7485
  const centre = document.createElement("div");
7500
7486
  centre.style.cssText = "position:absolute;inset:0;display:flex;align-items:center;justify-content:center;font-size:20px;";
7501
- centre.textContent = "📄";
7487
+ centre.textContent = "📄";
7502
7488
  spinnerWrap.appendChild(ring);
7503
7489
  spinnerWrap.appendChild(centre);
7504
7490
  container.appendChild(spinnerWrap);
7505
7491
  const statusEl = document.createElement("div");
7506
7492
  statusEl.setAttribute("aria-live", "polite");
7507
7493
  statusEl.style.cssText = `color:${this.theme.text};font-size:15px;font-weight:600;`;
7508
- statusEl.textContent = "Reading your document…";
7494
+ statusEl.textContent = "Reading your document…";
7509
7495
  container.appendChild(statusEl);
7510
7496
  const subEl = document.createElement("div");
7511
7497
  subEl.style.cssText = `color:${this.theme.textSecondary};font-size:12px;max-width:260px;line-height:1.5;`;
7512
- subEl.textContent = "This usually takes 5–15 seconds. Please wait.";
7498
+ subEl.textContent = "This usually takes 5–15 seconds. Please wait.";
7513
7499
  container.appendChild(subEl);
7514
7500
  if (!this.livenessEntryId) {
7515
7501
  this.showErrorStep("Document upload failed. Please try again.");
@@ -7554,8 +7540,8 @@ var SmartComplySDK = (() => {
7554
7540
  if (polls < MAX_POLLS && !this.isDestroyed) {
7555
7541
  this._ocrPollTimer = setTimeout(poll, 2e3);
7556
7542
  } else if (!this.isDestroyed) {
7557
- statusEl.textContent = "Taking longer than usual…";
7558
- subEl.textContent = "We'll continue — you can confirm your details on the next screen.";
7543
+ statusEl.textContent = "Taking longer than usual…";
7544
+ subEl.textContent = "We'll continue — you can confirm your details on the next screen.";
7559
7545
  this._ocrPollTimer = setTimeout(() => {
7560
7546
  if (!this.isDestroyed) this.showStep("document_confirm");
7561
7547
  }, 2e3);
@@ -7574,7 +7560,7 @@ var SmartComplySDK = (() => {
7574
7560
  container.style.cssText += "display:flex;flex-direction:column;align-items:center;text-align:center;gap:14px;padding:20px 0;";
7575
7561
  const icon = document.createElement("div");
7576
7562
  icon.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;`;
7577
- icon.textContent = "📅";
7563
+ icon.textContent = "📅";
7578
7564
  container.appendChild(icon);
7579
7565
  const t2 = document.createElement("h2");
7580
7566
  t2.style.cssText = `color:${this.theme.text};font-size:18px;font-weight:700;margin:0;`;
@@ -7603,7 +7589,7 @@ var SmartComplySDK = (() => {
7603
7589
  container.style.cssText += "display:flex;flex-direction:column;align-items:center;text-align:center;gap:14px;padding:20px 0;";
7604
7590
  const icon = document.createElement("div");
7605
7591
  icon.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;`;
7606
- icon.textContent = "🔍";
7592
+ icon.textContent = "🔍";
7607
7593
  container.appendChild(icon);
7608
7594
  const t2 = document.createElement("h2");
7609
7595
  t2.style.cssText = `color:${this.theme.text};font-size:18px;font-weight:700;margin:0;`;
@@ -7623,7 +7609,7 @@ var SmartComplySDK = (() => {
7623
7609
  });
7624
7610
  container.appendChild(retryBtn);
7625
7611
  }
7626
- // ── W11: You're all done (end-user final screen) ─────────────────
7612
+ // ── W11: You're all done (end-user final screen) ─────────────────
7627
7613
  renderDone(container) {
7628
7614
  container.style.cssText += "display:flex;flex-direction:column;align-items:center;text-align:center;gap:16px;padding:24px 0;";
7629
7615
  container.setAttribute("role", "status");
@@ -7636,7 +7622,7 @@ var SmartComplySDK = (() => {
7636
7622
  });
7637
7623
  const iconWrap = document.createElement("div");
7638
7624
  iconWrap.style.cssText = `width:80px;height:80px;border-radius:50%;background:${this.theme.successBg};border:3px solid ${this.theme.success};display:flex;align-items:center;justify-content:center;font-size:36px;font-weight:700;color:${this.theme.success};animation:sc-pop 0.4s ease;`;
7639
- iconWrap.textContent = "✓";
7625
+ iconWrap.textContent = "✓";
7640
7626
  container.appendChild(iconWrap);
7641
7627
  const title = document.createElement("h2");
7642
7628
  title.style.cssText = `color:${this.theme.text};font-size:22px;font-weight:700;margin:0;`;
@@ -7648,7 +7634,7 @@ var SmartComplySDK = (() => {
7648
7634
  container.appendChild(desc);
7649
7635
  const info = document.createElement("div");
7650
7636
  info.style.cssText = `color:${this.theme.textMuted};font-size:11px;display:flex;align-items:center;gap:4px;`;
7651
- info.textContent = "🔒 Your data is encrypted and secure";
7637
+ info.textContent = "🔒 Your data is encrypted and secure";
7652
7638
  container.appendChild(info);
7653
7639
  const doneBtn = this.createPrimaryButton("Close");
7654
7640
  doneBtn.addEventListener("click", () => {
@@ -7656,12 +7642,12 @@ var SmartComplySDK = (() => {
7656
7642
  });
7657
7643
  container.appendChild(doneBtn);
7658
7644
  }
7659
- // ── W14: Retry limit reached ─────────────────────────────────────
7645
+ // ── W14: Retry limit reached ─────────────────────────────────────
7660
7646
  _renderRetryLimitReached(container) {
7661
7647
  container.style.cssText += "display:flex;flex-direction:column;align-items:center;text-align:center;gap:14px;padding:24px 0;";
7662
7648
  const icon = document.createElement("div");
7663
7649
  icon.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;`;
7664
- icon.textContent = "⚠️";
7650
+ icon.textContent = "⚠️";
7665
7651
  container.appendChild(icon);
7666
7652
  const t2 = document.createElement("h2");
7667
7653
  t2.style.cssText = `color:${this.theme.text};font-size:18px;font-weight:700;margin:0;`;
@@ -7678,7 +7664,7 @@ var SmartComplySDK = (() => {
7678
7664
  });
7679
7665
  container.appendChild(closeBtn);
7680
7666
  }
7681
- // ── W13: Camera pre-warm ─────────────────────────────────────────
7667
+ // ── W13: Camera pre-warm ─────────────────────────────────────────
7682
7668
  _prewarmCamera() {
7683
7669
  if (this._prewarmedStream || this.isDestroyed) return;
7684
7670
  navigator.mediaDevices?.getUserMedia?.({ video: { facingMode: "user" } }).then((stream) => {
@@ -7717,7 +7703,7 @@ var SmartComplySDK = (() => {
7717
7703
  <div style="display:flex;flex-direction:column;align-items:center;gap:14px;padding:28px 20px;">
7718
7704
  <div style="position:relative;width:52px;height:52px;">
7719
7705
  <div style="position:absolute;inset:0;border-radius:50%;border:3px solid ${this.theme.border};border-top-color:${this.theme.primary};animation:sc-spin 0.8s linear infinite;"></div>
7720
- <div style="position:absolute;inset:0;display:flex;align-items:center;justify-content:center;font-size:20px;">🔍</div>
7706
+ <div style="position:absolute;inset:0;display:flex;align-items:center;justify-content:center;font-size:20px;">🔍</div>
7721
7707
  </div>
7722
7708
  <div style="color:${this.theme.text};font-size:14px;font-weight:600;">Scanning document...</div>
7723
7709
  <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>
@@ -7775,7 +7761,7 @@ var SmartComplySDK = (() => {
7775
7761
  <div style="display:flex;flex-direction:column;align-items:center;gap:16px;padding:28px 20px;text-align:center;">
7776
7762
  <div style="position:relative;width:52px;height:52px;">
7777
7763
  <div style="position:absolute;inset:0;border-radius:50%;border:3px solid ${this.theme.border};border-top-color:${this.theme.primary};animation:sc-spin 0.8s linear infinite;"></div>
7778
- <div style="position:absolute;inset:0;display:flex;align-items:center;justify-content:center;font-size:20px;">🔄</div>
7764
+ <div style="position:absolute;inset:0;display:flex;align-items:center;justify-content:center;font-size:20px;">🔄</div>
7779
7765
  </div>
7780
7766
  <div style="color:${this.theme.text};font-size:14px;font-weight:600;">Retrying...</div>
7781
7767
  <div style="color:${this.theme.textSecondary};font-size:12px;max-width:240px;line-height:1.5;">Attempt ${retryCount} of ${maxRetries}</div>
@@ -7816,7 +7802,7 @@ var SmartComplySDK = (() => {
7816
7802
  wrap.setAttribute("role", "alert");
7817
7803
  const icon = document.createElement("div");
7818
7804
  icon.style.cssText = `width:56px;height:56px;border-radius:50%;background:${this.theme.errorBg};border:3px solid ${this.theme.error};display:flex;align-items:center;justify-content:center;font-size:26px;`;
7819
- icon.textContent = "🔍";
7805
+ icon.textContent = "🔍";
7820
7806
  wrap.appendChild(icon);
7821
7807
  const titleEl = document.createElement("div");
7822
7808
  titleEl.style.cssText = `color:${this.theme.text};font-size:14px;font-weight:700;`;
@@ -7840,7 +7826,7 @@ var SmartComplySDK = (() => {
7840
7826
  this.showErrorStep(userMessage);
7841
7827
  }
7842
7828
  }
7843
- // ── Liveness ────────────────────────────────────────────────────
7829
+ // ── Liveness ────────────────────────────────────────────────────
7844
7830
  renderLiveness(container) {
7845
7831
  container.style.cssText += "display:flex;flex-direction:column;gap:14px;";
7846
7832
  if (this._livenessFailures >= _SmartComplyFlow.MAX_RETRIES) {
@@ -7899,7 +7885,7 @@ var SmartComplySDK = (() => {
7899
7885
  }
7900
7886
  renderResult(_container) {
7901
7887
  }
7902
- // ── Error ───────────────────────────────────────────────────────
7888
+ // ── Error ───────────────────────────────────────────────────────
7903
7889
  showErrorStep(message) {
7904
7890
  this.currentStep = "error";
7905
7891
  if (!this.contentArea) return;
@@ -7916,7 +7902,7 @@ var SmartComplySDK = (() => {
7916
7902
  const isDocQuality = /blurry|blur|quality|glare|dark|bright|lighting/i.test(message);
7917
7903
  const isExpiredDoc = /document.*expired|expired.*document/i.test(message);
7918
7904
  const isFaceMatch = /face.*match|selfie.*match|does not match/i.test(message);
7919
- const errorIcon = isCameraErr ? "📷" : isNetworkErr ? "📡" : isAuthErr ? "⏱" : isDocQuality ? "🔍" : isExpiredDoc ? "📅" : isFaceMatch ? "🤳" : "✕";
7905
+ const errorIcon = isCameraErr ? "📷" : isNetworkErr ? "📡" : isAuthErr ? "⏱" : isDocQuality ? "🔍" : isExpiredDoc ? "📅" : isFaceMatch ? "🤳" : "✕";
7920
7906
  const errorTitle = isCameraErr ? "Camera Access Required" : isNetworkErr ? "Connection Problem" : isAuthErr ? "Session Expired" : isDocQuality ? "Document Photo Unclear" : isExpiredDoc ? "Document Expired" : isFaceMatch ? "Face Match Failed" : "Verification Unsuccessful";
7921
7907
  const userMessage = isCameraErr ? "Please allow camera access in your browser settings and try again." : isNetworkErr ? "Check your internet connection and try again." : isAuthErr ? "Your session has expired. Please start again." : isDocQuality ? _sanitizeUserMessage(message) || "Please retake your document photo in good lighting with no glare." : isExpiredDoc ? "The document you submitted has expired. Please use a valid, current ID." : isFaceMatch ? "Your selfie did not match the photo on your ID. Please ensure you are using your own valid document and face the camera directly." : _sanitizeUserMessage(message) || "We were unable to complete your verification. Please try again.";
7922
7908
  const iconWrap = document.createElement("div");
@@ -7952,9 +7938,9 @@ var SmartComplySDK = (() => {
7952
7938
  wrapper.appendChild(closeBtn);
7953
7939
  this.contentArea.appendChild(wrapper);
7954
7940
  }
7955
- // ─────────────────────────────────────────────────────────────────
7941
+ // ─────────────────────────────────────────────────────────────────
7956
7942
  // UI Helpers
7957
- // ─────────────────────────────────────────────────────────────────
7943
+ // ─────────────────────────────────────────────────────────────────
7958
7944
  createHeader() {
7959
7945
  const header = document.createElement("div");
7960
7946
  header.setAttribute("role", "banner");
@@ -8021,7 +8007,7 @@ var SmartComplySDK = (() => {
8021
8007
  stepIndicator.appendChild(this.stepLabel);
8022
8008
  header.appendChild(stepIndicator);
8023
8009
  const closeBtn = document.createElement("button");
8024
- closeBtn.innerHTML = "✕";
8010
+ closeBtn.innerHTML = "✕";
8025
8011
  closeBtn.setAttribute("aria-label", "Close identity verification");
8026
8012
  closeBtn.style.cssText = `
8027
8013
  width:32px;height:32px;border-radius:8px;flex-shrink:0;
@@ -8102,7 +8088,7 @@ var SmartComplySDK = (() => {
8102
8088
  }
8103
8089
  const arrow = document.createElement("span");
8104
8090
  arrow.style.cssText = `color:${this.theme.textMuted};font-size:18px;flex-shrink:0;`;
8105
- arrow.textContent = "→";
8091
+ arrow.textContent = "→";
8106
8092
  card.appendChild(textWrap);
8107
8093
  card.appendChild(arrow);
8108
8094
  return card;
@@ -8174,7 +8160,7 @@ var SmartComplySDK = (() => {
8174
8160
  if (this.currentStep === "loading" || this.currentStep === "welcome") {
8175
8161
  this.stepLabel.textContent = "";
8176
8162
  } else if (this.currentStep === "done" || this.currentStep === "result") {
8177
- this.stepLabel.textContent = "Complete ✓";
8163
+ this.stepLabel.textContent = "Complete ✓";
8178
8164
  } else if (stage2Steps.includes(this.currentStep)) {
8179
8165
  this.stepLabel.textContent = "Stage 2 of 2: Face Check";
8180
8166
  } else if (stage1Steps.includes(this.currentStep)) {