@neofaceid/web-sdk 1.25.4 → 1.25.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -11,7 +11,8 @@ export declare interface ApplicationRegistrationData {
11
11
  }
12
12
 
13
13
  /**
14
- * Application registration result
14
+ * Application registration result.
15
+ * `app_token` só vem na criação/rotação; em GETs de leitura vem só `app_token_last4`.
15
16
  */
16
17
  export declare interface ApplicationRegistrationResult {
17
18
  success: boolean;
@@ -20,7 +21,8 @@ export declare interface ApplicationRegistrationResult {
20
21
  application_name: string;
21
22
  domain: string;
22
23
  accept_only_email_with_same_domain: boolean;
23
- app_token: string;
24
+ app_token?: string;
25
+ app_token_last4?: string;
24
26
  is_active: boolean;
25
27
  created_at: string;
26
28
  };
@@ -494,6 +496,7 @@ export declare const ENVIRONMENT_URLS: Record<Environment, string>;
494
496
  */
495
497
  export declare enum ErrorType {
496
498
  NETWORK = "NetworkError",
499
+ /** @deprecated Use `ErrorType.NETWORK`. Mantido para compatibilidade com consumidores existentes do SDK. */
497
500
  NETWORK_ERROR = "NetworkError",
498
501
  INVALID_TOKEN = "InvalidTokenError",
499
502
  RECOGNITION_FAILED = "RecognitionFailedError",
@@ -1360,6 +1363,6 @@ export declare const validateToken: (applicationToken: string) => Promise<boolea
1360
1363
  * MINOR: Incrementado quando adicionamos funcionalidades mantendo compatibilidade
1361
1364
  * PATCH: Incrementado quando corrigimos bugs mantendo compatibilidade
1362
1365
  */
1363
- export declare const VERSION = "1.25.4";
1366
+ export declare const VERSION = "1.25.6";
1364
1367
 
1365
1368
  export { }
@@ -5336,9 +5336,15 @@ function init(options = {}) {
5336
5336
  }
5337
5337
  if (applicationToken) {
5338
5338
  globalConfig.applicationToken = applicationToken;
5339
+ } else if (applicationToken === "") {
5340
+ console.warn(
5341
+ "[NeoFaceID SDK] applicationToken vazio em init() — 401 esperado em chamadas autenticadas."
5342
+ );
5339
5343
  }
5340
5344
  globalConfig.initialized = true;
5341
- console.log(`[NeoFaceID SDK] Inicializado - Ambiente: ${globalConfig.environment}, URL: ${globalConfig.baseUrl}`);
5345
+ console.log(
5346
+ `[NeoFaceID SDK] Inicializado - Ambiente: ${globalConfig.environment}, URL: ${globalConfig.baseUrl}`
5347
+ );
5342
5348
  }
5343
5349
  function getBaseUrl() {
5344
5350
  if (!globalConfig.initialized) {
@@ -5408,8 +5414,8 @@ const compressDocumentImage = async (imageBlob) => new Promise((resolve, reject)
5408
5414
  const img = new Image();
5409
5415
  img.onload = () => {
5410
5416
  const MAX_SIZE = 1280;
5411
- let width = img.width;
5412
- let height = img.height;
5417
+ let { width } = img;
5418
+ let { height } = img;
5413
5419
  if (width > height && width > MAX_SIZE) {
5414
5420
  height = height * MAX_SIZE / width;
5415
5421
  width = MAX_SIZE;
@@ -6027,6 +6033,11 @@ const registerPersonWithoutFace = async (personData, applicationToken, options)
6027
6033
  }
6028
6034
  ];
6029
6035
  }
6036
+ if (!applicationToken) {
6037
+ console.warn(
6038
+ "[NeoFaceID SDK] registerPersonWithoutFace sem applicationToken — 401 esperado."
6039
+ );
6040
+ }
6030
6041
  const response = await fetch(`${getApiBaseUrl()}/api/v1/signup/donor/`, {
6031
6042
  method: "POST",
6032
6043
  headers: {
@@ -6161,6 +6172,11 @@ const registerPersonWithBiometric = async (personData, facePhotos, applicationTo
6161
6172
  }
6162
6173
  ];
6163
6174
  }
6175
+ if (!applicationToken) {
6176
+ console.warn(
6177
+ "[NeoFaceID SDK] registerPersonWithBiometric sem applicationToken — 401 esperado."
6178
+ );
6179
+ }
6164
6180
  const response = await fetch(`${getApiBaseUrl()}/api/v1/signup/donor/`, {
6165
6181
  method: "POST",
6166
6182
  headers: {
@@ -6701,18 +6717,16 @@ const startProofOfLife = async (videoBase64, applicationToken) => {
6701
6717
  throw new NeoFaceError("Unknown error occurred", ErrorType.NETWORK_ERROR);
6702
6718
  }
6703
6719
  };
6704
- const videoToBase64 = async (videoBlob) => {
6705
- return new Promise((resolve, reject) => {
6706
- const reader = new FileReader();
6707
- reader.onload = () => {
6708
- const result = reader.result;
6709
- const base642 = result.includes(",") ? result.split(",")[1] : result;
6710
- resolve(base642);
6711
- };
6712
- reader.onerror = () => reject(new NeoFaceError("Failed to convert video to base64", ErrorType.CAPTURE_ERROR));
6713
- reader.readAsDataURL(videoBlob);
6714
- });
6715
- };
6720
+ const videoToBase64 = async (videoBlob) => new Promise((resolve, reject) => {
6721
+ const reader = new FileReader();
6722
+ reader.onload = () => {
6723
+ const result = reader.result;
6724
+ const base642 = result.includes(",") ? result.split(",")[1] : result;
6725
+ resolve(base642);
6726
+ };
6727
+ reader.onerror = () => reject(new NeoFaceError("Failed to convert video to base64", ErrorType.CAPTURE_ERROR));
6728
+ reader.readAsDataURL(videoBlob);
6729
+ });
6716
6730
  const blobToBase64 = (blob) => new Promise((resolve, reject) => {
6717
6731
  const reader = new FileReader();
6718
6732
  reader.onload = () => {
@@ -6775,13 +6789,19 @@ const registerDocumentByImage = async (personId, jwtToken, images) => {
6775
6789
  throw new NeoFaceError("Unknown error occurred", ErrorType.NETWORK_ERROR);
6776
6790
  }
6777
6791
  };
6778
- const getTaskStatus = async (taskId) => {
6792
+ const getTaskStatus = async (taskId, applicationToken) => {
6779
6793
  const controller = createTimeoutController();
6794
+ {
6795
+ console.warn(
6796
+ "[NeoFaceID SDK] getTaskStatus sem applicationToken — /tasks/status/ vai responder 401."
6797
+ );
6798
+ }
6780
6799
  try {
6781
6800
  const response = await fetch(`${getApiBaseUrl()}/api/v1/tasks/status/?task_id=${taskId}`, {
6782
6801
  method: "GET",
6783
6802
  headers: {
6784
- "Content-Type": "application/json"
6803
+ "Content-Type": "application/json",
6804
+ ...applicationToken ? { "X-App-Token": applicationToken } : {}
6785
6805
  },
6786
6806
  signal: controller.signal
6787
6807
  });
@@ -6813,7 +6833,7 @@ const identifyPersonAsync = async (image, applicationToken, options = {}) => {
6813
6833
  person: initialResponse.person
6814
6834
  };
6815
6835
  }
6816
- const taskId = initialResponse.taskId;
6836
+ const { taskId } = initialResponse;
6817
6837
  if (!taskId) {
6818
6838
  return { personFound: false };
6819
6839
  }
@@ -7647,7 +7667,9 @@ function BiometricRegistrationModal({
7647
7667
  const captureStateRef = useRef(null);
7648
7668
  const [state, dispatch] = useReducer(modalReducer, void 0, createInitialState);
7649
7669
  const [faceDetected, setFaceDetected] = useState(false);
7650
- const [faceDistance, setFaceDistance] = useState("ok");
7670
+ const [faceDistance, setFaceDistance] = useState(
7671
+ "ok"
7672
+ );
7651
7673
  const [cameraReady, setCameraReady] = useState(false);
7652
7674
  useEffect(() => {
7653
7675
  if (state.status === "liveness") {
@@ -7778,15 +7800,13 @@ function BiometricRegistrationModal({
7778
7800
  }
7779
7801
  }, 50);
7780
7802
  }
7781
- } else {
7782
- if (holdStartTimeRef.current) {
7783
- holdStartTimeRef.current = null;
7784
- if (progressIntervalRef.current) {
7785
- clearInterval(progressIntervalRef.current);
7786
- progressIntervalRef.current = null;
7787
- }
7788
- dispatch({ type: "UPDATE_PROGRESS", progress: 0 });
7803
+ } else if (holdStartTimeRef.current) {
7804
+ holdStartTimeRef.current = null;
7805
+ if (progressIntervalRef.current) {
7806
+ clearInterval(progressIntervalRef.current);
7807
+ progressIntervalRef.current = null;
7789
7808
  }
7809
+ dispatch({ type: "UPDATE_PROGRESS", progress: 0 });
7790
7810
  }
7791
7811
  };
7792
7812
  useEffect(() => {
@@ -7813,8 +7833,8 @@ function BiometricRegistrationModal({
7813
7833
  };
7814
7834
  loadModels();
7815
7835
  }, []);
7816
- useEffect(() => {
7817
- return () => {
7836
+ useEffect(
7837
+ () => () => {
7818
7838
  if (streamRef.current) {
7819
7839
  streamRef.current.getTracks().forEach((track) => {
7820
7840
  track.stop();
@@ -7836,8 +7856,9 @@ function BiometricRegistrationModal({
7836
7856
  clearTimeout(stepTimeoutTimerRef.current);
7837
7857
  stepTimeoutTimerRef.current = null;
7838
7858
  }
7839
- };
7840
- }, []);
7859
+ },
7860
+ []
7861
+ );
7841
7862
  useEffect(() => {
7842
7863
  let mounted = true;
7843
7864
  const initCamera = async () => {
@@ -7979,15 +8000,13 @@ function BiometricRegistrationModal({
7979
8000
  );
7980
8001
  manageHoldAndCapture(positionCorrect);
7981
8002
  }
7982
- } else {
7983
- if (holdStartTimeRef.current) {
7984
- holdStartTimeRef.current = null;
7985
- if (progressIntervalRef.current) {
7986
- clearInterval(progressIntervalRef.current);
7987
- progressIntervalRef.current = null;
7988
- }
7989
- dispatch({ type: "UPDATE_PROGRESS", progress: 0 });
8003
+ } else if (holdStartTimeRef.current) {
8004
+ holdStartTimeRef.current = null;
8005
+ if (progressIntervalRef.current) {
8006
+ clearInterval(progressIntervalRef.current);
8007
+ progressIntervalRef.current = null;
7990
8008
  }
8009
+ dispatch({ type: "UPDATE_PROGRESS", progress: 0 });
7991
8010
  }
7992
8011
  } catch (error) {
7993
8012
  }
@@ -8016,38 +8035,37 @@ function BiometricRegistrationModal({
8016
8035
  }
8017
8036
  holdStartTimeRef.current = null;
8018
8037
  };
8019
- } else {
8020
- const onCanPlay = () => {
8021
- if (isRunning) startDetection();
8022
- };
8023
- let pollCount = 0;
8024
- const MAX_POLLS = 50;
8025
- const pollTimer = window.setInterval(() => {
8026
- pollCount++;
8027
- if (!isRunning) {
8028
- clearInterval(pollTimer);
8029
- return;
8030
- }
8031
- if (videoRef.current && videoRef.current.readyState >= 2) {
8032
- clearInterval(pollTimer);
8033
- videoRef.current.removeEventListener("canplay", onCanPlay);
8034
- startDetection();
8035
- } else if (pollCount >= MAX_POLLS) {
8036
- clearInterval(pollTimer);
8037
- }
8038
- }, 300);
8039
- video == null ? void 0 : video.addEventListener("canplay", onCanPlay, { once: true });
8040
- return () => {
8041
- isRunning = false;
8042
- clearInterval(pollTimer);
8043
- video == null ? void 0 : video.removeEventListener("canplay", onCanPlay);
8044
- if (progressIntervalRef.current) {
8045
- clearInterval(progressIntervalRef.current);
8046
- progressIntervalRef.current = null;
8047
- }
8048
- holdStartTimeRef.current = null;
8049
- };
8050
8038
  }
8039
+ const onCanPlay = () => {
8040
+ if (isRunning) startDetection();
8041
+ };
8042
+ let pollCount = 0;
8043
+ const MAX_POLLS = 50;
8044
+ const pollTimer = window.setInterval(() => {
8045
+ pollCount++;
8046
+ if (!isRunning) {
8047
+ clearInterval(pollTimer);
8048
+ return;
8049
+ }
8050
+ if (videoRef.current && videoRef.current.readyState >= 2) {
8051
+ clearInterval(pollTimer);
8052
+ videoRef.current.removeEventListener("canplay", onCanPlay);
8053
+ startDetection();
8054
+ } else if (pollCount >= MAX_POLLS) {
8055
+ clearInterval(pollTimer);
8056
+ }
8057
+ }, 300);
8058
+ video == null ? void 0 : video.addEventListener("canplay", onCanPlay, { once: true });
8059
+ return () => {
8060
+ isRunning = false;
8061
+ clearInterval(pollTimer);
8062
+ video == null ? void 0 : video.removeEventListener("canplay", onCanPlay);
8063
+ if (progressIntervalRef.current) {
8064
+ clearInterval(progressIntervalRef.current);
8065
+ progressIntervalRef.current = null;
8066
+ }
8067
+ holdStartTimeRef.current = null;
8068
+ };
8051
8069
  }, [state.status]);
8052
8070
  const capturePhoto = async () => {
8053
8071
  if (!videoRef.current || !canvasRef.current || isCapturingRef.current) {
@@ -8151,7 +8169,7 @@ function BiometricRegistrationModal({
8151
8169
  const renderLivenessDetection = () => {
8152
8170
  if (state.status !== "liveness") return null;
8153
8171
  const progress = `${state.currentStepIndex + 1}/${state.stepSequence.length - 1}`;
8154
- const stepProgress = state.stepProgress;
8172
+ const { stepProgress } = state;
8155
8173
  return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "liveness-container", children: [
8156
8174
  /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "progress-indicator", children: /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "progress-text", children: progress }) }),
8157
8175
  faceDetected && faceDistance !== "ok" && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: `status-badge ${faceDistance === "not-centered" ? "warning" : "error"}`, children: [
@@ -8180,7 +8198,14 @@ function BiometricRegistrationModal({
8180
8198
  stepProgress > 0 && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "progress-bar", children: /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "progress-fill", style: { width: `${stepProgress}%` } }) })
8181
8199
  ] }),
8182
8200
  /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "branding-small", children: [
8183
- /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "brand-logo-small", style: { display: "inline-flex", width: 18, height: 18, color: "currentColor" }, dangerouslySetInnerHTML: { __html: NEOFACEID_MARK_MONO_SVG } }),
8201
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
8202
+ "span",
8203
+ {
8204
+ className: "brand-logo-small",
8205
+ style: { display: "inline-flex", width: 18, height: 18, color: "currentColor" },
8206
+ dangerouslySetInnerHTML: { __html: NEOFACEID_MARK_MONO_SVG }
8207
+ }
8208
+ ),
8184
8209
  /* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: "NeoFaceId by" }),
8185
8210
  /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "brand-name", children: "OCTA" })
8186
8211
  ] })
@@ -8227,8 +8252,16 @@ function BiometricRegistrationModal({
8227
8252
  /* @__PURE__ */ jsxRuntimeExports.jsx("h3", { children: "Não foi possível processar" }),
8228
8253
  /* @__PURE__ */ jsxRuntimeExports.jsx("p", { children: state.message }),
8229
8254
  /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "button-group", children: [
8230
- state.retryable && /* @__PURE__ */ jsxRuntimeExports.jsx("button", { className: "secondary-button", onClick: () => dispatch({ type: "RESET" }), children: "Tentar Novamente" }),
8231
- /* @__PURE__ */ jsxRuntimeExports.jsx("button", { className: "ghost-button", onClick: onClose, children: "Cancelar" })
8255
+ state.retryable && /* @__PURE__ */ jsxRuntimeExports.jsx(
8256
+ "button",
8257
+ {
8258
+ type: "button",
8259
+ className: "secondary-button",
8260
+ onClick: () => dispatch({ type: "RESET" }),
8261
+ children: "Tentar Novamente"
8262
+ }
8263
+ ),
8264
+ /* @__PURE__ */ jsxRuntimeExports.jsx("button", { type: "button", className: "ghost-button", onClick: onClose, children: "Cancelar" })
8232
8265
  ] })
8233
8266
  ] });
8234
8267
  };
@@ -8271,7 +8304,7 @@ function BiometricRegistrationModal({
8271
8304
  ] }) }),
8272
8305
  /* @__PURE__ */ jsxRuntimeExports.jsx("h3", { children: onPhotosCaptured ? "Captura concluída!" : "Verificação concluída!" }),
8273
8306
  /* @__PURE__ */ jsxRuntimeExports.jsx("p", { children: onPhotosCaptured ? "Suas capturas faciais foram realizadas" : "Sua biometria foi registrada com sucesso" }),
8274
- /* @__PURE__ */ jsxRuntimeExports.jsx("button", { className: "primary-button", onClick: onClose, children: "Continuar" })
8307
+ /* @__PURE__ */ jsxRuntimeExports.jsx("button", { type: "button", className: "primary-button", onClick: onClose, children: "Continuar" })
8275
8308
  ] });
8276
8309
  const renderDuplicate = () => {
8277
8310
  if (state.status !== "duplicate") return null;
@@ -8283,6 +8316,7 @@ function BiometricRegistrationModal({
8283
8316
  /* @__PURE__ */ jsxRuntimeExports.jsx(
8284
8317
  "button",
8285
8318
  {
8319
+ type: "button",
8286
8320
  className: "primary-button",
8287
8321
  onClick: () => {
8288
8322
  onClose();
@@ -8294,6 +8328,7 @@ function BiometricRegistrationModal({
8294
8328
  /* @__PURE__ */ jsxRuntimeExports.jsx(
8295
8329
  "button",
8296
8330
  {
8331
+ type: "button",
8297
8332
  className: "secondary-button",
8298
8333
  style: { marginTop: "12px" },
8299
8334
  onClick: () => {
@@ -8308,6 +8343,7 @@ function BiometricRegistrationModal({
8308
8343
  /* @__PURE__ */ jsxRuntimeExports.jsx(
8309
8344
  "button",
8310
8345
  {
8346
+ type: "button",
8311
8347
  className: "ghost-button",
8312
8348
  onClick: () => window.open("https://support.neofaceid.com", "_blank"),
8313
8349
  children: "Falar com Suporte"
@@ -8975,7 +9011,7 @@ function BiometricRegistrationModal({
8975
9011
  }
8976
9012
  ` }),
8977
9013
  /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "modal-overlay", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "modal-content", children: [
8978
- /* @__PURE__ */ jsxRuntimeExports.jsx("button", { className: "close-button", onClick: onClose, children: "×" }),
9014
+ /* @__PURE__ */ jsxRuntimeExports.jsx("button", { type: "button", className: "close-button", onClick: onClose, children: "×" }),
8979
9015
  state.status === "liveness" && renderLivenessDetection(),
8980
9016
  state.status === "camera-loading" && renderCameraLoading(),
8981
9017
  state.status === "processing" && renderProcessing(),
@@ -9241,7 +9277,7 @@ class BiometricCaptureModal {
9241
9277
  } catch (error) {
9242
9278
  this.options.onError(
9243
9279
  new NeoFaceError(
9244
- "Erro ao inicializar câmera: " + error.message,
9280
+ `Erro ao inicializar câmera: ${error.message}`,
9245
9281
  ErrorType.CAMERA_ERROR
9246
9282
  )
9247
9283
  );
@@ -9323,7 +9359,7 @@ class BiometricCaptureModal {
9323
9359
  this.canvas.width = this.video.videoWidth;
9324
9360
  this.canvas.height = this.video.videoHeight;
9325
9361
  } catch (error) {
9326
- throw new Error("Não foi possível acessar a câmera: " + error.message);
9362
+ throw new Error(`Não foi possível acessar a câmera: ${error.message}`);
9327
9363
  }
9328
9364
  }
9329
9365
  /**
@@ -9377,13 +9413,13 @@ class BiometricCaptureModal {
9377
9413
  const imageData = this.canvas.toDataURL("image/jpeg", 0.8);
9378
9414
  const base64Data = imageData.split(",")[1];
9379
9415
  const dataUrl = `data:image/jpeg;base64,${base64Data}`;
9380
- let detectedType = this.options.mode === "auto" ? await this.detectBiometricType(base64Data) : this.options.mode;
9416
+ const detectedType = this.options.mode === "auto" ? await this.detectBiometricType(base64Data) : this.options.mode;
9381
9417
  this.close();
9382
9418
  this.options.onSuccess(dataUrl, detectedType);
9383
9419
  } catch (error) {
9384
9420
  this.options.onError(
9385
9421
  new NeoFaceError(
9386
- "Erro ao capturar imagem: " + error.message,
9422
+ `Erro ao capturar imagem: ${error.message}`,
9387
9423
  ErrorType.CAPTURE_ERROR
9388
9424
  )
9389
9425
  );
@@ -10687,7 +10723,7 @@ async function captureFaceSilently() {
10687
10723
  cleanup();
10688
10724
  reject(
10689
10725
  new NeoFaceError(
10690
- "Erro ao reproduzir câmera: " + err.message,
10726
+ `Erro ao reproduzir câmera: ${err.message}`,
10691
10727
  ErrorType.CAMERA_ERROR
10692
10728
  )
10693
10729
  );
@@ -10703,7 +10739,7 @@ async function captureFaceSilently() {
10703
10739
  cleanup();
10704
10740
  reject(
10705
10741
  new NeoFaceError(
10706
- "Não foi possível acessar a câmera: " + error.message,
10742
+ `Não foi possível acessar a câmera: ${error.message}`,
10707
10743
  ErrorType.CAMERA_ERROR
10708
10744
  )
10709
10745
  );
@@ -11204,9 +11240,12 @@ async function detectBiometricType(imageData) {
11204
11240
  async function detectFace(img) {
11205
11241
  try {
11206
11242
  if (typeof window !== "undefined" && window.faceapi) {
11207
- const faceapi2 = window.faceapi;
11243
+ const { faceapi: faceapi2 } = window;
11208
11244
  await loadFaceApiModels();
11209
- const tinyOptions = new faceapi2.TinyFaceDetectorOptions({ inputSize: 320, scoreThreshold: 0.5 });
11245
+ const tinyOptions = new faceapi2.TinyFaceDetectorOptions({
11246
+ inputSize: 320,
11247
+ scoreThreshold: 0.5
11248
+ });
11210
11249
  const detections = await faceapi2.detectAllFaces(img, tinyOptions).withFaceLandmarks();
11211
11250
  if (detections && detections.length > 0) {
11212
11251
  const bestDetection = detections.reduce(
@@ -11305,7 +11344,7 @@ async function loadFaceApiModels() {
11305
11344
  if (typeof window === "undefined" || !window.faceapi) {
11306
11345
  return;
11307
11346
  }
11308
- const faceapi2 = window.faceapi;
11347
+ const { faceapi: faceapi2 } = window;
11309
11348
  if (faceapi2.nets.tinyFaceDetector.isLoaded) {
11310
11349
  return;
11311
11350
  }
@@ -11336,7 +11375,7 @@ const biometricDetection = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.
11336
11375
  initializeBiometricDetection,
11337
11376
  isAdvancedDetectionAvailable
11338
11377
  }, Symbol.toStringTag, { value: "Module" }));
11339
- const VERSION = "1.25.4";
11378
+ const VERSION = "1.25.6";
11340
11379
  const RELEASE_DATE = "2026-08-29";
11341
11380
  class OnboardingCaptureModal {
11342
11381
  constructor(options) {
@@ -11364,7 +11403,10 @@ class OnboardingCaptureModal {
11364
11403
  await this.runFaceCaptureCountdown();
11365
11404
  this.faceBlob = await this.captureFrame();
11366
11405
  this.step = "document";
11367
- this.updateTexts("Captura do Documento", 'Posicione seu documento visível e clique em "Capturar"');
11406
+ this.updateTexts(
11407
+ "Captura do Documento",
11408
+ 'Posicione seu documento visível e clique em "Capturar"'
11409
+ );
11368
11410
  await this.waitForUserCaptureClick();
11369
11411
  this.documentBlob = await this.captureFrame();
11370
11412
  await this.close();
@@ -11462,7 +11504,9 @@ class OnboardingCaptureModal {
11462
11504
  async runFaceCaptureCountdown() {
11463
11505
  if (!this.overlay) return;
11464
11506
  const countdownEl = this.overlay.querySelector(".neofaceid-countdown");
11465
- const countdownNumberEl = this.overlay.querySelector(".neofaceid-countdown-number");
11507
+ const countdownNumberEl = this.overlay.querySelector(
11508
+ ".neofaceid-countdown-number"
11509
+ );
11466
11510
  const statusText = this.overlay.querySelector(".neofaceid-status-text");
11467
11511
  countdownEl.style.display = "flex";
11468
11512
  statusText.textContent = "Prepare-se! Capturando seu rosto...";
@@ -11509,7 +11553,11 @@ class OnboardingCaptureModal {
11509
11553
  this.canvas.height = this.video.videoHeight;
11510
11554
  ctx.drawImage(this.video, 0, 0, this.canvas.width, this.canvas.height);
11511
11555
  const blob = await new Promise((resolve, reject) => {
11512
- this.canvas.toBlob((b) => b ? resolve(b) : reject(new Error("Falha ao gerar imagem")), "image/jpeg", 0.92);
11556
+ this.canvas.toBlob(
11557
+ (b) => b ? resolve(b) : reject(new Error("Falha ao gerar imagem")),
11558
+ "image/jpeg",
11559
+ 0.92
11560
+ );
11513
11561
  });
11514
11562
  return blob;
11515
11563
  }
@@ -12139,13 +12187,15 @@ class DocumentCaptureModal {
12139
12187
 
12140
12188
  <div class="neoface-doc-body">
12141
12189
  <div class="neoface-doc-select-grid">
12142
- ${Object.entries(DOCUMENT_INFO).filter(([type]) => type !== "CPF").map(([type, info]) => `
12190
+ ${Object.entries(DOCUMENT_INFO).filter(([type]) => type !== "CPF").map(
12191
+ ([type, info]) => `
12143
12192
  <button class="neoface-doc-select-option" data-type="${type}">
12144
12193
  <span class="neoface-doc-select-icon">${info.icon}</span>
12145
12194
  <span class="neoface-doc-select-name">${info.name}</span>
12146
12195
  <svg class="neoface-doc-select-arrow" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M9 18l6-6-6-6"/></svg>
12147
12196
  </button>
12148
- `).join("")}
12197
+ `
12198
+ ).join("")}
12149
12199
  </div>
12150
12200
 
12151
12201
  <div class="neoface-doc-tips">
@@ -12363,8 +12413,8 @@ class DocumentCaptureModal {
12363
12413
  const img = new Image();
12364
12414
  img.onload = () => {
12365
12415
  const MAX_SIZE = 1280;
12366
- let width = img.width;
12367
- let height = img.height;
12416
+ let { width } = img;
12417
+ let { height } = img;
12368
12418
  if (width > height && width > MAX_SIZE) {
12369
12419
  height = height * MAX_SIZE / width;
12370
12420
  width = MAX_SIZE;
@@ -12384,7 +12434,9 @@ class DocumentCaptureModal {
12384
12434
  canvas.toBlob(
12385
12435
  (blob) => {
12386
12436
  if (blob) {
12387
- console.log(`[DocumentCapture] Compressed image from ${(file.size / 1024).toFixed(0)}KB to ${(blob.size / 1024).toFixed(0)}KB`);
12437
+ console.log(
12438
+ `[DocumentCapture] Compressed image from ${(file.size / 1024).toFixed(0)}KB to ${(blob.size / 1024).toFixed(0)}KB`
12439
+ );
12388
12440
  resolve(blob);
12389
12441
  } else {
12390
12442
  reject(new Error("Failed to compress image"));
@@ -12405,7 +12457,9 @@ class DocumentCaptureModal {
12405
12457
  const retakeBtn = (_b = this.overlay) == null ? void 0 : _b.querySelector(".neoface-doc-retake-btn");
12406
12458
  confirmBtn == null ? void 0 : confirmBtn.addEventListener("click", () => this.handleConfirm());
12407
12459
  retakeBtn == null ? void 0 : retakeBtn.addEventListener("click", () => this.handleRetake());
12408
- const previewImg = (_c = this.overlay) == null ? void 0 : _c.querySelector(".neoface-doc-preview-current");
12460
+ const previewImg = (_c = this.overlay) == null ? void 0 : _c.querySelector(
12461
+ ".neoface-doc-preview-current"
12462
+ );
12409
12463
  if (previewImg) {
12410
12464
  const blob = this.currentStep === "preview-front" ? this.frontBlob : this.backBlob;
12411
12465
  if (blob) previewImg.src = URL.createObjectURL(blob);
@@ -12474,8 +12528,8 @@ class DocumentCaptureModal {
12474
12528
  if (loading) loading.style.display = "flex";
12475
12529
  const ctx = this.canvas.getContext("2d");
12476
12530
  if (!ctx) return;
12477
- const videoWidth = this.video.videoWidth;
12478
- const videoHeight = this.video.videoHeight;
12531
+ const { videoWidth } = this.video;
12532
+ const { videoHeight } = this.video;
12479
12533
  const frameWidthPercent = 0.75;
12480
12534
  const frameHeightPercent = 0.65;
12481
12535
  const cropWidth = Math.floor(videoWidth * frameWidthPercent);