# careplix-scan-sdk

Careplix Scan SDK for Web Browser Environment to generate Raw Scan Data.

# Installation

```sh
# with npm
npm install careplix-scan-sdk

# with yarn
yarn add careplix-scan-sdk
```

```js
//import Face Scan module
import { facescan } from "careplix-scan-sdk";

//import Finger Scan module
import { fingerscan } from "careplix-scan-sdk";
```

# Usage

Include the following html elements in the Scan Page.

```html
<div style="height: 100vh; position: relative;">
  <video id="videoInput" style="position: fixed; right: 1rem; top: 1rem; height: 1px; width: 1px;" autoplay muted playsinline></video>
  <canvas id="canvasOutput" style="width: 100%; height: 100%; transform: scaleX(-1);"></canvas>
</div>
```

## Face Scan

```js
// Initialize the Callbacks
facescan.onFrame(({ type, message, progress, timeElapsed, isLiteMode, isThrottling }) => {
  // Save each frame data
});
facescan.onError((err, code, stackTrace) => {
  // On any error this callback will be called
});
facescan.onScanFinish(({ raw_intensity, ppg_time, average_fps }) => {
  // Call our Cloud APIs with the given parameters
});

// Start Scan Process
facescan
  .startScan({})
  .then(() => {
    console.log("Scan Started");
  })
  .catch((err) => {
    console.log("Scan Failed");
    console.error(err);
  });
```

> Note: If you're using React, please consider the following approach...

```js
// use Ref for video & canvas elements
const videoRef = useRef();
const canvasRef = useRef();

React.useEffect(() => {
  // initialize all the callbacks like onFrame, onScanFinish, onError etc.
  ...

  // Start Scan Process
  facescan.startScan({ canvasElement: canvasRef.current, videoElement: videoRef.current });

  return () => {
    // be sure to cancel the ongoing scan in cleanup function
    facescan.stopScan();
  };
}, []);
```

### `onFrame()`

During Scan you receive data from every processed frame through this callback.
| Property Name | Type | Description |
| --- | --- | --- |
| type | string | Type of the frame. Which can be either `"error"` or `"calibration"` or `"scan"` |
| message | string | Hint for user to correct the position of their face on the screen |
| progress | number | Progress percentage of the scan |
| timeElapsed | number | Time Elapsed in ms |
| isLiteMode | boolean | `true` when the SDK switches to [Lite-Mode](#litemode) |
| isThrottling | boolean | `true` when the device performance is likely throttling |

### `onError()`

If any error occurs during Scan, this callback will be called with the `Error` object and `Code` string.
| Error Code | Error Message | Cause/Reason |
| --- | --- | --- |
| FCINT01 | Please check your internet connection & try again. | SDK failed to download necessary files for AI scan. |
| FCSCN01 | No suitable subject detected. If the issue persists, consider adjusting the framing or removing any obstructions from the view. | No human face detected for a certain duration during scan-time. |

[More Errors...](#errors)

### `onScanFinish()`

When the scan is finished successfully, this callback will be called with raw data, which will be needed for the API call.
| Property Name | Type | Description |
| --- | --- | --- |
| raw_intensity | array | Raw Scan Data |
| ppg_time | array | Raw Scan Data |
| average_fps | number | Average FPS During Scan |

### `startScan()`

This function call starts the Scan.
| Parameter | Type | Default | Description |
| --- | --- | --- | --- |
| scanDuration | number | 60 | Duration of Scan phase in sec (30-120) |
| livelinessDetectionDuration | number | 50 | Duration in sec (10 to scanDuration) within which liveliness is detected |
| strictness | number | 4 | Level of strictness between 1 to 5 |
| deviceModel | string | Derived from userAgentData/userAgent | The Model name/number of the Device. e.g. "SM-S918B" denotes a "Samsung S23 Ultra" device. If this parameter isn't provided then Model is assumed from [userAgentData](https://developer.mozilla.org/en-US/docs/Web/API/Navigator/userAgentData) or [userAgent](https://developer.mozilla.org/en-US/docs/Web/API/Navigator/userAgent) |
| drawConfig | { type: string, color: string, lineSize: number } | { type: "rounded-corners", color: "#fff", lineSize: 5 } | Configuration options for shape drawn around the face during the scan.<br/>type can be "face-circle" or "face-mesh" or "rounded-corners"<br/>also, color & lineSize can be set as needed. |
| models_path | string | CarePlix CDN | Path of the models directory, only if model files are self-hosted |
| tryHDCamera | boolean | false | Scan is started with the camera at standard resolution by default for better performance. Set this to `true` to start the camera in HD. Note: the SDK may still drop back to the standard resolution automatically if runtime performance is poor. |
| videoElement | HTMLVideoElement | | Ref (React) or DOMElement referring to video element |
| canvasElement | HTMLCanvasElement | | Ref (React) or DOMElement referring to canvas element |

### `stopScan()`

This function call stops the Scan.

## LiteMode

During Calibration time we try to detect if the device has enough processing resource available to run the Face Detection continuously. If for any reason, the device does not have enough resources available, we then start the Scan in Lite Mode. In Lite Mode, we detect the face periodically and continue with the Scanning Process.

## Finger Scan

```js
// Initialize the Callbacks
fingerscan.onFrame(({ type, message, progress, timeElapsed, isThrottling }) => {
  // Save each frame data
});
fingerscan.onError((err, code, stackTrace) => {
  // On any error this callback will be called
});
fingerscan.onScanFinish(({ raw_intensity, ppg_time, average_fps }) => {
  // Call our Cloud APIs with the given parameters
});

// Start Scan Process
fingerscan
  .startScan({})
  .then(() => {
    console.log("Scan Started");
  })
  .catch((err) => {
    console.log("Scan Failed");
    console.error(err);
  });
```

> Note: If you're using React, please consider the following approach...

```js
// use Ref for video & canvas elements
const videoRef = useRef();
const canvasRef = useRef();

React.useEffect(() => {
  // initialize all the callbacks like onFrame, onScanFinish, onError etc.
  ...

  // Start Scan Process
  fingerscan.startScan({ canvasElement: canvasRef.current, videoElement: videoRef.current });

  return () => {
    // be sure to cancel the ongoing scan in cleanup function
    fingerscan.stopScan();
  };
}, []);
```

### `onFrame()`

During Scan you receive data from every processed frame through this callback.
| Property Name | Type | Description |
| --- | --- | --- |
| type | string | Type of the frame. Which can be either `"error"` or `"calibration"` or `"scan"` |
| message | string | Hint for user to correct the position of their finger on the back camera |
| progress | number | Progress percentage of the scan |
| timeElapsed | number | Time Elapsed in ms |
| isThrottling | boolean | `true` when the device performance is likely throttling |

### `onError()`

If any error occurs during Scan, this callback will be called with the `Error` object and `Code` string.
| Error Code | Error Message | Cause/Reason |
| --- | --- | --- |
| --- | Flash could not be acquired. | (Non-Severe) This error will not Cancel the Scan.<br>This error will be logged in console, when device flashlight isn't accessible via the SDK or Browser. |

[More Errors...](#errors)

### `onScanFinish()`

When the scan is finished successfully, this callback will be called with raw data, which will be needed for the API call.
| Property Name | Type | Description |
| --- | --- | --- |
| raw_intensity | array | Raw Scan Data |
| ppg_time | array | Raw Scan Data |
| average_fps | number | Average FPS During Scan |

### `startScan()`

This function call starts the Scan.
| Parameter | Type | Default | Description |
| --- | --- | --- | --- |
| scanDuration | number | 60 | Duration of Scan phase in sec (10-120) |
| videoElement | HTMLVideoElement | | Ref (React) or DOMElement referring to video element |
| canvasElement | HTMLCanvasElement | | Ref (React) or DOMElement referring to canvas element |

### `stopScan()`

This function call stops the Scan.

## Errors

Following are some Errors which are common to both Finger/Face Scan SDK
| Error Code | Error Message | Cause/Reason |
| --- | --- | --- |
| CMUSR01 | We are not able to access the Camera. Please try again. | SDK is unable to get access to camera, either browser permission is disabled, or device camera is disabled, or hardware camera is not available. |
| CMUSR02 | App functionality disabled in the Background. Keep it in the Foreground for proper operation. | App is moved to background, maybe due to a phone-call or other reasons. |
| CMSCN01 | Sorry we're unable to compute the signal. Please try again. | SDK failed to perform some logical operation during the scan. |

## Get Device Model Name

```js
import { getDeviceModelName } from "careplix-scan-sdk";

const deviceModel = await getDeviceModelName();
```

## Capture image during scan

```js
function captureImage() {
  let canvas = document.getElementById("canvasOutput");
  let dataURL = canvas.toDataURL("image/png");

  process(dataURL);
  /*
      with the dataURL i.e. "data:image/png;base64,*****" you can do the following things...
      1. Save as PNG image file, then upload to backend.
      2. Send the dataURL to the backend, then save it as file in server.
      3. Send & Save the dataURL as-is.
    */
}
```
