@monitordog/detector 1.0.2 → 1.0.3

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 (34) hide show
  1. package/README.md +13 -107
  2. package/dist/assets/inference-worker-EjUccpPR.js +8 -0
  3. package/dist/assets/ort/ort-wasm-simd-threaded.mjs +59 -0
  4. package/dist/assets/ort/ort-wasm-simd-threaded.wasm +0 -0
  5. package/dist/assets/sdk/detector-320.onnx.enc +0 -0
  6. package/dist/assets/sdk/detector-416.onnx.enc +0 -0
  7. package/dist/assets/sdk/detector-640.onnx.enc +0 -0
  8. package/dist/constants.d.ts +0 -6
  9. package/dist/detect/model-loader.d.ts +1 -11
  10. package/dist/environment.d.ts +0 -8
  11. package/dist/events.d.ts +2 -5
  12. package/dist/index.d.ts +1 -3
  13. package/dist/monitordog-detector.js +603 -11543
  14. package/dist/monitordog-detector.umd.cjs +1 -54
  15. package/dist/service/container.d.ts +0 -8
  16. package/dist/service/detect-service.d.ts +0 -30
  17. package/dist/service/detection-event-service.d.ts +2 -10
  18. package/dist/service/webcam-service.d.ts +0 -2
  19. package/dist/types.d.ts +19 -97
  20. package/package.json +15 -18
  21. package/dist/assets/inference-worker-C-n1YxCo.js +0 -2
  22. package/dist/detect/wasm/webcam-frame-analysis-wasm-bytes.d.ts +0 -1
  23. package/dist/detect/webcam-blockage-detector.d.ts +0 -32
  24. package/dist/detect/webcam-frame-analysis-wasm.d.ts +0 -47
  25. package/dist/detect/webcam-frame-analysis.d.ts +0 -34
  26. package/dist/detect/webcam-lighting-detector.d.ts +0 -21
  27. package/dist/language.d.ts +0 -6
  28. package/dist/monitordog-detector.d.ts +0 -41
  29. package/dist/pose/mediapipe-asset-loader.d.ts +0 -16
  30. package/dist/pose/mediapipe-main-user-tracker.d.ts +0 -90
  31. package/dist/pose.d.ts +0 -15
  32. package/dist/service/overlay-renderer.d.ts +0 -71
  33. package/dist/service/overlay-service.d.ts +0 -75
  34. package/dist/service/overlay-watchdog-service.d.ts +0 -13
@@ -3,7 +3,6 @@ import { AuthService } from "./auth-service";
3
3
  import { CameraService } from "./camera-service";
4
4
  import { DetectionEventService } from "./detection-event-service";
5
5
  import { DetectService } from "./detect-service";
6
- import { OverlayService } from "./overlay-service";
7
6
  import { WebcamService } from "./webcam-service";
8
7
  export type DetectorOptions = Required<Pick<MonitorDogDetectorOptions, "apiBaseUrl">> & MonitorDogDetectorOptions & {
9
8
  confidenceThreshold: number;
@@ -18,17 +17,11 @@ export type DetectorOptions = Required<Pick<MonitorDogDetectorOptions, "apiBaseU
18
17
  export declare class ServiceContainer {
19
18
  #private;
20
19
  readonly auth: AuthService;
21
- readonly overlay: OverlayService;
22
20
  readonly camera: CameraService;
23
21
  readonly detectionEvents: DetectionEventService;
24
22
  readonly detect: DetectService;
25
23
  readonly webcam: WebcamService;
26
- onCameraRetry?: () => void | Promise<void>;
27
24
  onCameraDisconnect?: () => void | Promise<void>;
28
- onRemoteUnlock?: () => void | Promise<void>;
29
- onRemoteUnlockRequest?: () => void | Promise<void>;
30
- getRemoteUnlockRequestCooldownMs?: () => number;
31
- onShutdownRequest?: () => void;
32
25
  onLoginRequired?: () => void;
33
26
  constructor(getOptions: () => DetectorOptions);
34
27
  get options(): Readonly<DetectorOptions>;
@@ -39,7 +32,6 @@ export declare class ServiceContainer {
39
32
  degradeInferenceModelForMemoryPressure(): void;
40
33
  get shouldPauseForHiddenPage(): boolean;
41
34
  get shouldPauseDetection(): boolean;
42
- get shouldPauseForResumePassword(): boolean;
43
35
  applyPolicyItems(items: LockPolicyResponse[], _account: AccountResponse): void;
44
36
  resetAuthenticatedState(): void;
45
37
  }
@@ -5,49 +5,19 @@ export declare class DetectService {
5
5
  private inferenceWorker?;
6
6
  private loadPromise?;
7
7
  private lastInferenceMemoryErrorAt;
8
- private mainUserTracker?;
9
- private mainUserTrackerLoadPromise?;
10
- private mainUserTrackerLoadTimeoutId?;
11
- private mainUserTrackerLoadToken;
12
- private mainUserTrackerDisabledReason;
13
- private mainUserTrackingEnabled;
14
- private webcamFrameAnalyzer?;
15
- private webcamBlockageDetector?;
16
- private webcamLightingDetector?;
17
- private activeLightingOverlayState?;
18
- private poseDebugCanvas?;
19
- private baselineRefreshPendingAfterNoFace;
20
8
  constructor(services: ServiceContainer);
21
9
  load(): Promise<void>;
22
10
  detect(source: MonitorDogImageSource): Promise<InternalDetectionResult>;
23
11
  toPublicResult(result: InternalDetectionResult): MonitorDogDetectionResult;
24
12
  detectVideo(video: HTMLVideoElement): MonitorDogVideoDetectionController;
25
13
  startWebcamDetection(): Promise<MonitorDogWebcamDetectionController>;
26
- isMainUserTrackingEnabled(): boolean;
27
- setMainUserTrackingEnabled(enabled: boolean): void;
28
14
  dispose(): void;
29
- private ensureMainUserTrackerLoading;
30
- private scheduleMainUserTrackerLoading;
31
- private clearMainUserTrackerLoadTimeout;
32
- private loadMainUserTracker;
33
- private detectMainUser;
34
- private isNoUserTrackingState;
35
- private shouldRefreshBaselineForNormalState;
36
- private handleWebcamLightingResult;
37
- private clearWebcamLightingOverlay;
38
- private renderPoseDebugOverlay;
39
- private getPoseDebugCanvas;
40
- private clearPoseDebugOverlay;
41
- private drawPoseDebug;
42
15
  private handleDetectionLoopError;
43
16
  private recoverFromInferenceMemoryError;
44
17
  private resetInferenceWorker;
45
18
  private degradeModelForMemoryPressure;
46
19
  private isInferenceMemoryError;
47
20
  private getInferenceWorker;
48
- private getWebcamFrameAnalyzer;
49
- private getWebcamBlockageDetector;
50
- private getWebcamLightingDetector;
51
21
  private loadInferenceWorker;
52
22
  private loadInferenceWorkerWithOptions;
53
23
  }
@@ -1,5 +1,3 @@
1
- import type { WebcamBlockageAnalysis } from "../detect/webcam-blockage-detector";
2
- import type { MainUserTrackingResult } from "../pose/mediapipe-main-user-tracker";
3
1
  import type { InternalDetectionResult, MonitorDogImageSource } from "../types";
4
2
  import type { ServiceContainer } from "./container";
5
3
  export declare class DetectionEventService {
@@ -11,22 +9,16 @@ export declare class DetectionEventService {
11
9
  private noFaceStartedAt?;
12
10
  private suppressNoFaceUntil;
13
11
  constructor(services: ServiceContainer);
14
- handleDetectionResult(result: InternalDetectionResult, trackingResult: MainUserTrackingResult, source?: MonitorDogImageSource): Promise<void>;
15
- handleWebcamBlockageResult(analysis: WebcamBlockageAnalysis, source?: MonitorDogImageSource): Promise<void>;
12
+ handleDetectionResult(result: InternalDetectionResult, source?: MonitorDogImageSource): Promise<void>;
16
13
  reset(): void;
17
14
  resetForWebcamStartup(): void;
18
- resetAfterResumePasswordUnlock(): void;
15
+ clearTransientState(): void;
19
16
  private uploadWebcamImage;
20
17
  private uploadMonitorImage;
21
18
  private uploadImage;
22
19
  private shouldSendEvent;
23
- private shouldSendWebcamBlockedEvent;
24
- private shouldShowOverlay;
25
20
  private lock;
26
21
  private clearLock;
27
22
  private hasNoFaceDelayElapsed;
28
23
  private getLockDuration;
29
- private getOverlayDuration;
30
- private shouldPauseDetectionAfterCapture;
31
- private getMode;
32
24
  }
@@ -21,6 +21,4 @@ export declare class WebcamService {
21
21
  private handleCameraDisconnect;
22
22
  private addVisibilityListener;
23
23
  private removeVisibilityListener;
24
- private isCameraPermissionError;
25
- private isCameraReadError;
26
24
  }
package/dist/types.d.ts CHANGED
@@ -1,6 +1,5 @@
1
- import type { MainUserTrackingResult } from "./pose/mediapipe-main-user-tracker";
2
1
  import type { MonitorDogSdkError } from "./sdk-error";
3
- export type DetectionReasonEnum = "mobileDevice" | "noFaceDetected" | "twoFacesDetected" | "oneFaceDetected" | "logout" | "login" | "webcamBlocked";
2
+ export type DetectionReasonEnum = "mobileDevice" | "noFaceDetected" | "twoFacesDetected" | "oneFaceDetected" | "logout" | "login";
4
3
  export type MonitorDogImageSource = HTMLImageElement | HTMLCanvasElement | HTMLVideoElement | ImageBitmap | ImageData;
5
4
  export interface MonitorDogDetection {
6
5
  classId: number;
@@ -25,23 +24,8 @@ export interface DetectionEvent {
25
24
  type: MonitorDogDetectionEventType;
26
25
  payload: CreateEventPayload;
27
26
  }
28
- export type MonitorDogDetectionEventType = "noFaceDetected" | "twoFacesDetected" | "mobileDevice" | "webcamBlocked";
27
+ export type MonitorDogDetectionEventType = "noFaceDetected" | "twoFacesDetected" | "mobileDevice";
29
28
  export type MonitorDogUserActivityEventType = "login" | "logout";
30
- export type MonitorDogOverlayType = MonitorDogDetectionEventType | "webcamTooDark" | "webcamTooBright" | "cameraPermissionDenied" | "cameraReadableError";
31
- export type MonitorDogLanguage = "en" | "ko" | "ja";
32
- export interface MonitorDogOverlayMessages extends Record<MonitorDogOverlayType, string> {
33
- remoteAdminLocked: string;
34
- remoteLocked: string;
35
- cameraRetryButton: string;
36
- cameraRetryingButton: string;
37
- remoteUnlockButton: string;
38
- remoteUnlockingButton: string;
39
- remoteUnlockRequestButton: string;
40
- remoteUnlockRequestingButton: string;
41
- noFacePasswordInputPlaceholder: string;
42
- noFacePasswordSubmitButton: string;
43
- noFacePasswordSubmittingButton: string;
44
- }
45
29
  export type DeviceType = "desktop" | "mobile" | "tablet" | "laptop" | "other" | "none";
46
30
  export type DeviceOs = "windows" | "macos" | "linux" | "android" | "ios" | "other" | "none";
47
31
  export type CreateEventPayload = {
@@ -66,46 +50,10 @@ export type CreateEventPayload = {
66
50
  video_urls?: Array<string>;
67
51
  program_list?: Array<string>;
68
52
  };
69
- export interface MonitorDogOverlayOptions {
70
- enabled?: boolean;
71
- locale?: MonitorDogLanguage;
72
- watchdog?: boolean;
73
- watchdogIntervalMs?: number;
74
- rootId?: string;
75
- className?: string;
76
- messageClassName?: string;
77
- cameraRetryButtonClassName?: string;
78
- style?: Partial<CSSStyleDeclaration>;
79
- messageStyle?: Partial<CSSStyleDeclaration>;
80
- cameraRetryButtonStyle?: Partial<CSSStyleDeclaration>;
81
- cameraRetryButtonText?: string;
82
- cameraRetryingButtonText?: string;
83
- remoteUnlockButtonClassName?: string;
84
- remoteUnlockButtonStyle?: Partial<CSSStyleDeclaration>;
85
- remoteUnlockButtonText?: string;
86
- remoteUnlockingButtonText?: string;
87
- remoteUnlockRequestButtonText?: string;
88
- remoteUnlockRequestingButtonText?: string;
89
- noFacePasswordFormClassName?: string;
90
- noFacePasswordFormStyle?: Partial<CSSStyleDeclaration>;
91
- noFacePasswordInputClassName?: string;
92
- noFacePasswordInputStyle?: Partial<CSSStyleDeclaration>;
93
- noFacePasswordInputPlaceholder?: string;
94
- noFacePasswordToggleButtonClassName?: string;
95
- noFacePasswordToggleButtonStyle?: Partial<CSSStyleDeclaration>;
96
- noFacePasswordOpenIconSrc?: string;
97
- noFacePasswordCloseIconSrc?: string;
98
- noFacePasswordSubmitButtonClassName?: string;
99
- noFacePasswordSubmitButtonStyle?: Partial<CSSStyleDeclaration>;
100
- noFacePasswordSubmitButtonText?: string;
101
- noFacePasswordSubmittingButtonText?: string;
102
- messages?: Partial<MonitorDogOverlayMessages>;
103
- }
104
53
  export type MonitorDogCaptureImageResult = Blob | File | undefined | null;
105
54
  export interface MonitorDogVideoDetectionResult extends MonitorDogDetectionResult {
106
55
  video: HTMLVideoElement;
107
56
  timestamp: number;
108
- mainUserTracking: MainUserTrackingResult;
109
57
  }
110
58
  export interface MonitorDogVideoDetectionController {
111
59
  stop: () => void;
@@ -124,13 +72,9 @@ export interface MonitorDogDetectorOptions {
124
72
  video?: HTMLVideoElement;
125
73
  onDetect: (result: MonitorDogVideoDetectionResult) => void | Promise<void>;
126
74
  onError?: (error: unknown) => void;
127
- overlay?: MonitorDogOverlayOptions;
128
75
  captureMonitorImage?: () => MonitorDogCaptureImageResult | Promise<MonitorDogCaptureImageResult>;
129
76
  constraints?: MediaStreamConstraints;
130
77
  runInBackground?: boolean;
131
- mainUserTrackingEnabled?: boolean;
132
- mainUserTrackingWasmBasePath?: string;
133
- mainUserTrackingModelAssetPath?: string;
134
78
  }
135
79
  export type MonitorDogDetectorSessionStatus = "anonymous" | "authenticated";
136
80
  export type MonitorDogDetectorStatus = "idle" | "loading" | "starting" | "running" | "stopped" | "disposed" | "error";
@@ -171,14 +115,27 @@ export interface MonitorDogTokenSet {
171
115
  expiresIn?: number;
172
116
  expiresAt?: string;
173
117
  }
174
- export type SdkModelAssetName = "detector" | "ort-js" | "ort-wasm" | "mediapipe-vision-wasm-js" | "mediapipe-vision-wasm-wasm" | "mediapipe-pose-landmarker";
175
- export interface SdkModelResponse {
118
+ export type SdkModelAssetName = "detector";
119
+ export interface SdkAssetKeyResponse {
176
120
  encrypted_dek: string;
177
- asset_download_url: string;
178
121
  asset: SdkModelAssetName;
179
122
  input_size: number | null;
180
123
  version: string;
181
124
  }
125
+ export interface SdkAssetManifestDetectorEntry {
126
+ file: string;
127
+ version: string;
128
+ encryptedSha256: string;
129
+ }
130
+ export interface SdkAssetManifest {
131
+ environment: string;
132
+ bundleId: string;
133
+ assetVersion: string;
134
+ createdAt: string;
135
+ assets: {
136
+ detector: Record<"320" | "416" | "640", SdkAssetManifestDetectorEntry>;
137
+ };
138
+ }
182
139
  export interface LetterboxResult {
183
140
  data: ImageData;
184
141
  sourceWidth: number;
@@ -319,7 +276,7 @@ export interface UserPreferences {
319
276
  mobileDetectionLockDuration: number;
320
277
  mobileDetectionEnabled: boolean;
321
278
  mobileDetectionMode: LockPolicyValue;
322
- language: MonitorDogLanguage;
279
+ language: "en" | "ko" | "ja";
323
280
  faceDetectionThreshold: number;
324
281
  noPersonDetectionEnabled: boolean;
325
282
  noPersonLockDuration: number;
@@ -327,39 +284,4 @@ export interface UserPreferences {
327
284
  multiPersonDetectionEnabled: boolean;
328
285
  multiPersonLockDuration: number;
329
286
  multiPersonDetectionMode: LockPolicyValue;
330
- headTurningThreshold: number;
331
- webcamBlockageDetectionEnabled: boolean;
332
- webcamBlockageLockDuration: number;
333
- webcamBlockageDetectionMode: LockPolicyValue;
334
287
  }
335
- export type LiveStatus = {
336
- l?: boolean;
337
- k?: string;
338
- ku?: string;
339
- m?: boolean;
340
- d?: DetectionLevel;
341
- e?: Array<MinimalEventLockSetting>;
342
- s?: boolean;
343
- dp?: DlpDetectionPolicy;
344
- dls?: number;
345
- bl?: Array<string>;
346
- require_password_on_resume?: boolean;
347
- no_face_lock_delay_seconds?: number;
348
- use_face_on_resume?: boolean;
349
- };
350
- export type LockLogResponse = {
351
- organization_uuid: string;
352
- lock_target_type: string;
353
- account_uuid: string;
354
- lock_level: string;
355
- device_uuid: string;
356
- uuid: string;
357
- locker_uuid: string;
358
- reason: string;
359
- suspicious_activity_uuid: string;
360
- unlocker_uuid: string;
361
- unlocked_at: string;
362
- created_at: string;
363
- updated_at: string;
364
- is_active: boolean;
365
- };
package/package.json CHANGED
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "@monitordog/detector",
3
- "version": "1.0.2",
3
+ "version": "1.0.3",
4
4
  "type": "module",
5
- "description": "Browser SDK for running the bundled MonitorDog ONNX detector.",
5
+ "description": "Lean browser SDK for MonitorDog local ONNX detection.",
6
6
  "license": "SEE LICENSE IN LICENSE",
7
7
  "main": "./dist/monitordog-detector.umd.cjs",
8
8
  "module": "./dist/monitordog-detector.js",
9
- "types": "./dist/monitordog-detector.d.ts",
9
+ "types": "./dist/index.d.ts",
10
10
  "files": [
11
11
  "dist"
12
12
  ],
@@ -15,7 +15,7 @@
15
15
  },
16
16
  "exports": {
17
17
  ".": {
18
- "types": "./dist/monitordog-detector.d.ts",
18
+ "types": "./dist/index.d.ts",
19
19
  "import": "./dist/monitordog-detector.js",
20
20
  "require": "./dist/monitordog-detector.umd.cjs"
21
21
  }
@@ -23,25 +23,22 @@
23
23
  "sideEffects": false,
24
24
  "scripts": {
25
25
  "dev": "vite",
26
- "build:webcam-frame-analysis-wasm": "powershell -ExecutionPolicy Bypass -File scripts/build-webcam-frame-analysis-wasm.ps1",
27
- "build:ort-webassembly-reduced": "powershell -ExecutionPolicy Bypass -File scripts/build-ort-webassembly-reduced.ps1",
28
- "build:ort-detector-wasm": "powershell -ExecutionPolicy Bypass -File scripts/build-ort-detector-wasm.ps1",
29
- "build:demo": "vite build --config vite.demo.config.ts",
30
- "deploy:demo": "npm run build:demo && npx wrangler pages deploy dist-demo --project-name monitordog --branch main --commit-dirty=true",
31
- "build": "vite build && tsc -p tsconfig.build.json && node scripts/copy-types.cjs",
26
+ "build": "vite build && tsc -p tsconfig.build.json",
32
27
  "preview": "vite preview",
33
- "test": "vitest run"
28
+ "test": "vitest run",
29
+ "package:dev": "node scripts/package-sdk.mjs --environment dev",
30
+ "package:prod": "node scripts/package-sdk.mjs --environment prod",
31
+ "publish:dry-run": "node scripts/publish-sdk.mjs --skip-package --dry-run",
32
+ "publish:public": "node scripts/publish-sdk.mjs"
33
+ },
34
+ "dependencies": {
35
+ "html2canvas": "^1.4.1",
36
+ "onnxruntime-web": "1.24.3"
34
37
  },
35
38
  "devDependencies": {
36
- "@sentry/browser": "^10.53.1",
37
- "binaryen": "^129.0.0",
39
+ "adm-zip": "^0.5.16",
38
40
  "typescript": "~6.0.2",
39
41
  "vite": "^8.1.2",
40
- "vite-plugin-javascript-obfuscator": "^3.1.0",
41
42
  "vitest": "^4.1.9"
42
- },
43
- "dependencies": {
44
- "@mediapipe/tasks-vision": "^0.10.35",
45
- "html2canvas": "^1.4.1"
46
43
  }
47
44
  }
@@ -1,2 +0,0 @@
1
- (function(){let e=[`phone_back`,`phone_front`,`phone_back_cam`,`cup`,`hand`,`face`];function t(e){let t=new DataView(e.buffer,e.byteOffset,e.byteLength),i=t.getUint32(0,!0),a=t.getUint32(4,!0),o=r(e.byteLength,i+a),s=Uint32Array.BYTES_PER_ELEMENT*2,c=n(t,s,i,{classId:5,label:`face`,recordFloatCount:o});s+=i*o*Float32Array.BYTES_PER_ELEMENT;let l=n(t,s,a,{classId:0,label:`phone`,recordFloatCount:o});return{faceDetected:i>0,phoneDetected:a>0,faceCount:i,phoneCount:a,faceDetections:c,phoneDetections:l}}function n(e,t,n,r){let a=[],o=t;for(let t=0;t<n;t+=1){let t=r.recordFloatCount===7,n=t?e.getFloat32(o,!0):r.classId,s=t?o+Float32Array.BYTES_PER_ELEMENT:o;a.push({classId:n,label:t?i(n):r.label,score:e.getFloat32(s,!0),confidence:e.getFloat32(s+4,!0),x:e.getFloat32(s+8,!0),y:e.getFloat32(s+12,!0),width:e.getFloat32(s+16,!0),height:e.getFloat32(s+20,!0)}),o+=r.recordFloatCount*Float32Array.BYTES_PER_ELEMENT}return a}function r(e,t){return t===0||e-Uint32Array.BYTES_PER_ELEMENT*2==t*7*Float32Array.BYTES_PER_ELEMENT?7:6}function i(t){return e[t]??`unknown`}async function a(e){return c({...e,asset:`detector`,inputSize:e.inputSize,errorContext:`model`})}async function o(e){let t=await c({apiBaseUrl:e.apiBaseUrl,accessToken:e.accessToken,asset:`ort-js`,errorContext:`ORT JS runtime`});try{return new TextDecoder().decode(t)}finally{t.fill(0)}}async function s(e){return c({apiBaseUrl:e.apiBaseUrl,accessToken:e.accessToken,asset:`ort-wasm`,errorContext:`ORT WASM runtime`})}async function c(e){x();let t=await crypto.subtle.generateKey({name:`RSA-OAEP`,modulusLength:2048,publicExponent:new Uint8Array([1,0,1]),hash:`SHA-256`},!0,[`decrypt`]),n=m(await f(t.publicKey)),r=await l({apiBaseUrl:e.apiBaseUrl,accessToken:e.accessToken,asset:e.asset,inputSize:e.inputSize,errorContext:e.errorContext},n),i=await u(r.asset_download_url),a=new Uint8Array(await crypto.subtle.decrypt({name:`RSA-OAEP`},t.privateKey,b(h(r.encrypted_dek)))),o=g(a);try{return await d(i,o)}finally{i.fill(0),a.fill(0),o.fill(0)}}async function l(e,t){let n=new URLSearchParams({asset:e.asset,public_key:t});e.inputSize!==void 0&&n.set(`input_size`,String(e.inputSize));let r=await fetch(`${e.apiBaseUrl}/auth/sdk-assets?${n}`,{method:`GET`,headers:{accept:`application/json`,authorization:`Bearer ${e.accessToken}`,"Device-Access-Token":e.accessToken}});if(!r.ok)throw Error(`MonitorDog SDK ${e.errorContext} request failed: ${r.status}`);let i=await r.json();if(!i.encrypted_dek||!i.asset_download_url)throw Error(`MonitorDog SDK ${e.errorContext} response is incomplete.`);return{encrypted_dek:i.encrypted_dek,asset_download_url:i.asset_download_url,asset:i.asset??e.asset,input_size:i.input_size??null,version:i.version??``}}async function u(e){let t=await fetch(e);if(!t.ok)throw Error(`Failed to download MonitorDog model: ${t.status} ${t.statusText}`);return new Uint8Array(await t.arrayBuffer())}async function d(e,t){if(e.byteLength<=12)throw Error(`MonitorDog encrypted model data is too short.`);let n=await crypto.subtle.importKey(`raw`,b(t),{name:`AES-GCM`},!1,[`decrypt`]),r=e.slice(0,12),i=e.slice(12);return new Uint8Array(await crypto.subtle.decrypt({name:`AES-GCM`,iv:b(r)},n,b(i)))}async function f(e){let t=await crypto.subtle.exportKey(`spki`,e);return[`-----BEGIN PUBLIC KEY-----`,...p(new Uint8Array(t)).match(/.{1,64}/g)??[],`-----END PUBLIC KEY-----`].join(`
2
- `)}function p(e){let t=``;for(let n of e)t+=String.fromCharCode(n);return btoa(t)}function m(e){return p(new TextEncoder().encode(e))}function h(e){let t=e.replace(/-----BEGIN [^-]+-----/g,``).replace(/-----END [^-]+-----/g,``).replace(/\s/g,``).replace(/-/g,`+`).replace(/_/g,`/`),n=(4-t.length%4)%4,r=t+`=`.repeat(n),i=atob(r),a=new Uint8Array(i.length);for(let e=0;e<i.length;e+=1)a[e]=i.charCodeAt(e);return a}function g(e){if(y(e.byteLength))return new Uint8Array(e);let t=new TextDecoder().decode(e).trim(),n=_(t.startsWith(`"`)&&t.endsWith(`"`)?t.slice(1,-1):t);if(n&&y(n.byteLength))return n;throw Error(`MonitorDog SDK model DEK must decode to a 128-bit or 256-bit AES key. Received ${e.byteLength} bytes.`)}function _(e){if(/^[0-9a-f]+$/i.test(e)&&e.length%2==0)return v(e);try{return h(e)}catch{return}}function v(e){let t=new Uint8Array(e.length/2);for(let n=0;n<t.length;n+=1)t[n]=Number.parseInt(e.slice(n*2,n*2+2),16);return t}function y(e){return e===16||e===32}function b(e){let t=new ArrayBuffer(e.byteLength);return new Uint8Array(t).set(e),t}function x(){if(!globalThis.crypto?.subtle)throw Error(`MonitorDog SDK model decryption requires Web Crypto API.`)}var S=class{loadOptions;module;loadPromise;wasmBlobUrl;detectorInputPointer=0;detectorInputByteLength=0;detectorDimsPointer=0;detectorDimsByteLength=0;detectorOutputDataPointerPointer=0;detectorOutputByteLengthPointer=0;constructor(e){this.loadOptions=e}async load(e){this.loadPromise||=this.loadModel(e),await this.loadPromise}async run(e){let t=await this.getModule();if(e.input.type!==`float32`)throw Error(`ort-detector PoC only supports float32 input tensors.`);if(!(e.input.data instanceof Float32Array))throw Error(`ort-detector PoC expected Float32Array input data.`);let n=e.input.data,r=t._malloc(n.byteLength),i=t._malloc(e.input.dims.length*8),a=t._malloc(4),o=t._malloc(4),s=t._malloc(4),c=t._malloc(4);try{t.HEAPF32.set(n,r/Float32Array.BYTES_PER_ELEMENT),C(t,i,e.input.dims),T(t,t._md_ort_run_float32_nchw(r,n.length,i,e.input.dims.length,a,o,s,c),`ort-detector inference failed`);let l=t.getValue(a,`*`),u=t.getValue(o,`i32`),d=t.getValue(s,`*`),f=t.getValue(c,`i32`);try{let n=new Float32Array(u);return n.set(t.HEAPF32.subarray(l/Float32Array.BYTES_PER_ELEMENT,l/Float32Array.BYTES_PER_ELEMENT+u)),{output:{type:`float32`,data:n,dims:w(t,d,f)},input:e.metadata}}finally{t._md_ort_free(l),t._md_ort_free(d)}}finally{t.HEAPU8.fill(0,r,r+n.byteLength),t._free(r),t._free(i),t._free(a),t._free(o),t._free(s),t._free(c)}}async runDetector(e){let n=await this.getModule();if(e.input.type!==`float32`)throw Error(`ort-detector only supports float32 input tensors.`);if(!(e.input.data instanceof Float32Array))throw Error(`ort-detector expected Float32Array input data.`);let r=e.input.data,i=this.ensureDetectorBuffers(n,r.byteLength,e.input.dims.length*BigInt64Array.BYTES_PER_ELEMENT);n.HEAPF32.set(r,i.inputPointer/Float32Array.BYTES_PER_ELEMENT),C(n,i.dimsPointer,e.input.dims),T(n,n._md_ort_run_detector_float32_nchw(i.inputPointer,r.length,i.dimsPointer,e.input.dims.length,e.metadata.sourceWidth,e.metadata.sourceHeight,e.metadata.ratio,e.metadata.padX,e.metadata.padY,e.confidenceThreshold,e.faceConfidenceThreshold,e.iouThreshold,e.maxDetections,i.outputDataPointerPointer,i.outputByteLengthPointer),`ort-detector run failed`);let a=n.getValue(i.outputDataPointerPointer,`*`),o=n.getValue(i.outputByteLengthPointer,`i32`);try{return t(n.HEAPU8.subarray(a,a+o))}finally{n._md_ort_free(a)}}dispose(){this.releaseDetectorBuffers(),this.module?._md_ort_dispose(),this.module=void 0,this.loadPromise=void 0,this.revokeWasmBlobUrl()}async loadModel(e){let t=await this.getModule();try{let n=t._malloc(e.byteLength);try{t.HEAPU8.set(e,n),T(t,t._md_ort_load_model(n,e.byteLength),`ort-detector model load failed`)}finally{t.HEAPU8.fill(0,n,n+e.byteLength),t._free(n)}}finally{e.fill(0)}}async getModule(){if(!this.module){let[e,t]=await Promise.all([o(this.loadOptions),s(this.loadOptions)]),n=new Blob([e],{type:`text/javascript`}),r=URL.createObjectURL(n),i=URL.createObjectURL(new Blob([E(t)],{type:`application/wasm`})),a;try{a=(await import(r)).default}finally{t.fill(0),URL.revokeObjectURL(r)}this.revokeWasmBlobUrl(),this.wasmBlobUrl=i,this.module=await a({locateFile:e=>e.endsWith(`.wasm`)?i:e});let c=this.module._md_ort_init();T(this.module,c,`ort-detector initialization failed`)}return this.module}ensureDetectorBuffers(e,t,n){return this.detectorInputByteLength<t&&(this.detectorInputPointer&&(e.HEAPU8.fill(0,this.detectorInputPointer,this.detectorInputPointer+this.detectorInputByteLength),e._free(this.detectorInputPointer)),this.detectorInputPointer=e._malloc(t),this.detectorInputByteLength=t),this.detectorDimsByteLength<n&&(this.detectorDimsPointer&&e._free(this.detectorDimsPointer),this.detectorDimsPointer=e._malloc(n),this.detectorDimsByteLength=n),this.detectorOutputDataPointerPointer||=e._malloc(4),this.detectorOutputByteLengthPointer||=e._malloc(4),{inputPointer:this.detectorInputPointer,dimsPointer:this.detectorDimsPointer,outputDataPointerPointer:this.detectorOutputDataPointerPointer,outputByteLengthPointer:this.detectorOutputByteLengthPointer}}releaseDetectorBuffers(){let e=this.module;if(!e){this.resetDetectorBuffers();return}this.detectorInputPointer&&(e.HEAPU8.fill(0,this.detectorInputPointer,this.detectorInputPointer+this.detectorInputByteLength),e._free(this.detectorInputPointer)),this.detectorDimsPointer&&e._free(this.detectorDimsPointer),this.detectorOutputDataPointerPointer&&e._free(this.detectorOutputDataPointerPointer),this.detectorOutputByteLengthPointer&&e._free(this.detectorOutputByteLengthPointer),this.resetDetectorBuffers()}resetDetectorBuffers(){this.detectorInputPointer=0,this.detectorInputByteLength=0,this.detectorDimsPointer=0,this.detectorDimsByteLength=0,this.detectorOutputDataPointerPointer=0,this.detectorOutputByteLengthPointer=0}revokeWasmBlobUrl(){this.wasmBlobUrl&&=(URL.revokeObjectURL(this.wasmBlobUrl),void 0)}};function C(e,t,n){let r=t/BigInt64Array.BYTES_PER_ELEMENT;for(let t=0;t<n.length;t+=1)e.HEAP64[r+t]=BigInt(n[t])}function w(e,t,n){let r=t/BigInt64Array.BYTES_PER_ELEMENT,i=[];for(let t=0;t<n;t+=1)i.push(Number(e.HEAP64[r+t]));return i}function T(e,t,n){if(t===0)return;let r=e._md_ort_get_last_error(),i=r?e.UTF8ToString(r):``;throw Error(i||n)}function E(e){let t=new ArrayBuffer(e.byteLength);return new Uint8Array(t).set(e),t}let D=self,O,k=Promise.resolve();D.addEventListener(`message`,e=>{A(e.data)});async function A(e){try{if(e.type===`load`){O?.dispose(),O=new S(e.model),await O.load(await a(e.model)),z({id:e.id,ok:!0});return}let t=await j(e);z({id:e.id,ok:!0,result:t})}catch(t){z({id:e.id,ok:!1,error:t instanceof Error?t.message:String(t)})}}function j(e){let t=k.then(()=>M(e));return k=t.then(()=>void 0,()=>void 0),t}async function M(e){return N(e)}async function N(e){if(!O)throw Error(`ort-detector runtime is not loaded.`);let t=e.debug?performance.now():0,n=e.debug?performance.now():0,{input:r,metadata:i}=e.source.kind===`bitmap`?P(e.source,e.inputSize,e.inputType):F(e.source,e.inputSize,e.inputType),a=e.debug?performance.now():0,o=await O.runDetector({input:r,metadata:i,confidenceThreshold:e.confidenceThreshold,faceConfidenceThreshold:e.faceConfidenceThreshold,iouThreshold:e.iouThreshold,maxDetections:e.maxDetections});if(e.debug){let r=performance.now();console.info(`[MonitorDog] worker inference`,{source:e.source.kind,inputSize:e.inputSize,preprocessMs:B(a-n),ortMs:B(r-a),totalMs:B(r-t)})}return o}function P(e,t,n){try{if(typeof OffscreenCanvas>`u`)throw Error(`OffscreenCanvas is not available.`);let r=I(e.sourceWidth,e.sourceHeight,t),i=new OffscreenCanvas(t,t).getContext(`2d`);if(!i)throw Error(`2D canvas context is not available.`);return i.fillStyle=`rgb(114, 114, 114)`,i.fillRect(0,0,t,t),i.drawImage(e.bitmap,r.padX,r.padY,Math.round(e.sourceWidth*r.ratio),Math.round(e.sourceHeight*r.ratio)),{input:R(i.getImageData(0,0,t,t).data,n,t),metadata:r}}finally{e.bitmap.close()}}function F(e,t,n){let r=I(e.sourceWidth,e.sourceHeight,t);return{input:L(e.data,e.sourceWidth,e.sourceHeight,r,t,n),metadata:r}}function I(e,t,n){let r=Math.min(n/e,n/t);return{sourceWidth:e,sourceHeight:t,ratio:r,padX:Math.floor((n-Math.round(e*r))/2),padY:Math.floor((n-Math.round(t*r))/2)}}function L(e,t,n,r,i,a){let o=i*i,s=[1,3,i,i],c=a===`uint8`?new Uint8Array(o*3):new Float32Array(o*3);for(let s=0;s<i;s+=1)for(let l=0;l<i;l+=1){let u=s*i+l,d=Math.floor((l-r.padX)/r.ratio),f=Math.floor((s-r.padY)/r.ratio),p=d>=0&&f>=0&&d<t&&f<n,m=(f*t+d)*4,h=p?e[m]:114,g=p?e[m+1]:114,_=p?e[m+2]:114;a===`uint8`?(c[u]=h,c[u+o]=g,c[u+o*2]=_):(c[u]=h/255,c[u+o]=g/255,c[u+o*2]=_/255)}return{type:a,data:c,dims:s}}function R(e,t,n){let r=n*n,i=[1,3,n,n];if(t===`uint8`){let t=new Uint8Array(r*3);for(let n=0;n<r;n+=1){let i=n*4;t[n]=e[i],t[n+r]=e[i+1],t[n+r*2]=e[i+2]}return{type:`uint8`,data:t,dims:i}}let a=new Float32Array(r*3);for(let t=0;t<r;t+=1){let n=t*4;a[t]=e[n]/255,a[t+r]=e[n+1]/255,a[t+r*2]=e[n+2]/255}return{type:`float32`,data:a,dims:i}}function z(e,t){D.postMessage(e,t??[])}function B(e){return Math.round(e*10)/10}})();
@@ -1 +0,0 @@
1
- export declare const WEBCAM_FRAME_ANALYSIS_WASM_BYTES: Uint8Array<ArrayBuffer>;
@@ -1,32 +0,0 @@
1
- import { type WebcamFrameAnalysis } from "./webcam-frame-analysis";
2
- export interface WebcamBlockageAnalysis {
3
- blocked: boolean;
4
- suspected: boolean;
5
- likelyCovered: boolean;
6
- changedCoverage: number;
7
- }
8
- export declare class WebcamBlockageDetector {
9
- private previousFrameData?;
10
- private baselineFrameData?;
11
- private baselineEdgeDensity?;
12
- private baselineEdgeDensityUpdatedAt?;
13
- private baselineColorVariance?;
14
- private baselineLuminanceHistogram?;
15
- private smoothedEdgeDensity?;
16
- private smoothedEdgeDensityUpdatedAt?;
17
- private blocked;
18
- private blockedStartedAt?;
19
- private baselineRefreshPending;
20
- private clearSampleCount;
21
- private startedAt;
22
- private calibrated;
23
- private calibrationNoiseSamples;
24
- private adaptivePixelChangeThreshold;
25
- analyze(frame: WebcamFrameAnalysis): WebcamBlockageAnalysis;
26
- reset(): void;
27
- needsBaselineRefresh(): boolean;
28
- refreshBaseline(frame: WebcamFrameAnalysis): void;
29
- private finalizeCalibration;
30
- private smoothEdgeDensity;
31
- private updateBaselineEdgeDensity;
32
- }
@@ -1,47 +0,0 @@
1
- export declare const WEBCAM_ANALYSIS_LIGHTING_NONE = 0;
2
- export declare const WEBCAM_ANALYSIS_LIGHTING_TOO_DARK = 1;
3
- export declare const WEBCAM_ANALYSIS_LIGHTING_TOO_BRIGHT = 2;
4
- export interface WebcamFrameWasmAnalysis {
5
- edgeDensity: number;
6
- coverage: number;
7
- colorVariance: number;
8
- averageLuminance: number;
9
- luminanceSpread: number;
10
- luminanceHistogram: Uint16Array;
11
- normalizedLuminanceHistogram: Float32Array;
12
- darkRatio: number;
13
- brightRatio: number;
14
- blackout: boolean;
15
- lightingIssueCode: number;
16
- }
17
- export interface WebcamBlockageWasmInput {
18
- image: ImageData;
19
- previousFrameData?: Uint8ClampedArray;
20
- baselineFrameData?: Uint8ClampedArray;
21
- pixelChangeThreshold: number;
22
- edgeDensity: number;
23
- baselineEdgeDensity?: number;
24
- colorVariance: number;
25
- baselineColorVariance?: number;
26
- luminanceEntropy: number;
27
- luminanceSpread: number;
28
- normalizedLuminanceHistogram: Float32Array;
29
- baselineLuminanceHistogram?: Float32Array;
30
- blackout: boolean;
31
- currentlyBlocked: boolean;
32
- }
33
- export interface WebcamBlockageWasmAnalysis {
34
- changedCoverage: number;
35
- previousChangedCoverage: number;
36
- frameNoiseAverage: number;
37
- hasCoveredArea: boolean;
38
- detected: boolean;
39
- likelyCovered: boolean;
40
- }
41
- export declare class WebcamFrameAnalysisWasm {
42
- private readonly exports;
43
- constructor();
44
- analyze(image: ImageData): WebcamFrameWasmAnalysis;
45
- analyzeBlockage(input: WebcamBlockageWasmInput): WebcamBlockageWasmAnalysis;
46
- }
47
- export declare const webcamFrameAnalysisWasm: WebcamFrameAnalysisWasm;
@@ -1,34 +0,0 @@
1
- export interface WebcamFrameAnalysis {
2
- image: ImageData;
3
- pixelCount: number;
4
- edgeDensity: number;
5
- coverage: number;
6
- colorVariance: number;
7
- averageLuminance: number;
8
- luminanceSpread: number;
9
- luminanceEntropy: number;
10
- luminanceHistogram: Uint16Array;
11
- normalizedLuminanceHistogram: Float32Array;
12
- darkRatio: number;
13
- brightRatio: number;
14
- blackout: boolean;
15
- lightingIssueCode: number;
16
- }
17
- export declare const WEBCAM_ANALYSIS_SAMPLE_WIDTH = 40;
18
- export declare const WEBCAM_ANALYSIS_SAMPLE_HEIGHT = 30;
19
- export declare const LUMINANCE_HISTOGRAM_BINS = 16;
20
- export declare class WebcamFrameAnalyzer {
21
- private readonly context;
22
- constructor();
23
- analyze(video: HTMLVideoElement): WebcamFrameAnalysis;
24
- }
25
- export declare function analyzeWebcamFrame(image: ImageData): WebcamFrameAnalysis;
26
- export declare function captureWebcamFrame(context: CanvasRenderingContext2D, video: HTMLVideoElement): ImageData;
27
- export declare function createWebcamAnalysisCanvas(errorMessage: string): {
28
- canvas: HTMLCanvasElement;
29
- context: CanvasRenderingContext2D;
30
- };
31
- export declare function getPixelLuminance(data: Uint8ClampedArray, index: number): number;
32
- export declare function normalizeHistogram(histogram: Uint16Array, pixelCount: number): Float32Array;
33
- export declare function getHistogramDistance(current: Float32Array, baseline: Float32Array): number;
34
- export declare function isWebcamBlackoutFrame(frame: WebcamFrameAnalysis): boolean;
@@ -1,21 +0,0 @@
1
- import { type WebcamFrameAnalysis } from "./webcam-frame-analysis";
2
- export type WebcamLightingIssue = "tooDark" | "tooBright";
3
- export interface WebcamLightingAnalysis {
4
- issue?: WebcamLightingIssue;
5
- active: boolean;
6
- averageLuminance: number;
7
- luminanceSpread: number;
8
- luminanceEntropy: number;
9
- darkRatio: number;
10
- brightRatio: number;
11
- }
12
- export declare class WebcamLightingDetector {
13
- private startedAt;
14
- private issueStartedAt?;
15
- private clearStartedAt?;
16
- private pendingIssue?;
17
- private activeIssue?;
18
- analyze(frame: WebcamFrameAnalysis): WebcamLightingAnalysis;
19
- reset(): void;
20
- private detectIssue;
21
- }
@@ -1,6 +0,0 @@
1
- import type { MonitorDogLanguage, MonitorDogOverlayMessages } from "./types";
2
- export declare const DEFAULT_MONITORDOG_LANGUAGE: MonitorDogLanguage;
3
- export declare const MONITORDOG_OVERLAY_MESSAGES: Record<MonitorDogLanguage, MonitorDogOverlayMessages>;
4
- export declare function resolveMonitorDogLanguage(language: string | undefined): MonitorDogLanguage;
5
- export declare function getMonitorDogOverlayMessages(language: string | undefined): MonitorDogOverlayMessages;
6
- export declare function getBrowserMonitorDogLanguage(): MonitorDogLanguage;
@@ -1,41 +0,0 @@
1
- import type { MonitorDogDetectorOptions, MonitorDogDetectorState, MonitorDogLoginRequest, MonitorDogSessionToken, UserPreferences } from "./types";
2
- export declare class MonitorDogDetector {
3
- #private;
4
- static init(options: MonitorDogDetectorOptions): Promise<MonitorDogDetector>;
5
- constructor(options: MonitorDogDetectorOptions);
6
- load(): Promise<void>;
7
- login(request: MonitorDogLoginRequest): Promise<MonitorDogSessionToken>;
8
- private completeAuthenticatedLogin;
9
- logout(): Promise<void>;
10
- start(): Promise<void>;
11
- stop(): void;
12
- setRunInBackground(runInBackground: boolean): void;
13
- getUserPreferences(): Readonly<UserPreferences>;
14
- isMainUserTrackingEnabled(): boolean;
15
- setMainUserTrackingEnabled(enabled: boolean): void;
16
- getState(): MonitorDogDetectorState;
17
- dispose(): void;
18
- private resetLoggedOutState;
19
- private rollbackAuthenticatedLogin;
20
- private startRuntime;
21
- private clearSessionState;
22
- private stopLocalRuntime;
23
- private assertUsable;
24
- private assertAuthenticated;
25
- private lifecycleError;
26
- private transitionToError;
27
- private updateState;
28
- private notifyStatusChange;
29
- private createSdkError;
30
- private isDetectorRunning;
31
- private hasRuntimeToStop;
32
- private getStartErrorCode;
33
- private getStartErrorMessage;
34
- private isCameraPermissionError;
35
- private isCameraReadError;
36
- }
37
- export declare function configureMonitorDogDetector(options: MonitorDogDetectorOptions): MonitorDogDetector;
38
- export declare function createMonitorDogDetector(options: MonitorDogDetectorOptions): Promise<MonitorDogDetector>;
39
- export declare function getDetector(): MonitorDogDetector;
40
- export { MonitorDogSdkError, isMonitorDogSdkError } from "./sdk-error";
41
- export type { AccountResponse, LockPolicyResponse, MonitorDogDetection, MonitorDogDetectionResult, MonitorDogDetectorCameraStatus, MonitorDogDetectorOptions, MonitorDogDetectorSessionStatus, MonitorDogDetectorState, MonitorDogDetectorStatus, MonitorDogLoginRequest, MonitorDogSdkErrorCode, MonitorDogSdkTokenResponse, MonitorDogSessionToken, MonitorDogSessionTokenProvider, MonitorDogVideoDetectionResult, UserPreferences, } from "./types";
@@ -1,16 +0,0 @@
1
- export type MediaPipeWasmFileset = {
2
- wasmLoaderPath: string;
3
- wasmBinaryPath: string;
4
- assetLoaderPath?: string;
5
- assetBinaryPath?: string;
6
- };
7
- export type MediaPipeAssetBundle = {
8
- wasmFileset: MediaPipeWasmFileset;
9
- poseModelAssetBuffer: Uint8Array;
10
- dispose: () => void;
11
- };
12
- export type MediaPipeAssetLoadOptions = {
13
- apiBaseUrl: string;
14
- accessToken: string;
15
- };
16
- export declare function loadMediaPipeAssetBundle(options: MediaPipeAssetLoadOptions): Promise<MediaPipeAssetBundle>;