UNPKG

@microblink/blinkinput-in-browser-sdk

Version:

A simple barcode scanning library for WebAssembly-enabled browsers.

1,148 lines (1,133 loc) 373 kB
import { r as registerInstance, c as createEvent, h, H as Host, g as getElement } from './index-a39cc62f.js'; import { s as stringToArray, a as stringToObject, b as setWebComponentParts, c as classNames, g as getWebComponentParts, h as hasSupportedImageFiles } from './generic.helpers-ec366719.js'; /*! **************************************************************************** Copyright (c) Microblink. All rights reserved. THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR NON-INFRINGEMENT. ***************************************************************************** */ /*! ***************************************************************************** Copyright (c) Microsoft Corporation. Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted. THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ***************************************************************************** */ function __awaiter(thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); } /** * Copyright (c) Microblink Ltd. All rights reserved. */ let nextMessageID = 0; function getNextMessageID() { const msgId = nextMessageID; nextMessageID = nextMessageID + 1; return msgId; } class BaseRequestMessage { constructor(action) { this.action = action; this.messageID = getNextMessageID(); } } class InitMessage extends BaseRequestMessage { constructor(wasmLoadSettings, userId) { super(InitMessage.action); this.wasmModuleName = wasmLoadSettings.wasmModuleName; this.licenseKey = wasmLoadSettings.licenseKey; this.userId = userId; this.registerLoadCallback = wasmLoadSettings.loadProgressCallback !== null; this.allowHelloMessage = wasmLoadSettings.allowHelloMessage; this.engineLocation = wasmLoadSettings.engineLocation; this.wasmType = wasmLoadSettings.wasmType; this.numberOfWorkers = wasmLoadSettings.numberOfWorkers; } } InitMessage.action = "init"; var ParameterType; (function (ParameterType) { ParameterType[ParameterType["Any"] = 0] = "Any"; ParameterType[ParameterType["Recognizer"] = 1] = "Recognizer"; ParameterType[ParameterType["RecognizerSettings"] = 2] = "RecognizerSettings"; ParameterType[ParameterType["Callback"] = 3] = "Callback"; })(ParameterType || (ParameterType = {})); class CreateNewRecognizer extends BaseRequestMessage { constructor(className, params) { super(CreateNewRecognizer.action); this.className = className; this.params = params; } } CreateNewRecognizer.action = "createNewNativeObject"; class CreateRecognizerRunner extends BaseRequestMessage { constructor(recognizerHandles, allowMultipleResults, registeredMetadataCallbacks) { super(CreateRecognizerRunner.action); this.recognizerHandles = recognizerHandles; this.allowMultipleResults = allowMultipleResults; this.registeredMetadataCallbacks = registeredMetadataCallbacks; } } CreateRecognizerRunner.action = "createRecognizerRunner"; class ReconfigureRecognizerRunner extends BaseRequestMessage { constructor(recognizerHandles, allowMultipleResults) { super(ReconfigureRecognizerRunner.action); this.recognizerHandles = recognizerHandles; this.allowMultipleResults = allowMultipleResults; } } ReconfigureRecognizerRunner.action = "reconfigureRecognizerRunner"; class DeleteRecognizerRunner extends BaseRequestMessage { constructor() { super(DeleteRecognizerRunner.action); } } DeleteRecognizerRunner.action = "deleteRecognizerRunner"; class InvokeObjectMethod extends BaseRequestMessage { constructor(objectHandle, methodName, params) { super(InvokeObjectMethod.action); this.objectHandle = objectHandle; this.methodName = methodName; this.params = params; } } InvokeObjectMethod.action = "invokeObject"; class ProcessImage extends BaseRequestMessage { constructor(image) { super(ProcessImage.action); this.frame = image; } getTransferrables() { return [this.frame.imageData.data.buffer]; } } ProcessImage.action = "processImage"; class ResetRecognizers extends BaseRequestMessage { constructor(hardReset) { super(ResetRecognizers.action); this.hardReset = hardReset; } } ResetRecognizers.action = "resetRecognizers"; class RegisteredMetadataCallbacks { constructor() { this.onDebugText = false; this.onDetectionFailed = false; this.onQuadDetection = false; this.onPointsDetection = false; this.onFirstSideResult = false; this.onGlare = false; } } class RegisterMetadataCallbacks extends BaseRequestMessage { constructor(registeredMetadataCallbacks) { super(RegisterMetadataCallbacks.action); this.registeredMetadataCallbacks = registeredMetadataCallbacks; } } RegisterMetadataCallbacks.action = "registerMetadataCallbacks"; class SetDetectionOnly extends BaseRequestMessage { constructor(detectionOnlyMode) { super(SetDetectionOnly.action); this.detectionOnlyMode = detectionOnlyMode; } } SetDetectionOnly.action = "setDetectionOnly"; class SetClearTimeoutCallback extends BaseRequestMessage { constructor(callbackNonEmpty) { super(SetClearTimeoutCallback.action); this.callbackNonEmpty = callbackNonEmpty; } } SetClearTimeoutCallback.action = "setClearTimeoutCallback"; class SetCameraPreviewMirrored extends BaseRequestMessage { constructor(cameraPreviewMirrored) { super(SetCameraPreviewMirrored.action); this.cameraPreviewMirrored = cameraPreviewMirrored; } } SetCameraPreviewMirrored.action = "setCameraPreviewMirrored"; // ===================================== / // Metadata callback messages // ===================================== / var MetadataCallback; (function (MetadataCallback) { MetadataCallback[MetadataCallback["onDebugText"] = 0] = "onDebugText"; MetadataCallback[MetadataCallback["onDetectionFailed"] = 1] = "onDetectionFailed"; MetadataCallback[MetadataCallback["onQuadDetection"] = 2] = "onQuadDetection"; MetadataCallback[MetadataCallback["onPointsDetection"] = 3] = "onPointsDetection"; MetadataCallback[MetadataCallback["onFirstSideResult"] = 4] = "onFirstSideResult"; MetadataCallback[MetadataCallback["clearTimeoutCallback"] = 5] = "clearTimeoutCallback"; MetadataCallback[MetadataCallback["onGlare"] = 6] = "onGlare"; MetadataCallback[MetadataCallback["recognizerCallback"] = 7] = "recognizerCallback"; })(MetadataCallback || (MetadataCallback = {})); /* eslint-enable @typescript-eslint/no-explicit-any */ /** * Copyright (c) Microblink Ltd. All rights reserved. */ /** * Defines the type of the WASM that will be loaded. */ var WasmType; (function (WasmType) { /** * The WASM that will be loaded will be most compatible with all browsers that * support the WASM, but will lack features that could be used to improve performance. */ WasmType["Basic"] = "BASIC"; /** * The WASM that will be loaded will be built with advanced WASM features, such as * bulk memory, SIMD, non-trapping floating point and sign extension. Such WASM can only * be executed in browsers that support those features. Attempting to run this * WASM in a non-compatible browser will crash your app. */ WasmType["Advanced"] = "ADVANCED"; /** * The WASM that will be loaded will be build with advanced WASM features, just * like above. Additionally, it will be also built with support for multi-threaded * processing. This feature requires a browser with support for both advanced WASM * features and `SharedArrayBuffer` */ WasmType["AdvancedWithThreads"] = "ADVANCED_WITH_THREADS"; })(WasmType || (WasmType = {})); /** * Copyright (c) Microblink Ltd. All rights reserved. */ const defaultWasmModuleName = "BlinkInputWasmSDK"; /** * Copyright (c) Microblink Ltd. All rights reserved. */ function defaultEventHandler(resolve, reject) { return (msg) => { const resultMsg = msg; if (resultMsg.success) { resolve(); } else { reject(resultMsg.error); } }; } function defaultResultEventHandler(successResolver, reject) { return (msg) => { const resultMsg = msg; if (resultMsg.success) { successResolver(msg); } else { reject(resultMsg.error); } }; } /* eslint-disable @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-assignment */ function wrapParameters(params) { // convert params const wrappedPrameters = []; for (let param of params) { let paramType = ParameterType.Any; if (param instanceof RemoteRecognizer) { paramType = ParameterType.Recognizer; param = param.getRemoteObjectHandle(); } wrappedPrameters.push({ parameter: param, type: paramType }); } return wrappedPrameters; } /* eslint-enable @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-assignment */ class RemoteRecognizer { /* eslint-enable lines-between-class-members */ constructor(wasmWorker, recognizerName, remoteObjHandle) { this.wasmSDKWorker = wasmWorker; this.objectHandle = remoteObjHandle; this.recognizerName = recognizerName; this.callbacks = new Map(); } /* eslint-enable @typescript-eslint/ban-types */ getRemoteObjectHandle() { return this.objectHandle; } currentSettings() { return new Promise((resolve, reject) => { if (this.objectHandle < 0) { reject("Invalid object handle: " + this.objectHandle.toString()); return; } const msg = new InvokeObjectMethod(this.objectHandle, "currentSettings", []); const handler = defaultResultEventHandler((msg) => { resolve(msg.result); }, reject); this.wasmSDKWorker.postMessage(msg, handler); }); } toJSON() { { // native module does not support toJSON method return Promise.resolve(null); } } clearAllCallbacks() { this.callbacks.clear(); this.wasmSDKWorker.unregisterRecognizerCallbacks(this.objectHandle); } /* eslint-disable @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-return */ // convert each function member into wrapped parameter, containing address where callback needs to be delivered removeFunctions(settings) { // clear any existing callbacks this.clearAllCallbacks(); const keys = Object.keys(settings); let needsRegistering = false; for (const key of keys) { const data = settings[key]; if (typeof data === "function") { this.callbacks.set(key, data); const wrappedFunction = { parameter: { recognizerHandle: this.objectHandle, callbackName: key }, type: ParameterType.Callback }; settings[key] = wrappedFunction; needsRegistering = true; } } if (needsRegistering) { this.wasmSDKWorker.registerRecognizerCallbacks(this.objectHandle, this); } return settings; } /* eslint-enable @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-return */ updateSettings(newSettings) { return new Promise((resolve, reject) => { if (this.objectHandle < 0) { reject("Invalid object handle: " + this.objectHandle.toString()); return; } /* eslint-disable @typescript-eslint/no-unsafe-assignment */ const msg = new InvokeObjectMethod(this.objectHandle, "updateSettings", [ { parameter: this.removeFunctions(newSettings), type: ParameterType.RecognizerSettings } ]); /* eslint-enable @typescript-eslint/no-unsafe-assignment */ const handler = defaultEventHandler(resolve, reject); this.wasmSDKWorker.postMessage(msg, handler); }); } /* eslint-disable @typescript-eslint/no-explicit-any */ invokeCallback(callbackName, args) { const callback = this.callbacks.get(callbackName); if (callback !== undefined) { callback(...args); } else { console.warn("Cannot find callback", callbackName); } } /* eslint-enable @typescript-eslint/no-explicit-any */ getResult() { return new Promise((resolve, reject) => { if (this.objectHandle < 0) { reject("Invalid object handle: " + this.objectHandle.toString()); return; } const msg = new InvokeObjectMethod(this.objectHandle, "getResult", []); const handler = defaultResultEventHandler((msg) => { resolve(msg.result); }, reject); this.wasmSDKWorker.postMessage(msg, handler); }); } delete() { return new Promise((resolve, reject) => { if (this.objectHandle < 0) { reject("Invalid object handle: " + this.objectHandle.toString()); return; } this.clearAllCallbacks(); const msg = new InvokeObjectMethod(this.objectHandle, "delete", []); const handler = defaultEventHandler(() => { this.objectHandle = -1; resolve(); }, reject); this.wasmSDKWorker.postMessage(msg, handler); }); } } function createRegisteredCallbacks(metadataCallbacks) { const msg = new RegisteredMetadataCallbacks(); // https://stackoverflow.com/a/20093686/213057 msg.onDebugText = !!metadataCallbacks.onDebugText; msg.onDetectionFailed = !!metadataCallbacks.onDetectionFailed; msg.onPointsDetection = !!metadataCallbacks.onPointsDetection; msg.onQuadDetection = !!metadataCallbacks.onQuadDetection; msg.onFirstSideResult = !!metadataCallbacks.onFirstSideResult; msg.onGlare = !!metadataCallbacks.onGlare; return msg; } class RemoteRecognizerRunner { constructor(wasmWorker) { this.deleted = false; this.wasmSDKWorker = wasmWorker; } processImage(image) { return new Promise((resolve, reject) => { if (this.deleted) { reject("Recognizer runner is deleted. It cannot be used anymore!"); return; } const msg = new ProcessImage(image); const handler = defaultResultEventHandler((response) => { const state = response.recognitionState; resolve(state); }, reject); this.wasmSDKWorker.postTransferrableMessage(msg, handler); }); } reconfigureRecognizers(recognizers, allowMultipleResults) { return new Promise((resolve, reject) => { if (this.deleted) { reject("Recognizer runner is deleted. It cannot be used anymore!"); return; } const recognizerHandles = getRecognizerHandles(recognizers); const msg = new ReconfigureRecognizerRunner(recognizerHandles, allowMultipleResults); const handler = defaultEventHandler(resolve, reject); this.wasmSDKWorker.postMessage(msg, handler); }); } setMetadataCallbacks(metadataCallbacks) { return new Promise((resolve, reject) => { const msg = new RegisterMetadataCallbacks(createRegisteredCallbacks(metadataCallbacks)); const handler = defaultEventHandler(resolve, reject); this.wasmSDKWorker.postMessageAndRegisterCallbacks(msg, metadataCallbacks, handler); }); } resetRecognizers(hardReset) { return new Promise((resolve, reject) => { const msg = new ResetRecognizers(hardReset); const handler = defaultEventHandler(resolve, reject); this.wasmSDKWorker.postMessage(msg, handler); }); } setDetectionOnlyMode(detectionOnly) { return new Promise((resolve, reject) => { const msg = new SetDetectionOnly(detectionOnly); const handler = defaultEventHandler(resolve, reject); this.wasmSDKWorker.postMessage(msg, handler); }); } setClearTimeoutCallback(clearTimeoutCallback) { return new Promise((resolve, reject) => { const msg = new SetClearTimeoutCallback(clearTimeoutCallback !== null); const handler = defaultEventHandler(resolve, reject); this.wasmSDKWorker.registerClearTimeoutCallback(clearTimeoutCallback); this.wasmSDKWorker.postMessage(msg, handler); }); } setCameraPreviewMirrored(mirrored) { return new Promise((resolve, reject) => { const msg = new SetCameraPreviewMirrored(mirrored); const handler = defaultEventHandler(resolve, reject); this.wasmSDKWorker.postMessage(msg, handler); }); } delete() { if (this.deleted) { return Promise.reject("Recognizer runner is already deleted."); } return new Promise((resolve, reject) => { const msg = new DeleteRecognizerRunner(); const handler = defaultEventHandler(() => { this.deleted = true; resolve(); }, reject); this.wasmSDKWorker.postMessage(msg, handler); }); } } function getRecognizerHandles(remoteRecognizers) { const recognizerHandles = []; for (const remoteRecognizer of remoteRecognizers) { recognizerHandles.push(remoteRecognizer.getRemoteObjectHandle()); } return recognizerHandles; } class WasmModuleWorkerProxy { constructor(wasmSDKWorker) { this.wasmSDKWorker = wasmSDKWorker; } createRecognizerRunner(recognizers, allowMultipleResults = false, metadataCallbacks = {}) { return new Promise((resolve, reject) => { const recognizerHandles = getRecognizerHandles(recognizers); const msg = new CreateRecognizerRunner(recognizerHandles, allowMultipleResults, createRegisteredCallbacks(metadataCallbacks)); const handler = defaultEventHandler(() => { resolve(new RemoteRecognizerRunner(this.wasmSDKWorker)); }, reject); this.wasmSDKWorker.postMessageAndRegisterCallbacks(msg, metadataCallbacks, handler); }); } /* eslint-disable @typescript-eslint/no-explicit-any */ newRecognizer(className, ...constructorArgs) { return new Promise((resolve, reject) => { const msg = new CreateNewRecognizer(className, wrapParameters(constructorArgs)); const handler = defaultResultEventHandler((msg) => { const remoteRecognizer = new RemoteRecognizer(this.wasmSDKWorker, className, msg.objectHandle); resolve(remoteRecognizer); }, reject); this.wasmSDKWorker.postMessage(msg, handler); }); } } class WasmSDKWorker { /* eslint-enable lines-between-class-members */ constructor(worker, loadProgressCallback, rejectHandler) { this.eventHandlers = {}; this.metadataCallbacks = {}; this.clearTimeoutCallback = null; this.loadedWasmType = WasmType.Basic; // will be updated after WASM gets loaded this.mbWasmWorker = worker; this.mbWasmWorker.onmessage = (event) => { this.handleWorkerEvent(event); }; this.mbWasmWorker.onerror = () => { rejectHandler("Problem during initialization of worker file!"); return; }; this.mbWasmModule = new WasmModuleWorkerProxy(this); this.loadCallback = loadProgressCallback; this.recognizersWithCallbacks = new Map(); this.showOverlay = false; } postMessage(message, eventHandler) { this.eventHandlers[message.messageID] = eventHandler; this.mbWasmWorker.postMessage(message); } postTransferrableMessage(message, eventHandler) { this.eventHandlers[message.messageID] = eventHandler; this.mbWasmWorker.postMessage(message, message.getTransferrables()); } postMessageAndRegisterCallbacks(message, metadataCallbacks, eventHandler) { this.eventHandlers[message.messageID] = eventHandler; this.metadataCallbacks = metadataCallbacks; this.mbWasmWorker.postMessage(message); } registerClearTimeoutCallback(callback) { this.clearTimeoutCallback = callback; } registerRecognizerCallbacks(remoteRecognizerHandle, recognizer) { this.recognizersWithCallbacks.set(remoteRecognizerHandle, recognizer); } unregisterRecognizerCallbacks(remoteRecognizerHandle) { this.recognizersWithCallbacks.delete(remoteRecognizerHandle); } /** * Clean up the active instance of the SDK. * * It's not possible to use the SDK after this method is called. */ delete() { this.mbWasmWorker.terminate(); } handleWorkerEvent(event) { if ("isCallbackMessage" in event.data) { const msg = event.data; switch (msg.callbackType) { case MetadataCallback.onDebugText: if (typeof this.metadataCallbacks.onDebugText === "function") { this.metadataCallbacks.onDebugText(msg.callbackParameters[0]); } break; case MetadataCallback.onDetectionFailed: if (typeof this.metadataCallbacks.onDetectionFailed === "function") { this.metadataCallbacks.onDetectionFailed(); } break; case MetadataCallback.onPointsDetection: if (typeof this.metadataCallbacks.onPointsDetection === "function") { this.metadataCallbacks.onPointsDetection(msg.callbackParameters[0]); } break; case MetadataCallback.onQuadDetection: if (typeof this.metadataCallbacks.onQuadDetection === "function") { this.metadataCallbacks.onQuadDetection(msg.callbackParameters[0]); } break; case MetadataCallback.onFirstSideResult: if (typeof this.metadataCallbacks.onFirstSideResult === "function") { this.metadataCallbacks.onFirstSideResult(); } break; case MetadataCallback.clearTimeoutCallback: if (this.clearTimeoutCallback && typeof this.clearTimeoutCallback.onClearTimeout === "function") { this.clearTimeoutCallback.onClearTimeout(); } break; case MetadataCallback.onGlare: if (typeof this.metadataCallbacks.onGlare === "function") { this.metadataCallbacks.onGlare(msg.callbackParameters[0]); } break; case MetadataCallback.recognizerCallback: { // first parameter is address, other parameters are callback parameters const address = msg.callbackParameters.shift(); const recognizer = this.recognizersWithCallbacks.get(address.recognizerHandle); if (recognizer !== undefined) { recognizer.invokeCallback(address.callbackName, msg.callbackParameters); } else { console.warn("Cannot find recognizer to deliver callback message. Maybe it's destroyed?", address); } break; } default: throw new Error(`Unknown callback type: ${MetadataCallback[msg.callbackType]}`); } } else if ("isLoadProgressMessage" in event.data) { const msg = event.data; if (typeof this.loadCallback === "function") { this.loadCallback(msg.progress); } } else { const msg = event.data; const eventHandler = this.eventHandlers[msg.messageID]; delete this.eventHandlers[msg.messageID]; eventHandler(msg); } } static createWasmWorker(worker, wasmLoadSettings, userId) { return __awaiter(this, void 0, void 0, function* () { return new Promise((resolve, reject) => { const wasmWorker = new WasmSDKWorker(worker, wasmLoadSettings.loadProgressCallback, reject); const initMessage = new InitMessage(wasmLoadSettings, userId); const initEventHandler = defaultResultEventHandler((msg) => { const successMsg = msg; wasmWorker.showOverlay = successMsg.showOverlay; wasmWorker.loadedWasmType = successMsg.wasmType; resolve(wasmWorker); }, /* eslint-disable @typescript-eslint/no-explicit-any */ (error) => { if (wasmWorker && typeof wasmWorker.delete === "function") { wasmWorker.delete(); } reject(error); } /* eslint-enable @typescript-eslint/no-explicit-any */ ); wasmWorker.postMessage(initMessage, initEventHandler); }); }); } } /** * Copyright (c) Microblink Ltd. All rights reserved. */ /* eslint-disable @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-assignment, @typescript-eslint/explicit-module-boundary-types */ class SDKError { constructor(error, details) { if (!error.code || !error.message) { throw new Error("Instance of SDKError is required to have code and message."); } this.message = error.message; this.code = error.code; this.details = details; } } /** * Copyright (c) Microblink Ltd. All rights reserved. */ /* eslint-disable max-len */ /** * Structures of Error Codes, Error Messages, and CustomError compatible objects for the Error Generator utility. * Error Code convention: SECTION_OBJECT_(ACTION)_PROBLEM */ var ErrorCodes$1; (function (ErrorCodes) { ErrorCodes["WORKER_WASM_LOAD_FAILURE"] = "WORKER_WASM_LOAD_FAILURE"; ErrorCodes["WORKER_WASM_INIT_MISSING"] = "WORKER_WASM_INIT_MISSING"; ErrorCodes["WORKER_FUNCTION_INVOKE_FAILURE"] = "WORKER_FUNCTION_INVOKE_FAILURE"; ErrorCodes["WORKER_RECOGNIZER_CREATION_FAILURE"] = "WORKER_RECOGNIZER_CREATION_FAILURE"; ErrorCodes["WORKER_RUNNER_EXISTS"] = "WORKER_RUNNER_EXISTS"; ErrorCodes["WORKER_RUNNER_CREATION_FAILURE"] = "WORKER_RUNNER_CREATION_FAILURE"; ErrorCodes["WORKER_RUNNER_MISSING"] = "WORKER_RUNNER_MISSING"; ErrorCodes["WORKER_RUNNER_RECONFIGURE_FAILURE"] = "WORKER_RUNNER_RECONFIGURE_FAILURE"; ErrorCodes["WORKER_RUNNER_DELETED"] = "WORKER_RUNNER_DELETED"; ErrorCodes["WORKER_RUNNER_DELETE_FAILURE"] = "WORKER_RUNNER_DELETE_FAILURE"; ErrorCodes["WORKER_OBJECT_INVOKE_FAILURE"] = "WORKER_OBJECT_INVOKE_FAILURE"; ErrorCodes["WORKER_IMAGE_PROCESS_FAILURE"] = "WORKER_IMAGE_PROCESS_FAILURE"; ErrorCodes["WORKER_HANDLE_UNDEFINED"] = "WORKER_HANDLE_UNDEFINED"; ErrorCodes["WORKER_MESSAGE_ACTION_UNKNOWN"] = "WORKER_MESSAGE_ACTION_UNKNOWN"; ErrorCodes["WORKER_LICENSE_UNLOCK_ERROR"] = "WORKER_LICENSE_UNLOCK_ERROR"; ErrorCodes["LOCAL_SDK_RUNNER_MISSING"] = "LOCAL_SDK_RUNNER_MISSING"; ErrorCodes["LOCAL_SDK_RUNNER_EMPTY"] = "LOCAL_SDK_RUNNER_EMPTY"; ErrorCodes["LICENSE_UNLOCK_ERROR"] = "LICENSE_UNLOCK_ERROR"; ErrorCodes["FRAME_CAPTURE_SVG_UNSUPPORTED"] = "FRAME_CAPTURE_SVG_UNSUPPORTED"; ErrorCodes["FRAME_CAPTURE_CANVAS_MISSING"] = "FRAME_CAPTURE_CANVAS_MISSING"; ErrorCodes["SDK_WASM_SETTINGS_MISSING"] = "SDK_WASM_SETTINGS_MISSING"; ErrorCodes["SDK_LICENSE_KEY_MISSING"] = "SDK_LICENSE_KEY_MISSING"; ErrorCodes["SDK_WASM_MODULE_NAME_MISSING"] = "SDK_WASM_MODULE_NAME_MISSING"; ErrorCodes["SDK_ENGINE_LOCATION_INVALID"] = "SDK_ENGINE_LOCATION_INVALID"; ErrorCodes["SDK_MISSING"] = "SDK_MISSING"; ErrorCodes["SDK_RECOGNIZERS_MISSING"] = "SDK_RECOGNIZERS_MISSING"; ErrorCodes["VIDEO_RECOGNIZER_ELEMENT_MISSING"] = "VIDEO_RECOGNIZER_ELEMENT_MISSING"; ErrorCodes["VIDEO_RECOGNIZER_CAMERA_MISSING"] = "VIDEO_RECOGNIZER_CAMERA_MISSING"; ErrorCodes["VIDEO_RECOGNIZER_CAMERA_NOT_ALLOWED"] = "VIDEO_RECOGNIZER_CAMERA_NOT_ALLOWED"; ErrorCodes["VIDEO_RECOGNIZER_CAMERA_UNAVAILABLE"] = "VIDEO_RECOGNIZER_CAMERA_UNAVAILABLE"; ErrorCodes["VIDEO_RECOGNIZER_CAMERA_IN_USE"] = "VIDEO_RECOGNIZER_CAMERA_IN_USE"; ErrorCodes["VIDEO_RECOGNIZER_MEDIA_DEVICES_UNSUPPORTED"] = "VIDEO_RECOGNIZER_MEDIA_DEVICES_UNSUPPORTED"; ErrorCodes["VIDEO_RECOGNIZER_FEED_RELEASED"] = "VIDEO_RECOGNIZER_FEED_RELEASED"; ErrorCodes["VIDEO_RECOGNIZER_FEED_NOT_PAUSED"] = "VIDEO_RECOGNIZER_FEED_NOT_PAUSED"; ErrorCodes["VIDEO_RECOGNIZER_PLAY_REQUEST_INTERRUPTED"] = "VIDEO_RECOGNIZER_PLAY_REQUEST_INTERRUPTED"; ErrorCodes["VIDEO_RECOGNIZER_FEED_PAUSED"] = "VIDEO_RECOGNIZER_FEED_PAUSED"; ErrorCodes["VIDEO_RECOGNIZER_RECOGNIZERS_RESET_FAILURE"] = "VIDEO_RECOGNIZER_RECOGNIZERS_RESET_FAILURE"; ErrorCodes["VIDEO_RECOGNIZER_FEED_MISSING"] = "VIDEO_RECOGNIZER_FEED_MISSING"; })(ErrorCodes$1 || (ErrorCodes$1 = {})); var ErrorMessages$1; (function (ErrorMessages) { ErrorMessages["WORKER_HANDLE_UNDEFINED"] = "Cannot find object with handle: undefined"; ErrorMessages["WORKER_WASM_LOAD_FAILURE"] = "Failed to load WASM in web worker!"; ErrorMessages["WORKER_WASM_INIT_MISSING"] = "WASM module is not initialized!"; ErrorMessages["WORKER_FUNCTION_INVOKE_FAILURE"] = "Failed to invoke function!"; ErrorMessages["WORKER_RECOGNIZER_CREATION_FAILURE"] = "Failed to create new recognizer!"; ErrorMessages["WORKER_RUNNER_EXISTS"] = "Recognizer runner is already created! Multiple instances are not allowed!"; ErrorMessages["WORKER_RUNNER_CREATION_FAILURE"] = "Failed to create new recognizer runner!"; ErrorMessages["WORKER_RUNNER_MISSING"] = "Recognizer runner is not created! There is nothing to reconfigure!"; ErrorMessages["WORKER_RUNNER_RECONFIGURE_FAILURE"] = "Failed to reconfigure recognizer runner!"; ErrorMessages["WORKER_RUNNER_DELETED"] = "Recognizer runner is already deleted!"; ErrorMessages["WORKER_RUNNER_DELETE_FAILURE"] = "Failed to delete recognizer runner!"; ErrorMessages["WORKER_OBJECT_INVOKE_FAILURE"] = "Failed to invoke object!"; ErrorMessages["WORKER_IMAGE_PROCESS_FAILURE"] = "Recognizer runner is not initialized! Cannot process image!"; ErrorMessages["LOCAL_SDK_RUNNER_MISSING"] = "Property nativeRecognizerRunner is not available!"; ErrorMessages["LOCAL_SDK_RUNNER_EMPTY"] = "Native RecognizerRunner cannot be empty!"; ErrorMessages["LICENSE_TOKEN_STATE_INCORRECT"] = "Internal error (Incorrect token state)"; ErrorMessages["LICENSE_PAYLOAD_VERIFICATION_FAILED"] = "Failed to verify server permission's digital signature!"; ErrorMessages["LICENSE_PAYLOAD_CORRUPTED"] = "Server permission payload is corrupted!"; ErrorMessages["LICENSE_PERMISSION_EXPIRED"] = "Internal error (server permission expired)"; ErrorMessages["LICENSE_REMOTE_LOCKED"] = "Provided license key has been remotely locked. Please contact support for more information!"; ErrorMessages["FRAME_CAPTURE_SVG_UNSUPPORTED"] = "Recognition of SVG elements not supported!"; ErrorMessages["FRAME_CAPTURE_CANVAS_MISSING"] = "Could not get canvas 2d context!"; ErrorMessages["SDK_WASM_SETTINGS_MISSING"] = "Missing WASM load settings!"; ErrorMessages["SDK_LICENSE_KEY_MISSING"] = "Missing license key!"; ErrorMessages["SDK_WASM_MODULE_NAME_MISSING"] = "Missing WASM module name!"; ErrorMessages["SDK_ENGINE_LOCATION_INVALID"] = "Setting property 'engineLocation' must be a string!"; ErrorMessages["SDK_MISSING"] = "SDK is not provided!"; ErrorMessages["SDK_RECOGNIZERS_MISSING"] = "To create RecognizerRunner at least 1 recognizer is required."; ErrorMessages["VIDEO_RECOGNIZER_ELEMENT_MISSING"] = "Video element, i.e. camera feed is not provided!"; ErrorMessages["VIDEO_RECOGNIZER_CAMERA_MISSING"] = "Camera not found!"; ErrorMessages["VIDEO_RECOGNIZER_CAMERA_NOT_ALLOWED"] = "Camera not allowed!"; ErrorMessages["VIDEO_RECOGNIZER_CAMERA_UNAVAILABLE"] = "Camera not available!"; ErrorMessages["VIDEO_RECOGNIZER_CAMERA_IN_USE"] = "Camera in use!"; ErrorMessages["VIDEO_RECOGNIZER_MEDIA_DEVICES_UNSUPPORTED"] = "Media devices not supported by browser."; ErrorMessages["VIDEO_RECOGNIZER_FEED_RELEASED"] = "The associated video feed has been released!"; ErrorMessages["VIDEO_RECOGNIZER_FEED_NOT_PAUSED"] = "The associated video feed is not paused. Use resumeRecognition instead!"; ErrorMessages["VIDEO_RECOGNIZER_PLAY_REQUEST_INTERRUPTED"] = "The play() request was interrupted or prevented by browser security rules!"; ErrorMessages["VIDEO_RECOGNIZER_FEED_PAUSED"] = "Cannot resume recognition while video feed is paused! Use recognize or startRecognition"; ErrorMessages["VIDEO_RECOGNIZER_RECOGNIZERS_RESET_FAILURE"] = "Could not reset recognizers!"; ErrorMessages["VIDEO_RECOGNIZER_FEED_MISSING"] = "Missing video feed!"; })(ErrorMessages$1 || (ErrorMessages$1 = {})); const videoRecognizerErrors = { feedMissing: { message: ErrorMessages$1.VIDEO_RECOGNIZER_FEED_MISSING, code: ErrorCodes$1.VIDEO_RECOGNIZER_FEED_MISSING, }, recognizersResetFailure: { message: ErrorMessages$1.VIDEO_RECOGNIZER_RECOGNIZERS_RESET_FAILURE, code: ErrorCodes$1.VIDEO_RECOGNIZER_RECOGNIZERS_RESET_FAILURE, }, feedPaused: { message: ErrorMessages$1.VIDEO_RECOGNIZER_FEED_PAUSED, code: ErrorCodes$1.VIDEO_RECOGNIZER_FEED_PAUSED, }, playRequestInterrupted: { message: ErrorMessages$1.VIDEO_RECOGNIZER_PLAY_REQUEST_INTERRUPTED, code: ErrorCodes$1.VIDEO_RECOGNIZER_PLAY_REQUEST_INTERRUPTED, }, videoFeedNotPaused: { message: ErrorMessages$1.VIDEO_RECOGNIZER_FEED_NOT_PAUSED, code: ErrorCodes$1.VIDEO_RECOGNIZER_FEED_NOT_PAUSED, }, videoFeedReleased: { message: ErrorMessages$1.VIDEO_RECOGNIZER_FEED_RELEASED, code: ErrorCodes$1.VIDEO_RECOGNIZER_FEED_RELEASED, }, mediaDevicesUnsupported: { code: ErrorCodes$1.VIDEO_RECOGNIZER_MEDIA_DEVICES_UNSUPPORTED, message: ErrorMessages$1.VIDEO_RECOGNIZER_MEDIA_DEVICES_UNSUPPORTED, }, cameraMissing: { code: ErrorCodes$1.VIDEO_RECOGNIZER_CAMERA_MISSING, message: ErrorMessages$1.VIDEO_RECOGNIZER_CAMERA_MISSING, }, elementMissing: { message: ErrorMessages$1.VIDEO_RECOGNIZER_ELEMENT_MISSING, code: ErrorCodes$1.VIDEO_RECOGNIZER_ELEMENT_MISSING, }, }; const sdkErrors = { wasmSettingsMissing: { message: ErrorMessages$1.SDK_WASM_SETTINGS_MISSING, code: ErrorCodes$1.SDK_WASM_SETTINGS_MISSING, }, licenseKeyMissing: { message: ErrorMessages$1.SDK_LICENSE_KEY_MISSING, code: ErrorCodes$1.SDK_LICENSE_KEY_MISSING, }, wasmModuleNameMissing: { message: ErrorMessages$1.SDK_WASM_MODULE_NAME_MISSING, code: ErrorCodes$1.SDK_WASM_MODULE_NAME_MISSING, }, engineLocationInvalid: { message: ErrorMessages$1.SDK_ENGINE_LOCATION_INVALID, code: ErrorCodes$1.SDK_ENGINE_LOCATION_INVALID, }, missing: { message: ErrorMessages$1.SDK_MISSING, code: ErrorCodes$1.SDK_MISSING, }, recognizersMissing: { message: ErrorMessages$1.SDK_RECOGNIZERS_MISSING, code: ErrorCodes$1.SDK_RECOGNIZERS_MISSING, }, }; const frameCaptureErrors = { svgUnsupported: { message: ErrorMessages$1.FRAME_CAPTURE_SVG_UNSUPPORTED, code: ErrorCodes$1.FRAME_CAPTURE_SVG_UNSUPPORTED, }, canvasMissing: { message: ErrorMessages$1.FRAME_CAPTURE_CANVAS_MISSING, code: ErrorCodes$1.FRAME_CAPTURE_CANVAS_MISSING, }, }; const licenseErrors = { licenseTokenStateIncorrect: { code: ErrorCodes$1.LICENSE_UNLOCK_ERROR, message: ErrorMessages$1.LICENSE_TOKEN_STATE_INCORRECT, }, licensePayloadVerificationFailed: { code: ErrorCodes$1.LICENSE_UNLOCK_ERROR, message: ErrorMessages$1.LICENSE_PAYLOAD_VERIFICATION_FAILED, }, licensePayloadCorrupted: { code: ErrorCodes$1.LICENSE_UNLOCK_ERROR, message: ErrorMessages$1.LICENSE_PAYLOAD_CORRUPTED, }, licensePermissionExpired: { code: ErrorCodes$1.LICENSE_UNLOCK_ERROR, message: ErrorMessages$1.LICENSE_PERMISSION_EXPIRED, }, licenseRemoteLocked: { code: ErrorCodes$1.LICENSE_UNLOCK_ERROR, message: ErrorMessages$1.LICENSE_REMOTE_LOCKED, }, licenseNetworkError: { code: ErrorCodes$1.LICENSE_UNLOCK_ERROR, }, licenseInvalid: { code: ErrorCodes$1.LICENSE_UNLOCK_ERROR, }, }; const localSdkErrors = { runnerMissing: { message: ErrorMessages$1.LOCAL_SDK_RUNNER_MISSING, code: ErrorCodes$1.LOCAL_SDK_RUNNER_MISSING, }, runnerEmpty: { message: ErrorMessages$1.LOCAL_SDK_RUNNER_EMPTY, code: ErrorCodes$1.LOCAL_SDK_RUNNER_EMPTY, }, }; const workerErrors = { imageProcessFailure: { message: ErrorMessages$1.WORKER_IMAGE_PROCESS_FAILURE, code: ErrorCodes$1.WORKER_IMAGE_PROCESS_FAILURE, }, objectInvokeFailure: { message: ErrorMessages$1.WORKER_OBJECT_INVOKE_FAILURE, code: ErrorCodes$1.WORKER_OBJECT_INVOKE_FAILURE, }, runnerDeleteFailure: { message: ErrorMessages$1.WORKER_RUNNER_DELETE_FAILURE, code: ErrorCodes$1.WORKER_RUNNER_DELETE_FAILURE, }, runnerDeleted: { message: ErrorMessages$1.WORKER_RUNNER_DELETED, code: ErrorCodes$1.WORKER_RUNNER_DELETED, }, runnerReconfigureFailure: { message: ErrorMessages$1.WORKER_RUNNER_RECONFIGURE_FAILURE, code: ErrorCodes$1.WORKER_RUNNER_RECONFIGURE_FAILURE, }, runnerMissing: { message: ErrorMessages$1.WORKER_RUNNER_MISSING, code: ErrorCodes$1.WORKER_RUNNER_MISSING, }, runnerCreationFailure: { message: ErrorMessages$1.WORKER_RUNNER_CREATION_FAILURE, code: ErrorCodes$1.WORKER_RUNNER_CREATION_FAILURE, }, runnerExists: { message: ErrorMessages$1.WORKER_RUNNER_EXISTS, code: ErrorCodes$1.WORKER_RUNNER_EXISTS, }, recognizerCreationFailure: { message: ErrorMessages$1.WORKER_RECOGNIZER_CREATION_FAILURE, code: ErrorCodes$1.WORKER_RECOGNIZER_CREATION_FAILURE, }, functionInvokeFailure: { message: ErrorMessages$1.WORKER_FUNCTION_INVOKE_FAILURE, code: ErrorCodes$1.WORKER_FUNCTION_INVOKE_FAILURE, }, wasmInitMissing: { message: ErrorMessages$1.WORKER_WASM_INIT_MISSING, code: ErrorCodes$1.WORKER_WASM_INIT_MISSING, }, wasmLoadFailure: { message: ErrorMessages$1.WORKER_WASM_LOAD_FAILURE, code: ErrorCodes$1.WORKER_WASM_LOAD_FAILURE, }, handleUndefined: { message: ErrorMessages$1.WORKER_HANDLE_UNDEFINED, code: ErrorCodes$1.WORKER_HANDLE_UNDEFINED, }, }; /** * Copyright (c) Microblink Ltd. All rights reserved. */ /** * Preferred type of camera to be used when opening the camera feed. */ var PreferredCameraType; (function (PreferredCameraType) { /** Prefer back facing camera */ PreferredCameraType[PreferredCameraType["BackFacingCamera"] = 0] = "BackFacingCamera"; /** Prefer front facing camera */ PreferredCameraType[PreferredCameraType["FrontFacingCamera"] = 1] = "FrontFacingCamera"; })(PreferredCameraType || (PreferredCameraType = {})); // inspired by https://unpkg.com/browse/scandit-sdk@4.6.1/src/lib/cameraAccess.ts const backCameraKeywords = [ "rear", "back", "rück", "arrière", "trasera", "trás", "traseira", "posteriore", "后面", "後面", "背面", "后置", "後置", "背置", "задней", "الخلفية", "후", "arka", "achterzijde", "หลัง", "baksidan", "bagside", "sau", "bak", "tylny", "takakamera", "belakang", "אחורית", "πίσω", "spate", "hátsó", "zadní", "darrere", "zadná", "задня", "stražnja", "belakang", "बैक" ]; function isBackCameraLabel(label) { const lowercaseLabel = label.toLowerCase(); return backCameraKeywords.some(keyword => lowercaseLabel.includes(keyword)); } class SelectedCamera { constructor(mdi, facing) { this.deviceId = mdi.deviceId; this.facing = facing; this.groupId = mdi.groupId; this.label = mdi.label; } } function getCameraDevices$1() { return __awaiter(this, void 0, void 0, function* () { const frontCameras = []; const backCameras = []; { let devices = yield navigator.mediaDevices.enumerateDevices(); // if permission is not given, label of video devices will be empty string if (devices.filter(device => device.kind === "videoinput").every(device => device.label === "")) { const stream = yield navigator.mediaDevices.getUserMedia({ video: { facingMode: { ideal: "environment" } }, audio: false }); // enumerate devices again - now the label field should be non-empty, as we have a stream active // (even if we didn't get persistent permission for camera) devices = yield navigator.mediaDevices.enumerateDevices(); // close the stream, as we don't need it anymore stream.getTracks().forEach(track => track.stop()); } const cameras = devices.filter(device => device.kind === "videoinput"); for (const camera of cameras) { if (isBackCameraLabel(camera.label)) { backCameras.push(new SelectedCamera(camera, PreferredCameraType.BackFacingCamera)); } else { frontCameras.push(new SelectedCamera(camera, PreferredCameraType.FrontFacingCamera)); } } } return { frontCameras, backCameras }; }); } function selectCamera(cameraId, preferredCameraType) { return __awaiter(this, void 0, void 0, function* () { const { frontCameras, backCameras } = yield getCameraDevices$1(); if (frontCameras.length > 0 || backCameras.length > 0) { // decide from which array the camera will be selected let cameraPool = (backCameras.length > 0 ? backCameras : frontCameras); // if there is at least one back facing camera and user prefers back facing camera, use that as a selection pool if (preferredCameraType === PreferredCameraType.BackFacingCamera && backCameras.length > 0) { cameraPool = backCameras; } // if there is at least one front facing camera and is preferred by user, use that as a selection pool if (preferredCameraType === PreferredCameraType.FrontFacingCamera && frontCameras.length > 0) { cameraPool = frontCameras; } // otherwise use whichever pool is non-empty // sort camera pool by label cameraPool = cameraPool.sort((camera1, camera2) => camera1.label.localeCompare(camera2.label)); // Check if cameras are labeled with resolution information, take the higher-resolution one in that case // Otherwise pick the first camera { let selectedCameraIndex = 0; const cameraResolutions = cameraPool.map(camera => { const regExp = RegExp(/\b([0-9]+)MP?\b/, "i"); const match = regExp.exec(camera.label); if (match !== null) { return parseInt(match[1], 10); } else { return NaN; } }); if (!cameraResolutions.some(cameraResolution => isNaN(cameraResolution))) { selectedCameraIndex = cameraResolutions.lastIndexOf(Math.max(...cameraResolutions)); } if (cameraId) { let cameraDevice = null; cameraDevice = frontCameras.filter(device => device.deviceId === cameraId)[0]; if (!cameraDevice) { cameraDevice = backCameras.filter(device => device.deviceId === cameraId)[0]; } return cameraDevice || null; } return cameraPool[selectedCameraIndex]; } } else { // no cameras available on the device return null; } }); } /** * Bind camera device to video feed (HTMLVideoElement). * * This function will return `true` in case that video feed of camera device has been flipped, * and `false` otherwise. * * @param camera Camera device which should be binded with the video element. * @param videoFeed HTMLVideoElement to which camera device should be binded. * @param preferredCameraType Enum representing whether to use front facing or back facing camera. */ function bindCameraToVideoFeed(camera, videoFeed, preferredCameraType = PreferredCameraType.BackFacingCamera) { return __awaiter(this, void 0, void 0, function* () { const constraints = { audio: false, video: { width: { min: 640, ideal: 1920, max: 1920 }, height: { min: 480, ideal: 1080, max: 1080 } } }; if (camera.deviceId === "") { const isPreferredBackFacing = preferredCameraType === PreferredCameraType.BackFacingCamera; constraints.video.facingMode = { ideal: isPreferredBackFacing ? "environment" : "user" }; } else { constraints.video.deviceId = { exact: camera.deviceId }; } const stream = yield navigator.mediaDevices.getUserMedi