@keverdjs/fraud-sdk 1.1.0 → 2.0.0
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/README.md +0 -2
- package/dist/core/sdk.d.ts +46 -1
- package/dist/fintechrisk.js +1 -1
- package/dist/types.d.ts +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -41,7 +41,6 @@ import { Keverd } from '@keverdjs/fraud-sdk';
|
|
|
41
41
|
// Initialize with configuration
|
|
42
42
|
Keverd.init({
|
|
43
43
|
apiKey: 'your-api-key',
|
|
44
|
-
endpoint: 'https://api.keverd.com', // Optional
|
|
45
44
|
debug: true, // Optional: enable debug logging
|
|
46
45
|
});
|
|
47
46
|
|
|
@@ -66,7 +65,6 @@ Keverd.init('your-api-key');
|
|
|
66
65
|
// With options
|
|
67
66
|
Keverd.init({
|
|
68
67
|
apiKey: 'your-api-key',
|
|
69
|
-
endpoint: 'https://api.keverd.com',
|
|
70
68
|
userId: 'optional-user-id',
|
|
71
69
|
debug: false
|
|
72
70
|
});
|
package/dist/core/sdk.d.ts
CHANGED
|
@@ -16,11 +16,19 @@ export declare class KeverdSDK {
|
|
|
16
16
|
private pageInteractionCollector;
|
|
17
17
|
private isInitialized;
|
|
18
18
|
private sessionId;
|
|
19
|
+
private ghostInterval;
|
|
20
|
+
private ghostStartTime;
|
|
21
|
+
private ghostSignalCount;
|
|
22
|
+
private readonly MIN_GHOST_SIGNALS;
|
|
23
|
+
private readonly MAX_GHOST_COLLECTION_TIME;
|
|
19
24
|
constructor();
|
|
20
25
|
/**
|
|
21
26
|
* Initialize the SDK with configuration
|
|
22
27
|
*/
|
|
23
28
|
init(config: SDKConfig | string): void;
|
|
29
|
+
private startGhostSignalCollection;
|
|
30
|
+
private stopGhostSignalCollection;
|
|
31
|
+
private sendGhostSignals;
|
|
24
32
|
/**
|
|
25
33
|
* Get visitor data (fingerprint and risk assessment)
|
|
26
34
|
* This is the main method for getting risk scores
|
|
@@ -63,10 +71,47 @@ export declare class KeverdSDK {
|
|
|
63
71
|
* Generate a unique session ID
|
|
64
72
|
*/
|
|
65
73
|
private generateSessionId;
|
|
74
|
+
/**
|
|
75
|
+
* Detect browser name from user agent
|
|
76
|
+
*/
|
|
77
|
+
private _detectBrowser;
|
|
78
|
+
/**
|
|
79
|
+
* Detect OS from user agent
|
|
80
|
+
*/
|
|
81
|
+
private _detectOS;
|
|
82
|
+
/**
|
|
83
|
+
* Start a new session (called automatically on init, but can be called manually)
|
|
84
|
+
*/
|
|
85
|
+
startSession(userId?: string, deviceHash?: string, metadata?: Record<string, unknown>): Promise<void>;
|
|
86
|
+
/**
|
|
87
|
+
* End the current session
|
|
88
|
+
*/
|
|
89
|
+
endSession(): Promise<void>;
|
|
90
|
+
/**
|
|
91
|
+
* Pause the current session (e.g., when app goes to background)
|
|
92
|
+
*/
|
|
93
|
+
pauseSession(): Promise<void>;
|
|
94
|
+
/**
|
|
95
|
+
* Resume a paused session (e.g., when app comes to foreground)
|
|
96
|
+
*/
|
|
97
|
+
resumeSession(): Promise<void>;
|
|
98
|
+
/**
|
|
99
|
+
* Get current session status
|
|
100
|
+
*/
|
|
101
|
+
getSessionStatus(): Promise<{
|
|
102
|
+
session_id: string;
|
|
103
|
+
status: string;
|
|
104
|
+
is_active: boolean;
|
|
105
|
+
is_paused: boolean;
|
|
106
|
+
event_count: number;
|
|
107
|
+
started_at: string;
|
|
108
|
+
last_activity_at: string;
|
|
109
|
+
duration_seconds: number | null;
|
|
110
|
+
} | null>;
|
|
66
111
|
/**
|
|
67
112
|
* Destroy the SDK instance
|
|
68
113
|
*/
|
|
69
|
-
destroy(): void
|
|
114
|
+
destroy(): Promise<void>;
|
|
70
115
|
/**
|
|
71
116
|
* Check if SDK is initialized and ready to use
|
|
72
117
|
*/
|
package/dist/fintechrisk.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
!function(t,i){"object"==typeof exports&&"object"==typeof module?module.exports=i():"function"==typeof define&&define.amd?define([],i):"object"==typeof exports?exports.FintechRisk=i():t.FintechRisk=i()}(this,()=>(()=>{"use strict";var t={d:(i,e)=>{for(var n in e)t.o(e,n)&&!t.o(i,n)&&Object.defineProperty(i,n,{enumerable:!0,get:e[n]})},o:(t,i)=>Object.prototype.hasOwnProperty.call(t,i),r:t=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"t",{value:!0})}},i={};t.r(i),t.d(i,{BehavioralCollector:()=>a,DeviceCollector:()=>e,FingerprintJSCollector:()=>P,Keverd:()=>$,KeverdSDK:()=>I,KeystrokeMonitor:()=>s,KinematicEngine:()=>n});class e{constructor(){this.cachedDeviceInfo=null}collect(){if(this.cachedDeviceInfo)return this.cachedDeviceInfo;const t=this.generateDeviceFingerprint(),i=this.generateDeviceId(t);return this.cachedDeviceInfo={deviceId:i,fingerprint:t,manufacturer:this.getManufacturer(),model:this.getModel(),brand:this.getBrand(),device:this.getDevice(),product:this.getProduct(),hardware:this.getHardware(),sdkVersion:"1.0.0",osVersion:this.getOSVersion(),screenWidth:String(screen.width),screenHeight:String(screen.height),screenDensity:this.getScreenDensity(),locale:navigator.language||navigator.languages?.[0]||"en",timezone:Intl.DateTimeFormat().resolvedOptions().timeZone},this.cachedDeviceInfo}generateDeviceFingerprint(){const t=[],i=this.getCanvasFingerprint();i&&t.push(i);const e=this.getWebGLFingerprint();if(e&&t.push(e),t.push(navigator.userAgent),t.push(navigator.language||navigator.languages?.[0]||""),t.push(`${screen.width}x${screen.height}x${screen.colorDepth}`),t.push(String((new Date).getTimezoneOffset())),t.push(navigator.platform),t.push(String(navigator.hardwareConcurrency||0)),"deviceMemory"in navigator&&t.push(String(navigator.deviceMemory)),"maxTouchPoints"in navigator&&t.push(String(navigator.maxTouchPoints)),navigator.plugins&&navigator.plugins.length>0){const i=Array.from(navigator.plugins).slice(0,3).map(t=>t.name).join(",");t.push(i)}const n=t.join("|");return this.hashString(n)}getCanvasFingerprint(){try{const t=document.createElement("canvas"),i=t.getContext("2d");return i?(t.width=200,t.height=50,i.textBaseline="top",i.font="14px Arial",i.fillStyle="#f60",i.fillRect(125,1,62,20),i.fillStyle="#069",i.fillText("KeverdFingerprint",2,15),i.fillStyle="rgba(102, 204, 0, 0.7)",i.fillText("KeverdFingerprint",4,17),this.hashString(t.toDataURL())):""}catch(t){return""}}getWebGLFingerprint(){try{const t=document.createElement("canvas"),i=t.getContext("webgl")||t.getContext("experimental-webgl");if(!i)return"";const e=i.getExtension("WEBGL_debug_renderer_info");if(e){const t=i.getParameter(e.UNMASKED_VENDOR_WEBGL),n=i.getParameter(e.UNMASKED_RENDERER_WEBGL);return this.hashString(`${t}|${n}`)}const n=i.getParameter(i.VERSION),s=i.getParameter(i.VENDOR);return this.hashString(`${n}|${s}`)}catch(t){return""}}generateDeviceId(t){return t.substring(0,32)}getManufacturer(){const t=navigator.userAgent.toLowerCase();if(t.includes("iphone")||t.includes("ipad"))return"Apple";if(t.includes("android")){const i=t.match(/(?:^|\s)([a-z]+)(?:\s|$)/);return i?i[1].charAt(0).toUpperCase()+i[1].slice(1):void 0}}getModel(){const t=navigator.userAgent.match(/(iPhone|iPad|Android)[\s\/]+([\w]+)/i);return t?t[2]:void 0}getBrand(){return this.getManufacturer()}getDevice(){const t=navigator.userAgent.toLowerCase();return t.includes("mobile")?"mobile":t.includes("tablet")?"tablet":"desktop"}getProduct(){const t=navigator.userAgent.match(/(iPhone|iPad|Android|Windows|Mac|Linux)/i);return t?t[1]:void 0}getHardware(){const t=navigator.userAgent.match(/\(([^)]+)\)/);return t?t[1]:void 0}getOSVersion(){const t=navigator.userAgent,i=[/OS\s+([\d_]+)/i,/Android\s+([\d.]+)/i,/Windows\s+([\d.]+)/i,/Mac\s+OS\s+X\s+([\d_]+)/i,/Linux/i];for(const e of i){const i=t.match(e);if(i)return i[1]?.replace(/_/g,".")||i[0]}}getScreenDensity(){if(window.devicePixelRatio)return String(window.devicePixelRatio)}hashString(t){return this.sha256LikeHash(t)}sha256LikeHash(t){const i=[];let e=5381;for(let i=0;i<t.length;i++)e=(e<<5)+e+t.charCodeAt(i),e&=4294967295;i.push(e);let n=0;for(let i=t.length-1;i>=0;i--)n=(n<<7)-n+t.charCodeAt(i),n&=4294967295;i.push(n);let s=0;for(let i=0;i<t.length;i++)s^=t.charCodeAt(i)<<i%4*8,s&=4294967295;i.push(s);let r=0;for(let i=0;i<t.length;i++)r=31*r+t.charCodeAt(i)&4294967295;i.push(r);let o=0;for(let i=0;i<t.length;i++){o=o+(4294967295&(t.charCodeAt(i)<<i%16|t.charCodeAt(i)>>>32-i%16))&4294967295}i.push(o);let a=2166136261;for(let i=0;i<t.length;i++)a=16777619*(a^t.charCodeAt(i)),a&=4294967295;i.push(a);let h=0;for(let i=0;i<t.length;i++)h=h+t.charCodeAt(i)*(i+1)&4294967295;i.push(h);let c=0;for(let i=0;i<t.length;i+=2){c=(c<<3)-c+(t.charCodeAt(i)+256*(t.charCodeAt(i+1)||0)),c&=4294967295}i.push(c);return i.map(t=>Math.abs(t).toString(16).padStart(8,"0")).join("").substring(0,64).padEnd(64,"0")}clearCache(){this.cachedDeviceInfo=null}}class n{constructor(t={}){this.featureVectors=[],this.pointerQueue=[],this.lastVelocity=0,this.lastAcceleration=0,this.lastAngle=0,this.lastPoint=null,this.secondLastPoint=null,this.rafId=null,this.maxSwipeVelocity=0,this.isActive=!1,this.clickCount=0,this.rightClickCount=0,this.doubleClickCount=0,this.totalMouseDistance=0,this.lastClickTime=0,this.scrollDistance=0,this.lastScrollTop=0,this.touchEventCount=0,this.mouseMoveHandler=t=>this.enqueuePoint(t,"move"),this.mouseDownHandler=t=>{this.enqueuePoint(t,"down"),this.handleClick(t)},this.mouseUpHandler=t=>this.enqueuePoint(t,"up"),this.contextMenuHandler=t=>this.handleRightClick(t),this.scrollHandler=()=>this.handleScroll(),this.touchStartHandler=()=>this.handleTouch(),this.touchMoveHandler=()=>this.handleTouch(),this.touchEndHandler=()=>this.handleTouch(),this.onEvent=t.onEvent,this.maskValue=t.maskValue??-1}start(){this.isActive||"undefined"==typeof document||(document.addEventListener("mousemove",this.mouseMoveHandler,{passive:!0}),document.addEventListener("mousedown",this.mouseDownHandler,{passive:!0}),document.addEventListener("mouseup",this.mouseUpHandler,{passive:!0}),document.addEventListener("contextmenu",this.contextMenuHandler,{passive:!0}),window.addEventListener("scroll",this.scrollHandler,{passive:!0}),document.addEventListener("touchstart",this.touchStartHandler,{passive:!0}),document.addEventListener("touchmove",this.touchMoveHandler,{passive:!0}),document.addEventListener("touchend",this.touchEndHandler,{passive:!0}),this.lastScrollTop=window.pageYOffset||document.documentElement.scrollTop,this.isActive=!0)}stop(){this.isActive&&"undefined"!=typeof document&&(document.removeEventListener("mousemove",this.mouseMoveHandler),document.removeEventListener("mousedown",this.mouseDownHandler),document.removeEventListener("mouseup",this.mouseUpHandler),document.removeEventListener("contextmenu",this.contextMenuHandler),window.removeEventListener("scroll",this.scrollHandler),document.removeEventListener("touchstart",this.touchStartHandler),document.removeEventListener("touchmove",this.touchMoveHandler),document.removeEventListener("touchend",this.touchEndHandler),null!==this.rafId&&(cancelAnimationFrame(this.rafId),this.rafId=null),this.isActive=!1)}getVectors(){return this.featureVectors}getSuspiciousSwipeVelocity(){return this.maxSwipeVelocity}getMouseSignals(){const t=this.featureVectors.length>0?this.featureVectors.reduce((t,i)=>t+i.velocity,0)/this.featureVectors.length:0,i=window.pageYOffset||document.documentElement.scrollTop,e=Math.abs(i-this.lastScrollTop),n=i>this.lastScrollTop?"down":"up";return{totalDistance:this.totalMouseDistance,averageVelocity:t,clickCount:this.clickCount,rightClickCount:this.rightClickCount,doubleClickCount:this.doubleClickCount,scrollDistance:this.scrollDistance+e,scrollDirection:n,touchEvents:this.touchEventCount}}reset(){this.featureVectors=[],this.pointerQueue=[],this.lastVelocity=0,this.lastAcceleration=0,this.lastAngle=0,this.lastPoint=null,this.secondLastPoint=null,this.maxSwipeVelocity=0,this.clickCount=0,this.rightClickCount=0,this.doubleClickCount=0,this.totalMouseDistance=0,this.lastClickTime=0,this.scrollDistance=0,this.lastScrollTop=0,this.touchEventCount=0}enqueuePoint(t,i){const e={x:t.clientX,y:t.clientY,timestamp:performance.now(),type:i};this.pointerQueue.push(e),this.pointerQueue.length>200&&this.pointerQueue.shift(),this.onEvent&&this.onEvent("move"===i?"mousemove":"down"===i?"mousedown":"mouseup"),this.scheduleProcess()}scheduleProcess(){null===this.rafId&&(this.rafId=requestAnimationFrame(()=>{this.rafId=null,this.processQueue(),this.pointerQueue.length>0&&this.scheduleProcess()}))}processQueue(){for(;this.pointerQueue.length>0;){const t=this.pointerQueue.shift();this.computeFeatures(t),this.secondLastPoint=this.lastPoint,this.lastPoint=t}}computeFeatures(t){if(!this.lastPoint)return this.lastPoint=t,void(this.lastAngle=0);const i=t.timestamp-this.lastPoint.timestamp;if(i<=0)return;const e=t.x-this.lastPoint.x,n=t.y-this.lastPoint.y,s=Math.sqrt(e*e+n*n);this.totalMouseDistance+=s;const r=s/i,o=(r-this.lastVelocity)/i,a=(o-this.lastAcceleration)/i,h=Math.atan2(n,e),c=this.normalizeAngle(h-this.lastAngle)/i,l=this.calculateCurvature(t);this.featureVectors.push({timestamp:t.timestamp,velocity:r,acceleration:o,jerk:a,curvature:l,angularVelocity:c}),this.maxSwipeVelocity=Math.max(this.maxSwipeVelocity,r),r>2.5&&this.featureVectors.push({timestamp:t.timestamp,velocity:r,acceleration:o,jerk:a,curvature:l,angularVelocity:1.2*c}),this.featureVectors.length>200&&this.featureVectors.splice(0,this.featureVectors.length-200),this.lastVelocity=r,this.lastAcceleration=o,this.lastAngle=h}calculateCurvature(t){if(!this.lastPoint||!this.secondLastPoint)return 0;const i=this.secondLastPoint,e=this.lastPoint,n=t,s=Math.hypot(n.x-i.x,n.y-i.y),r=Math.hypot(e.x-i.x,e.y-i.y)+Math.hypot(n.x-e.x,n.y-e.y);return 0===s?0:(r-s)/s}normalizeAngle(t){for(;t>Math.PI;)t-=2*Math.PI;for(;t<-Math.PI;)t+=2*Math.PI;return t}handleClick(t){const i=performance.now();i-this.lastClickTime<500?this.doubleClickCount++:this.clickCount++,this.lastClickTime=i}handleRightClick(t){this.rightClickCount++}handleScroll(){const t=window.pageYOffset||document.documentElement.scrollTop,i=Math.abs(t-this.lastScrollTop);this.scrollDistance+=i,this.lastScrollTop=t}handleTouch(){this.touchEventCount++}}class s{constructor(t={}){this.keyDownTimes=new Map,this.lastKeyUpTime=null,this.lastKeyDownTime=null,this.featureVectors=[],this.dwellTimes=[],this.flightTimes=[],this.digraphLatencies=[],this.isActive=!1,this.keydownCount=0,this.keyupCount=0,this.specialKeyCount=0,this.lastKeystrokeTime=null,this.pauseCount=0,this.PAUSE_THRESHOLD=2e3,this.keystrokeTimestamps=[],this.keyDownHandler=t=>this.handleKeyDown(t),this.keyUpHandler=t=>this.handleKeyUp(t),this.onEvent=t.onEvent}start(){this.isActive||"undefined"==typeof document||(document.addEventListener("keydown",this.keyDownHandler,{passive:!0,capture:!0}),document.addEventListener("keyup",this.keyUpHandler,{passive:!0,capture:!0}),this.isActive=!0)}stop(){this.isActive&&"undefined"!=typeof document&&(document.removeEventListener("keydown",this.keyDownHandler,!0),document.removeEventListener("keyup",this.keyUpHandler,!0),this.isActive=!1)}getVectors(){return this.featureVectors}getDwellTimes(t=50){return this.dwellTimes.slice(-t)}getFlightTimes(t=50){return this.flightTimes.slice(-t)}getKeyboardSignals(){let t=0;if(this.keystrokeTimestamps.length>1){const i=(this.keystrokeTimestamps[this.keystrokeTimestamps.length-1]-this.keystrokeTimestamps[0])/6e4;i>0&&(t=this.keystrokeTimestamps.length/i)}const i=this.keydownCount,e=i>0?this.getBackspaceCount()/i:0;return{keydownCount:this.keydownCount,keyupCount:this.keyupCount,specialKeyCount:this.specialKeyCount,typingSpeed:t,pauseCount:this.pauseCount,backspaceRatio:e}}getBackspaceCount(){return 0}reset(){this.keyDownTimes.clear(),this.lastKeyUpTime=null,this.lastKeyDownTime=null,this.featureVectors=[],this.dwellTimes=[],this.flightTimes=[],this.digraphLatencies=[],this.keydownCount=0,this.keyupCount=0,this.specialKeyCount=0,this.lastKeystrokeTime=null,this.pauseCount=0,this.keystrokeTimestamps=[]}handleKeyDown(t){if(!this.isTargetField(t))return;const i=performance.now();if(this.keydownCount++,this.keystrokeTimestamps.push(i),(t.ctrlKey||t.altKey||t.shiftKey||t.metaKey)&&this.specialKeyCount++,null!==this.lastKeystrokeTime&&i-this.lastKeystrokeTime>this.PAUSE_THRESHOLD&&this.pauseCount++,this.lastKeystrokeTime=i,null!==this.lastKeyUpTime){const t=i-this.lastKeyUpTime;this.flightTimes.push(t),this.appendVector({dwellTime:-1,flightTime:t,digraphLatency:-1,timestamp:i})}if(null!==this.lastKeyDownTime){const t=i-this.lastKeyDownTime;this.digraphLatencies.push(t),this.appendVector({dwellTime:-1,flightTime:-1,digraphLatency:t,timestamp:i})}this.lastKeyDownTime=i,this.keyDownTimes.set(t.code,i),this.onEvent&&this.onEvent("keydown")}handleKeyUp(t){if(!this.isTargetField(t))return;const i=performance.now();this.keyupCount++;const e=this.keyDownTimes.get(t.code);if(void 0!==e){const n=i-e;this.dwellTimes.push(n),this.appendVector({dwellTime:n,flightTime:-1,digraphLatency:-1,timestamp:i}),this.keyDownTimes.delete(t.code)}this.lastKeyUpTime=i,this.onEvent&&this.onEvent("keyup")}appendVector(t){this.featureVectors.push(t),this.featureVectors.length>200&&this.featureVectors.splice(0,this.featureVectors.length-200)}isTargetField(t){const i=t.target;if(!i)return!1;return i.isContentEditable||["INPUT","TEXTAREA"].includes(i.tagName)}}const r=-1,o=["velocity","acceleration","jerk","curvature","angularVelocity","dwell","flight","digraphLatency"];class a{constructor(){this.isActive=!1,this.sessionEvents=[],this.trackEvent=t=>{this.sessionEvents.push({type:t,timestamp:performance.now()}),this.sessionEvents.length>500&&this.sessionEvents.shift()},this.kinematicEngine=new n({onEvent:this.trackEvent}),this.keystrokeMonitor=new s({onEvent:this.trackEvent})}start(){this.isActive||(this.kinematicEngine.start(),this.keystrokeMonitor.start(),this.isActive=!0)}stop(){this.isActive&&(this.kinematicEngine.stop(),this.keystrokeMonitor.stop(),this.isActive=!1)}reset(){this.sessionEvents=[],this.kinematicEngine.reset(),this.keystrokeMonitor.reset()}getData(){const t=this.kinematicEngine.getVectors(),i=this.keystrokeMonitor.getVectors(),e=[...t.map(t=>({timestamp:t.timestamp,values:[t.velocity,t.acceleration,t.jerk,t.curvature,t.angularVelocity,r,r,r]})),...i.map(t=>({timestamp:t.timestamp,values:[r,r,r,r,r,t.dwellTime,t.flightTime,t.digraphLatency]}))].sort((t,i)=>t.timestamp-i.timestamp),n=this.buildSequence(e),s=this.kinematicEngine.getSuspiciousSwipeVelocity(),o=this.calculateSessionEntropy();return{typing_dwell_ms:this.keystrokeMonitor.getDwellTimes(),typing_flight_ms:this.keystrokeMonitor.getFlightTimes(),swipe_velocity:s,suspicious_swipe_velocity:s,session_entropy:o,behavioral_vectors:n}}buildSequence(t){const i=[],e=Math.max(0,t.length-50),n=t.slice(e);for(const t of n)i.push(t.values);for(;i.length<50;)i.unshift(new Array(o.length).fill(r));return{featureNames:[...o],windowSize:50,maskValue:r,sequence:i}}calculateSessionEntropy(){if(0===this.sessionEvents.length)return 0;const t={};this.sessionEvents.forEach(i=>{t[i.type]=(t[i.type]||0)+1});const i=this.sessionEvents.length;return Object.values(t).reduce((t,e)=>{const n=e/i;return n>0?t-n*Math.log2(n):t},0)}getMouseSignals(){return this.kinematicEngine.getMouseSignals()}getKeyboardSignals(){return this.keystrokeMonitor.getKeyboardSignals()}}class h{constructor(){this.cachedFingerprint=null}collect(){if(this.cachedFingerprint)return this.cachedFingerprint;const t=performance.now();try{const i=document.createElement("canvas");i.width=200,i.height=50;const e=i.getContext("2d");if(!e)return null;e.textBaseline="top",e.font="14px Arial",e.textBaseline="alphabetic",e.fillStyle="#f60",e.fillRect(125,1,62,20),e.fillStyle="#069",e.fillText("KeverdFingerprint",2,15),e.fillStyle="rgba(102, 204, 0, 0.7)",e.fillText("KeverdFingerprint",4,17);const n=e.createLinearGradient(0,0,200,50);n.addColorStop(0,"rgba(255, 0, 0, 0.5)"),n.addColorStop(1,"rgba(0, 0, 255, 0.5)"),e.fillStyle=n,e.fillRect(0,0,200,50),e.strokeStyle="#000",e.lineWidth=2,e.beginPath(),e.arc(100,25,20,0,2*Math.PI),e.stroke(),e.font="12px Verdana",e.fillStyle="#000",e.fillText("CanvasFP",150,30);const s=i.toDataURL(),r=this.hashString(s),o=performance.now()-t;return this.cachedFingerprint={value:r,duration:Math.round(100*o)/100},this.cachedFingerprint}catch(t){return null}}hashString(t){let i=0;for(let e=0;e<t.length;e++){i=(i<<5)-i+t.charCodeAt(e),i&=i}return Math.abs(i).toString(16).padStart(8,"0")}clearCache(){this.cachedFingerprint=null}}class c{constructor(){this.cachedFingerprint=null}collect(){if(this.cachedFingerprint)return this.cachedFingerprint;const t=performance.now();try{const i=document.createElement("canvas"),e=i.getContext("webgl")||i.getContext("experimental-webgl");if(!e)return null;const n=e.getExtension("WEBGL_debug_renderer_info");let s=null,r=null;n?(s=e.getParameter(n.UNMASKED_VENDOR_WEBGL)||null,r=e.getParameter(n.UNMASKED_RENDERER_WEBGL)||null):(s=e.getParameter(e.VENDOR)||null,r=e.getParameter(e.RENDERER)||null);const o=e.getParameter(e.VERSION)||null,a=e.getParameter(e.SHADING_LANGUAGE_VERSION)||null,h=[];try{const t=e.getSupportedExtensions();t&&h.push(...t)}catch(t){}const c={maxTextureSize:e.getParameter(e.MAX_TEXTURE_SIZE),maxVertexAttribs:e.getParameter(e.MAX_VERTEX_ATTRIBS),maxViewportDims:e.getParameter(e.MAX_VIEWPORT_DIMS),maxTextureImageUnits:e.getParameter(e.MAX_TEXTURE_IMAGE_UNITS),maxCombinedTextureImageUnits:e.getParameter(e.MAX_COMBINED_TEXTURE_IMAGE_UNITS),maxFragmentUniformVectors:e.getParameter(e.MAX_FRAGMENT_UNIFORM_VECTORS),maxVaryingVectors:e.getParameter(e.MAX_VARYING_VECTORS),aliasedLineWidthRange:e.getParameter(e.ALIASED_LINE_WIDTH_RANGE),aliasedPointSizeRange:e.getParameter(e.ALIASED_POINT_SIZE_RANGE)},l={};try{const t=e.createShader(e.VERTEX_SHADER);if(t){e.shaderSource(t,"precision mediump float;"),e.compileShader(t);const i=e.createShader(e.FRAGMENT_SHADER);i&&(e.shaderSource(i,"precision mediump float;"),e.compileShader(i),l.float=e.getShaderPrecisionFormat(e.FRAGMENT_SHADER,e.HIGH_FLOAT)?.precision?.toString()||"unknown",l.int=e.getShaderPrecisionFormat(e.FRAGMENT_SHADER,e.HIGH_INT)?.precision?.toString()||"unknown")}}catch(t){}const u=performance.now()-t;return this.cachedFingerprint={vendor:s,renderer:r,version:o,shadingLanguageVersion:a,extensions:h.sort(),parameters:c,precision:l,duration:Math.round(100*u)/100},this.cachedFingerprint}catch(t){return null}}clearCache(){this.cachedFingerprint=null}}class l{constructor(){this.cachedFingerprint=null}async collect(){if(this.cachedFingerprint)return this.cachedFingerprint;const t=performance.now();try{const i=window.AudioContext||window.webkitAudioContext||window.mozAudioContext;if(!i)return null;const e=new i,n=e.createOscillator(),s=e.createAnalyser(),r=e.createGain(),o=e.createScriptProcessor(4096,1,1);return s.fftSize=2048,s.smoothingTimeConstant=.8,n.connect(s),s.connect(o),o.connect(r),r.connect(e.destination),n.type="triangle",n.frequency.value=1e4,new Promise(i=>{const s=[];let a=0;o.onaudioprocess=r=>{const o=r.inputBuffer.getChannelData(0);let h=0;for(let t=0;t<o.length;t++)h+=o[t]*o[t];const c=Math.sqrt(h/o.length);if(s.push(c),a++,a>=5){n.stop(),e.close();const r=this.calculateFingerprint(s),o=performance.now()-t;this.cachedFingerprint={value:r,duration:Math.round(100*o)/100},i(this.cachedFingerprint)}},n.start(0),r.gain.value=0,setTimeout(()=>{if(!this.cachedFingerprint){n.stop(),e.close();const s=this.getFallbackFingerprint(e),r=performance.now()-t;this.cachedFingerprint={value:s,duration:Math.round(100*r)/100},i(this.cachedFingerprint)}},1e3)})}catch(t){return null}}calculateFingerprint(t){if(0===t.length)return 0;const i=t.reduce((t,i)=>t+i,0)/t.length,e=t.reduce((t,e)=>t+Math.pow(e-i,2),0)/t.length,n=Math.sqrt(e),s=1e6*i+1e3*n+t.length;return Math.round(100*s)/100}getFallbackFingerprint(t){const i=t.sampleRate||44100,e=t.state||"unknown",n=(i.toString()+e).split("").reduce((t,i)=>(t<<5)-t+i.charCodeAt(0),0);return Math.abs(n)}clearCache(){this.cachedFingerprint=null}}class u{constructor(){this.cachedFingerprint=null,this.testFonts=["Arial","Verdana","Times New Roman","Courier New","Georgia","Palatino","Garamond","Bookman","Comic Sans MS","Trebuchet MS","Arial Black","Impact","Tahoma","Lucida Console","Lucida Sans Unicode","MS Sans Serif","MS Serif","Symbol","Webdings","Wingdings","Monaco","Menlo","Consolas","Courier","Helvetica","Helvetica Neue","Roboto","Open Sans","Lato","Montserrat"]}collect(){if(this.cachedFingerprint)return this.cachedFingerprint;const t=performance.now();try{const i=document.createElement("canvas").getContext("2d");if(!i)return null;const e="monospace",n="mmmmmmmmmmlli",s="72px";i.font=`${s} ${e}`;const r=i.measureText(n).width,o=[],a=[];for(const t of this.testFonts){i.font=`${s} ${t}, ${e}`;const h=i.measureText(n).width;Math.abs(h-r)>1?o.push(t):a.push(t)}const h=performance.now()-t;return this.cachedFingerprint={availableFonts:o.sort(),missingFonts:a.sort(),duration:Math.round(100*h)/100},this.cachedFingerprint}catch(t){return null}}clearCache(){this.cachedFingerprint=null}}class d{constructor(){this.cachedFingerprint=null}async collect(){if(this.cachedFingerprint)return this.cachedFingerprint;const t=performance.now();try{if(!navigator.mediaDevices||!navigator.mediaDevices.enumerateDevices)return null;let i=!1;try{const t=await navigator.mediaDevices.getUserMedia({audio:!0,video:!1});i=!0,t.getTracks().forEach(t=>t.stop())}catch(t){i=!1}const e=await navigator.mediaDevices.enumerateDevices(),n=[],s=[],r=[];e.forEach(t=>{const e={deviceId:t.deviceId,kind:t.kind,label:i?t.label:"",groupId:t.groupId,toJSON:()=>({deviceId:t.deviceId,kind:t.kind,label:i?t.label:"",groupId:t.groupId})};switch(t.kind){case"audioinput":n.push(e);break;case"audiooutput":s.push(e);break;case"videoinput":r.push(e)}});const o=performance.now()-t;return this.cachedFingerprint={audioInputs:n,audioOutputs:s,videoInputs:r,hasPermission:i,duration:Math.round(100*o)/100},this.cachedFingerprint}catch(t){return null}}clearCache(){this.cachedFingerprint=null}}class m{constructor(){this.cachedFingerprint=null}collect(){if(this.cachedFingerprint)return this.cachedFingerprint;const t=performance.now(),i={width:screen.width,height:screen.height,availWidth:screen.availWidth,availHeight:screen.availHeight,colorDepth:screen.colorDepth,pixelDepth:screen.pixelDepth,pixelRatio:window.devicePixelRatio||1,orientation:this.getOrientation(),orientationAngle:this.getOrientationAngle(),duration:0};return i.duration=Math.round(100*(performance.now()-t))/100,this.cachedFingerprint=i,i}getOrientation(){if("orientation"in screen){const t=screen.orientation;if(t&&t.type)return t.type}if("orientation"in window){const t=window.orientation;if(void 0!==t){if(0===t||180===t)return"portrait";if(90===t||-90===t)return"landscape"}}if(window.matchMedia){if(window.matchMedia("(orientation: portrait)").matches)return"portrait";if(window.matchMedia("(orientation: landscape)").matches)return"landscape"}return null}getOrientationAngle(){if("orientation"in screen){const t=screen.orientation;if(t&&"number"==typeof t.angle)return t.angle}if("orientation"in window){const t=window.orientation;if("number"==typeof t)return t}return null}clearCache(){this.cachedFingerprint=null}}class p{constructor(){this.cachedFingerprint=null}collect(){if(this.cachedFingerprint)return this.cachedFingerprint;const t=performance.now(),i=Intl.DateTimeFormat().resolvedOptions().timeZone,e=(new Date).getTimezoneOffset(),n=Intl.DateTimeFormat().resolvedOptions(),s=n.locale,r=navigator.languages||[navigator.language],o=this.getDateFormat(),a=this.getTimeFormat(),h=this.getNumberFormat(),c=n.calendar||null,l={timezone:i,timezoneOffset:e,locale:s,locales:r.slice(0,5),dateFormat:o,timeFormat:a,numberFormat:h,calendar:c,duration:0};return l.duration=Math.round(100*(performance.now()-t))/100,this.cachedFingerprint=l,l}getDateFormat(){try{const t=(new Intl.DateTimeFormat).format(new Date(2023,0,15));return t.includes("/")?"numeric":t.includes("-")?"iso":t.includes(".")?"european":"unknown"}catch{return"unknown"}}getTimeFormat(){try{const t=new Intl.DateTimeFormat(void 0,{hour:"numeric",minute:"numeric"}).format(new Date(2023,0,15,13,30));return t.toLowerCase().includes("am")||t.toLowerCase().includes("pm")?"12h":"24h"}catch{return"unknown"}}getNumberFormat(){try{const t=(new Intl.NumberFormat).format(1234.56);return t.includes(",")?"european":t.includes(".")?"american":"unknown"}catch{return"unknown"}}clearCache(){this.cachedFingerprint=null}}class g{constructor(){this.cachedFingerprint=null}collect(){if(this.cachedFingerprint)return this.cachedFingerprint;const t=performance.now();try{if(!navigator.plugins||0===navigator.plugins.length)return null;const i=[],e=new Set;for(let t=0;t<Math.min(navigator.plugins.length,10);t++){const n=navigator.plugins[t];if(!n)continue;const s=[];for(let t=0;t<Math.min(n.length,5);t++){const i=n[t];i&&i.type&&(s.push(i.type),e.add(i.type))}i.push({name:n.name||"Unknown",description:n.description||"",mimeTypes:s})}const n={plugins:i,mimeTypes:Array.from(e).sort(),duration:0};return n.duration=Math.round(100*(performance.now()-t))/100,this.cachedFingerprint=n,n}catch(t){return null}}clearCache(){this.cachedFingerprint=null}}class w{constructor(){this.cachedFingerprint=null}async collect(){if(this.cachedFingerprint)return this.cachedFingerprint;const t=performance.now();try{const i=await this.getBatteryManager();if(!i)return null;const e={level:i.level,charging:i.charging,chargingTime:i.chargingTime,dischargingTime:i.dischargingTime,duration:0};return e.duration=Math.round(100*(performance.now()-t))/100,this.cachedFingerprint=e,e}catch(t){return null}}async getBatteryManager(){if("getBattery"in navigator)try{return await navigator.getBattery()}catch(t){}if("webkitGetBattery"in navigator)try{return await navigator.webkitGetBattery()}catch(t){}if("mozGetBattery"in navigator)try{return await navigator.mozGetBattery()}catch(t){}return null}clearCache(){this.cachedFingerprint=null}}class f{constructor(){this.cachedFingerprint=null}async collect(){if(this.cachedFingerprint)return this.cachedFingerprint;const t=performance.now(),i={localStorage:await this.checkLocalStorage(),sessionStorage:await this.checkSessionStorage(),indexedDB:this.checkIndexedDB(),webSQL:this.checkWebSQL(),duration:0};return i.duration=Math.round(100*(performance.now()-t))/100,this.cachedFingerprint=i,i}async checkLocalStorage(){let t=!1,i=null,e=null;try{const n="__localStorage_test__";if(localStorage.setItem(n,n),localStorage.removeItem(n),t=!0,"storage"in navigator&&"estimate"in navigator.storage)try{const t=await navigator.storage.estimate();t&&(i=t.quota||null,e=t.usage||null)}catch(t){}}catch(i){t=!1}return{available:t,quota:i,usage:e}}async checkSessionStorage(){let t=!1,i=null,e=null;try{const n="__sessionStorage_test__";if(sessionStorage.setItem(n,n),sessionStorage.removeItem(n),t=!0,"storage"in navigator&&"estimate"in navigator.storage)try{const t=await navigator.storage.estimate();t&&(i=t.quota||null,e=t.usage||null)}catch(t){}}catch(i){t=!1}return{available:t,quota:i,usage:e}}checkIndexedDB(){return{available:"indexedDB"in window&&!!window.indexedDB}}checkWebSQL(){return{available:"openDatabase"in window&&!!window.openDatabase}}clearCache(){this.cachedFingerprint=null}}class v{constructor(){this.cachedFingerprint=null}collect(){if(this.cachedFingerprint)return this.cachedFingerprint;const t=performance.now(),i={hardwareConcurrency:navigator.hardwareConcurrency||0,deviceMemory:this.getDeviceMemory(),performanceMemory:this.getPerformanceMemory(),duration:0};return i.duration=Math.round(100*(performance.now()-t))/100,this.cachedFingerprint=i,i}getDeviceMemory(){return"deviceMemory"in navigator&&navigator.deviceMemory?navigator.deviceMemory:null}getPerformanceMemory(){if("memory"in performance){const t=performance.memory;return{jsHeapSizeLimit:t.jsHeapSizeLimit||null,totalJSHeapSize:t.totalJSHeapSize||null,usedJSHeapSize:t.usedJSHeapSize||null}}return{jsHeapSizeLimit:null,totalJSHeapSize:null,usedJSHeapSize:null}}clearCache(){this.cachedFingerprint=null}}class y{constructor(){this.cachedFingerprint=null}collect(){if(this.cachedFingerprint)return this.cachedFingerprint;const t=performance.now(),i={maxTouchPoints:navigator.maxTouchPoints||0,touchSupport:this.checkTouchSupport(),pointerSupport:this.checkPointerSupport(),pointerTypes:this.getPointerTypes(),duration:0};return i.duration=Math.round(100*(performance.now()-t))/100,this.cachedFingerprint=i,i}checkTouchSupport(){return"ontouchstart"in window||navigator.maxTouchPoints>0||!!window.DocumentTouch&&document instanceof window.DocumentTouch}checkPointerSupport(){return"PointerEvent"in window||"MSPointerEvent"in window}getPointerTypes(){const t=[];return"PointerEvent"in window&&(navigator.maxTouchPoints>0&&t.push("touch"),t.push("mouse"),"pen"in navigator&&t.push("pen")),t}clearCache(){this.cachedFingerprint=null}}class S{constructor(){this.cachedFingerprint=null}async collect(){if(this.cachedFingerprint)return this.cachedFingerprint;const t=performance.now();try{if(!("permissions"in navigator))return null;const i=navigator.permissions,e={camera:await this.queryPermission(i,"camera"),microphone:await this.queryPermission(i,"microphone"),notifications:await this.queryPermission(i,"notifications"),geolocation:await this.queryPermission(i,"geolocation"),persistentStorage:await this.queryPermission(i,"persistent-storage"),duration:0};return e.duration=Math.round(100*(performance.now()-t))/100,this.cachedFingerprint=e,e}catch(t){return null}}async queryPermission(t,i){try{return(await t.query({name:i})).state||null}catch(t){return null}}clearCache(){this.cachedFingerprint=null}}class b{constructor(){this.cachedFingerprint=null}async collect(){if(this.cachedFingerprint)return this.cachedFingerprint;const t=performance.now();try{const i=window.RTCPeerConnection||window.webkitRTCPeerConnection||window.mozRTCPeerConnection;if(!i)return null;const e=[];let n=null;const s=new i({iceServers:[{urls:"stun:stun.l.google.com:19302"}]});s.onicecandidate=t=>{if(t.candidate){const i=t.candidate.candidate.match(/([0-9]{1,3}\.){3}[0-9]{1,3}/);if(i){const t=i[0];this.isLocalIP(t)?e.includes(t)||e.push(t):n=t}}},s.createDataChannel("");const r=await s.createOffer();await s.setLocalDescription(r),await new Promise(t=>{const i=setTimeout(()=>{t()},2e3);s.onicegatheringstatechange=()=>{"complete"===s.iceGatheringState&&(clearTimeout(i),t())},"complete"===s.iceGatheringState&&(clearTimeout(i),t())}),s.close();const o={localIPs:e.sort(),publicIP:n,duration:0};return o.duration=Math.round(100*(performance.now()-t))/100,this.cachedFingerprint=o,o}catch(t){return null}}isLocalIP(t){if("127.0.0.1"===t||"::1"===t)return!0;const i=t.split(".");if(4===i.length){const t=parseInt(i[0],10),e=parseInt(i[1],10);if(10===t)return!0;if(172===t&&e>=16&&e<=31)return!0;if(192===t&&168===e)return!0;if(169===t&&254===e)return!0}return!1}clearCache(){this.cachedFingerprint=null}}class k{generate(t){const i=[];t.canvas?.value&&i.push(`canvas:${t.canvas.value}`),t.webgl&&(t.webgl.vendor&&i.push(`webgl_vendor:${t.webgl.vendor}`),t.webgl.renderer&&i.push(`webgl_renderer:${t.webgl.renderer}`),t.webgl.extensions.length>0&&i.push(`webgl_ext:${t.webgl.extensions.slice(0,10).join(",")}`)),t.audio?.value&&i.push(`audio:${t.audio.value}`),t.screen&&(i.push(`screen:${t.screen.width}x${t.screen.height}x${t.screen.pixelRatio}`),i.push(`color:${t.screen.colorDepth}`)),t.timezone&&(i.push(`tz:${t.timezone.timezone}`),i.push(`locale:${t.timezone.locale}`)),t.cpu&&(i.push(`cpu:${t.cpu.hardwareConcurrency}`),t.cpu.deviceMemory&&i.push(`memory:${t.cpu.deviceMemory}`)),t.touch&&i.push(`touch:${t.touch.maxTouchPoints}`),i.push(`ua:${navigator.userAgent}`),i.push(`lang:${navigator.language}`),i.push(`platform:${navigator.platform}`),t.fonts&&t.fonts.availableFonts.length>0&&i.push(`fonts:${t.fonts.availableFonts.slice(0,20).join(",")}`);const e=i.join("|");return this.sha256Hash(e)}calculateConfidence(t){let i=0,e=0;const n={canvas:20,webgl:20,audio:15,screen:10,timezone:10,cpu:10,fonts:10,touch:5,storage:5,permissions:5,webrtc:5,mediaDevices:5,battery:3,plugins:3};return Object.keys(n).forEach(s=>{e+=n[s],t[s]&&(i+=n[s])}),e>0?Math.min(i/e,1):0}sha256Hash(t){return"undefined"!=typeof crypto&&crypto.subtle,this.sha256LikeHash(t)}sha256LikeHash(t){const i=[];let e=5381;for(let i=0;i<t.length;i++)e=(e<<5)+e+t.charCodeAt(i),e&=4294967295;i.push(e);let n=0;for(let i=t.length-1;i>=0;i--)n=(n<<7)-n+t.charCodeAt(i),n&=4294967295;i.push(n);let s=0;for(let i=0;i<t.length;i++)s^=t.charCodeAt(i)<<i%4*8,s&=4294967295;i.push(s);let r=0;for(let i=0;i<t.length;i++)r=31*r+t.charCodeAt(i)&4294967295;i.push(r);let o=0;for(let i=0;i<t.length;i++){o=o+(4294967295&(t.charCodeAt(i)<<i%16|t.charCodeAt(i)>>>32-i%16))&4294967295}i.push(o);let a=2166136261;for(let i=0;i<t.length;i++)a=16777619*(a^t.charCodeAt(i)),a&=4294967295;i.push(a);let h=0;for(let i=0;i<t.length;i++)h=h+t.charCodeAt(i)*(i+1)&4294967295;i.push(h);let c=0;for(let i=0;i<t.length;i+=2){c=(c<<3)-c+(t.charCodeAt(i)+256*(t.charCodeAt(i+1)||0)),c&=4294967295}i.push(c);return i.map(t=>Math.abs(t).toString(16).padStart(8,"0")).join("").substring(0,64).padEnd(64,"0")}}class C{constructor(){this.cachedData=null,this.collectionStartTime=0,this.collectors={canvas:new h,webgl:new c,audio:new l,fonts:new u,mediaDevices:new d,screen:new m,timezone:new p,plugins:new g,battery:new w,storage:new f,cpu:new v,touch:new y,permissions:new S,webrtc:new b},this.visitorIDGenerator=new k}async collect(){if(this.cachedData)return this.cachedData;this.collectionStartTime=performance.now();const t={};try{t.canvas=this.collectors.canvas.collect()||void 0}catch(t){}try{t.webgl=this.collectors.webgl.collect()||void 0}catch(t){}try{t.fonts=this.collectors.fonts.collect()||void 0}catch(t){}try{t.screen=this.collectors.screen.collect()}catch(t){}try{t.timezone=this.collectors.timezone.collect()}catch(t){}try{t.plugins=this.collectors.plugins.collect()||void 0}catch(t){}try{t.cpu=this.collectors.cpu.collect()}catch(t){}try{t.touch=this.collectors.touch.collect()}catch(t){}try{t.audio=await this.collectors.audio.collect()||void 0}catch(t){}try{t.mediaDevices=await this.collectors.mediaDevices.collect()||void 0}catch(t){}try{t.battery=await this.collectors.battery.collect()||void 0}catch(t){}try{t.storage=await this.collectors.storage.collect()}catch(t){}try{t.permissions=await this.collectors.permissions.collect()||void 0}catch(t){}try{t.webrtc=await this.collectors.webrtc.collect()||void 0}catch(t){}const i=this.visitorIDGenerator.generate(t),e=this.visitorIDGenerator.calculateConfidence(t);return this.cachedData={visitorId:i,confidence:Math.round(1e3*e)/1e3,components:t,version:"1.0.0",timestamp:Date.now()},this.cachedData}async getVisitorId(){return(await this.collect()).visitorId}clearCache(){this.cachedData=null,Object.values(this.collectors).forEach(t=>{t&&"function"==typeof t.clearCache&&t.clearCache()})}getStats(){if(!this.cachedData)return{componentsCollected:0,totalComponents:13,collectionTime:0};const t=Object.keys(this.cachedData.components).length,i=performance.now()-this.collectionStartTime;return{componentsCollected:t,totalComponents:13,collectionTime:Math.round(100*i)/100}}}class M{constructor(){this.cachedSignals=null}collect(){if(this.cachedSignals)return this.cachedSignals;const t={isIncognito:this.detectIncognito(),isVPN:!1,isAutomated:this.detectAutomation(),hasAdBlocker:this.detectAdBlocker()};return this.cachedSignals=t,t}detectIncognito(){try{if("storage"in navigator&&"estimate"in navigator.storage)try{navigator.storage.estimate().then(()=>{}).catch(()=>{})}catch{return!0}if("storage"in navigator&&navigator.storage,navigator,window.chrome&&window.chrome.runtime&&!window.chrome.runtime.onConnect)return!0;try{const t="__incognito_test__";localStorage.setItem(t,"test"),localStorage.removeItem(t)}catch{return!0}return!1}catch(t){return!1}}detectAutomation(){try{if(!0===navigator.webdriver)return!0;if(window.chrome&&window.chrome.runtime&&window.chrome.runtime.onConnect){if(window.chrome.runtime.onConnect.hasListeners())return!0}if(!(window.chrome||window.safari||window.Notification&&window.DeviceMotionEvent))return!0;try{const t=document.createElement("canvas"),i=t.getContext("2d");if(i){i.textBaseline="top",i.font="14px Arial",i.fillText("Automation test",2,2);if(t.toDataURL().length<100)return!0}}catch{}return!!(window.__nightmare||window.__phantomas||window.Buffer)}catch(t){return!1}}detectAdBlocker(){try{const t=document.createElement("div");t.innerHTML=" ",t.className="adsbox",t.style.position="absolute",t.style.left="-9999px",document.body.appendChild(t),setTimeout(()=>{const i=0===t.offsetHeight||0===t.offsetWidth;return document.body.removeChild(t),i},100);const i=Array.from(document.getElementsByTagName("script"));return i.filter(t=>t.src&&t.src.includes("ads")&&!t.textContent).length>0||!!(window.uBlock||window.adblock||window.BlockAdBlock)}catch(t){return!1}}clearCache(){this.cachedSignals=null}}class D{constructor(){this.cachedCapabilities=null}collect(){if(this.cachedCapabilities)return this.cachedCapabilities;const t={hasWebGL:this.checkWebGL(),hasCanvas:this.checkCanvas(),hasWebRTC:this.checkWebRTC(),hasServiceWorker:this.checkServiceWorker(),hasIndexedDB:this.checkIndexedDB(),hasLocalStorage:this.checkLocalStorage(),hasSessionStorage:this.checkSessionStorage(),cookieEnabled:navigator.cookieEnabled,doNotTrack:"1"===navigator.doNotTrack||"yes"===navigator.doNotTrack};return this.cachedCapabilities=t,t}checkWebGL(){try{const t=document.createElement("canvas");return!(!t.getContext("webgl")&&!t.getContext("experimental-webgl"))}catch{return!1}}checkCanvas(){try{return!!document.createElement("canvas").getContext("2d")}catch{return!1}}checkWebRTC(){return!!((window.RTCPeerConnection||window.webkitRTCPeerConnection||window.mozRTCPeerConnection)&&navigator.mediaDevices&&navigator.mediaDevices.getUserMedia)}checkServiceWorker(){return"serviceWorker"in navigator}checkIndexedDB(){return"indexedDB"in window}checkLocalStorage(){try{const t="__localStorage_test__";return localStorage.setItem(t,t),localStorage.removeItem(t),!0}catch{return!1}}checkSessionStorage(){try{const t="__sessionStorage_test__";return sessionStorage.setItem(t,t),sessionStorage.removeItem(t),!0}catch{return!1}}clearCache(){this.cachedCapabilities=null}}class T{constructor(){this.cachedSignals=null}collect(){if(this.cachedSignals)return this.cachedSignals;const t={hardwareConcurrency:navigator.hardwareConcurrency||0,deviceMemory:this.getDeviceMemory(),maxTouchPoints:navigator.maxTouchPoints||0,connectionType:this.getConnectionType(),effectiveType:this.getEffectiveType(),downlink:this.getDownlink(),rtt:this.getRTT(),saveData:this.getSaveData()};return this.cachedSignals=t,t}getDeviceMemory(){return"deviceMemory"in navigator&&navigator.deviceMemory?navigator.deviceMemory:null}getConnectionType(){const t=navigator.connection||navigator.mozConnection||navigator.webkitConnection;return t&&t.type?t.type:null}getEffectiveType(){const t=navigator.connection||navigator.mozConnection||navigator.webkitConnection;return t&&t.effectiveType?t.effectiveType:null}getDownlink(){const t=navigator.connection||navigator.mozConnection||navigator.webkitConnection;return t&&t.downlink?t.downlink:null}getRTT(){const t=navigator.connection||navigator.mozConnection||navigator.webkitConnection;return t&&t.rtt?t.rtt:null}getSaveData(){const t=navigator.connection||navigator.mozConnection||navigator.webkitConnection;return t&&void 0!==t.saveData?t.saveData:null}clearCache(){this.cachedSignals=null}}class _{constructor(){this.focusCount=0,this.blurCount=0,this.copyCount=0,this.pasteCount=0,this.cutCount=0,this.fieldFocusOrder=[],this.fieldFocusTimes=new Map,this.backspaceCount=0,this.deleteCount=0,this.autofillDetected=!1,this.autocompleteDetected=!1,this.isActive=!1,this.focusHandler=t=>this.handleFocus(t),this.blurHandler=t=>this.handleBlur(t),this.copyHandler=t=>this.handleCopy(t),this.pasteHandler=t=>this.handlePaste(t),this.cutHandler=t=>this.handleCut(t),this.keydownHandler=t=>this.handleKeyDown(t),this.inputHandler=t=>this.handleInput(t)}start(){this.isActive||"undefined"==typeof document||(document.addEventListener("focus",this.focusHandler,!0),document.addEventListener("blur",this.blurHandler,!0),document.addEventListener("copy",this.copyHandler,!0),document.addEventListener("paste",this.pasteHandler,!0),document.addEventListener("cut",this.cutHandler,!0),document.addEventListener("keydown",this.keydownHandler,!0),document.addEventListener("input",this.inputHandler,!0),this.isActive=!0)}stop(){this.isActive&&"undefined"!=typeof document&&(document.removeEventListener("focus",this.focusHandler,!0),document.removeEventListener("blur",this.blurHandler,!0),document.removeEventListener("copy",this.copyHandler,!0),document.removeEventListener("paste",this.pasteHandler,!0),document.removeEventListener("cut",this.cutHandler,!0),document.removeEventListener("keydown",this.keydownHandler,!0),document.removeEventListener("input",this.inputHandler,!0),this.isActive=!1)}getData(){const t={};return this.fieldFocusTimes.forEach((i,e)=>{t[e]=i}),{focusCount:this.focusCount,blurCount:this.blurCount,copyCount:this.copyCount,pasteCount:this.pasteCount,cutCount:this.cutCount,autofillDetected:this.autofillDetected,autocompleteDetected:this.autocompleteDetected,fieldFocusOrder:[...this.fieldFocusOrder],timePerField:t,backspaceCount:this.backspaceCount,deleteCount:this.deleteCount}}reset(){this.focusCount=0,this.blurCount=0,this.copyCount=0,this.pasteCount=0,this.cutCount=0,this.fieldFocusOrder=[],this.fieldFocusTimes.clear(),this.backspaceCount=0,this.deleteCount=0,this.autofillDetected=!1,this.autocompleteDetected=!1}handleFocus(t){const i=t.target;if(!this.isFormField(i))return;this.focusCount++;const e=this.getFieldId(i);e&&!this.fieldFocusOrder.includes(e)&&this.fieldFocusOrder.push(e),this.fieldFocusTimes.set(e||"unknown",Date.now())}handleBlur(t){const i=t.target;if(!this.isFormField(i))return;this.blurCount++;const e=this.getFieldId(i);if(e){const t=this.fieldFocusTimes.get(e)||Date.now(),i=Date.now()-t;this.fieldFocusTimes.set(e,i)}}handleCopy(t){const i=t.target;this.isFormField(i)&&this.copyCount++}handlePaste(t){const i=t.target;this.isFormField(i)&&this.pasteCount++}handleCut(t){const i=t.target;this.isFormField(i)&&this.cutCount++}handleKeyDown(t){const i=t.target;this.isFormField(i)&&("Backspace"===t.key?this.backspaceCount++:"Delete"===t.key&&this.deleteCount++)}handleInput(t){const i=t.target;if(!this.isFormField(i))return;i.value&&"password"===i.type&&(this.autofillDetected=!0),i.hasAttribute("autocomplete")&&"off"!==i.getAttribute("autocomplete")&&(this.autocompleteDetected=!0)}isFormField(t){if(!t)return!1;const i=t.tagName.toLowerCase();return"input"===i||"textarea"===i||"select"===i||t.isContentEditable}getFieldId(t){return t.id?t.id:"name"in t&&t.name?t.name:t.getAttribute("data-field-id")?t.getAttribute("data-field-id"):null}}class x{constructor(){this.pageLoadTime=0,this.timeToFirstInteraction=0,this.startTime=Date.now(),this.firstInteractionTime=null,this.maxScrollDepth=0,this.clickCount=0,this.linkClickCount=0,this.imageViewCount=0,this.videoPlayCount=0,this.isActive=!1,this.clickHandler=t=>this.handleClick(t),this.scrollHandler=()=>this.handleScroll(),this.loadHandler=()=>this.handleLoad(),this.imageLoadHandler=()=>this.handleImageLoad(),this.videoPlayHandler=()=>this.handleVideoPlay(),this.startTime=performance.now()}start(){this.isActive||"undefined"==typeof document||("complete"===document.readyState?this.pageLoadTime=performance.now()-this.startTime:window.addEventListener("load",this.loadHandler),document.addEventListener("click",this.clickHandler,!0),window.addEventListener("scroll",this.scrollHandler,{passive:!0}),document.addEventListener("load",this.imageLoadHandler,!0),document.addEventListener("play",this.videoPlayHandler,!0),this.isActive=!0)}stop(){this.isActive&&"undefined"!=typeof document&&(window.removeEventListener("load",this.loadHandler),document.removeEventListener("click",this.clickHandler,!0),window.removeEventListener("scroll",this.scrollHandler),document.removeEventListener("load",this.imageLoadHandler,!0),document.removeEventListener("play",this.videoPlayHandler,!0),this.isActive=!1)}getData(){const t=Date.now()-this.startTime,i=this.calculateScrollDepth();return{pageLoadTime:this.pageLoadTime,timeToFirstInteraction:this.firstInteractionTime?this.firstInteractionTime-this.startTime:0,timeOnPage:t,scrollDepth:i,clickCount:this.clickCount,linkClickCount:this.linkClickCount,imageViewCount:this.imageViewCount,videoPlayCount:this.videoPlayCount}}reset(){this.pageLoadTime=0,this.timeToFirstInteraction=0,this.startTime=Date.now(),this.firstInteractionTime=null,this.maxScrollDepth=0,this.clickCount=0,this.linkClickCount=0,this.imageViewCount=0,this.videoPlayCount=0}handleLoad(){this.pageLoadTime=performance.now()-this.startTime}handleClick(t){this.firstInteractionTime||(this.firstInteractionTime=performance.now()),this.clickCount++;const i=t.target;("a"===i.tagName.toLowerCase()||i.closest("a"))&&this.linkClickCount++}handleScroll(){const t=this.calculateScrollDepth();this.maxScrollDepth=Math.max(this.maxScrollDepth,t)}handleImageLoad(){this.imageViewCount++}handleVideoPlay(){this.videoPlayCount++}calculateScrollDepth(){if("undefined"==typeof window||"undefined"==typeof document)return 0;const t=window.innerHeight||document.documentElement.clientHeight,i=Math.max(document.body.scrollHeight,document.body.offsetHeight,document.documentElement.clientHeight,document.documentElement.scrollHeight,document.documentElement.offsetHeight),e=window.pageYOffset||document.documentElement.scrollTop;if(0===i)return 0;const n=e+t;return Math.min(n/i,1)}}class I{constructor(){this.config=null,this.isInitialized=!1,this.sessionId=null,this.deviceCollector=new e,this.behavioralCollector=new a,this.fingerprintManager=new C,this.privacySignalCollector=new M,this.browserCapabilityCollector=new D,this.hardwareSignalCollector=new T,this.formInteractionCollector=new _,this.pageInteractionCollector=new x}init(t){this.isInitialized?this.config:(this.config="string"==typeof t?{apiKey:t,endpoint:"https://api.keverd.com",debug:!1}:{endpoint:"https://api.keverd.com",debug:!1,...t},this.behavioralCollector.start(),this.formInteractionCollector.start(),this.pageInteractionCollector.start(),this.sessionId=this.generateSessionId(),this.isInitialized=!0,this.config.debug)}async getVisitorData(){if(!this.isInitialized||!this.config)throw new Error("Keverd SDK not initialized. Call init() first.");try{const t=this.deviceCollector.collect(),i=this.behavioralCollector.getData(),e=await this.fingerprintManager.collect(),n={visitorId:e.visitorId,confidence:e.confidence,components:e.components},s=this.privacySignalCollector.collect(),r=this.browserCapabilityCollector.collect(),o=this.hardwareSignalCollector.collect(),a=this.formInteractionCollector.getData(),h=this.behavioralCollector.getMouseSignals(),c=this.behavioralCollector.getKeyboardSignals(),l=this.pageInteractionCollector.getData(),u={connectionType:o.connectionType||void 0,effectiveType:o.effectiveType||void 0,downlink:o.downlink||void 0,rtt:o.rtt||void 0,saveData:o.saveData||void 0},d={sessionId:this.sessionId||void 0,timestamp:(new Date).toISOString()},m={userId:this.config.userId,device:t,session:d,behavioral:i,fingerprintjs:n||void 0,privacySignals:s,browserCapabilities:r,hardwareSignals:o,formInteractions:a,mouseSignals:h,keyboardSignals:c,pageInteractions:l,networkSignals:u,useCase:"general"};return await this.sendFingerprintRequest(m)}catch(t){const i=t instanceof Error?t.message:"Unknown error";throw this.config.debug,new Error(`Failed to get visitor data: ${i}`)}}async createTransactionID(t){return(await this.getVisitorData()).session_id}async verifyLogin(t,i){if(!this.isInitialized||!this.config)throw new Error("Keverd SDK not initialized. Call init() first.");return await this.sendVerifyRequest("login",{userId:t,metadata:i})}async verifyCheckout(t,i,e){if(!this.isInitialized||!this.config)throw new Error("Keverd SDK not initialized. Call init() first.");return await this.sendVerifyRequest("checkout",{amount:t,currency:i,metadata:e})}async verifyRegistration(t){if(!this.isInitialized||!this.config)throw new Error("Keverd SDK not initialized. Call init() first.");return await this.sendVerifyRequest("registration",{metadata:t})}async verifyPasswordReset(t,i){if(!this.isInitialized||!this.config)throw new Error("Keverd SDK not initialized. Call init() first.");return await this.sendVerifyRequest("password_reset",{email:t,metadata:i})}async verifyAccountChange(t,i){if(!this.isInitialized||!this.config)throw new Error("Keverd SDK not initialized. Call init() first.");return await this.sendVerifyRequest("account_change",{changeType:t,metadata:i})}async sendVerifyRequest(t,i){if(!this.config)throw new Error("SDK not initialized");const e=this.deviceCollector.collect(),n=this.behavioralCollector.getData(),s=await this.fingerprintManager.collect(),r={visitorId:s.visitorId,confidence:s.confidence,components:s.components},o=this.privacySignalCollector.collect(),a=this.browserCapabilityCollector.collect(),h=this.hardwareSignalCollector.collect(),c=this.formInteractionCollector.getData(),l=this.behavioralCollector.getMouseSignals(),u=this.behavioralCollector.getKeyboardSignals(),d=this.pageInteractionCollector.getData(),m={connectionType:h.connectionType||void 0,effectiveType:h.effectiveType||void 0,downlink:h.downlink||void 0,rtt:h.rtt||void 0,saveData:h.saveData||void 0},p={sessionId:this.sessionId||void 0,timestamp:(new Date).toISOString()},g={userId:i.userId||this.config.userId,device:e,session:p,behavioral:n,fingerprintjs:r||void 0,privacySignals:o,browserCapabilities:a,hardwareSignals:h,formInteractions:c,mouseSignals:l,keyboardSignals:u,pageInteractions:d,networkSignals:m,useCase:t};i.metadata&&Object.assign(g,i.metadata),void 0!==i.amount&&(g.amount=i.amount),i.currency&&(g.currency=i.currency),i.email&&(g.email=i.email),i.changeType&&(g.changeType=i.changeType);const w=`${this.config.endpoint||"https://api.keverd.com"}/fingerprint/verify/${t}`,f={"Content-Type":"application/json","X-SDK-Source":"javascript"},v=this.config.apiKey;v&&(f["x-keverd-key"]=v,f["X-API-KEY"]=v,f.Authorization=`Bearer ${v}`);const y=await fetch(w,{method:"POST",headers:f,body:JSON.stringify(g)});if(!y.ok){const t=await y.text().catch(()=>"Unknown error");throw new Error(`HTTP ${y.status}: ${t}`)}return await y.json()}async sendFingerprintRequest(t){if(!this.config)throw new Error("SDK not initialized");const i=`${this.config.endpoint||"https://api.keverd.com"}/fingerprint/score`,e={"Content-Type":"application/json","X-SDK-Source":"javascript"},n=this.config.apiKey;n&&(e["x-keverd-key"]=n,e["X-API-KEY"]=n,e.Authorization=`Bearer ${n}`);const s=await fetch(i,{method:"POST",headers:e,body:JSON.stringify(t)});if(!s.ok){const t=await s.text().catch(()=>"Unknown error");throw new Error(`HTTP ${s.status}: ${t}`)}return await s.json()}generateSessionId(){return`${Date.now()}_${Math.random().toString(36).substr(2,9)}`}destroy(){this.behavioralCollector.stop(),this.formInteractionCollector.stop(),this.pageInteractionCollector.stop(),this.fingerprintManager.clearCache(),this.isInitialized=!1,this.config,this.config=null,this.sessionId=null}isReady(){return this.isInitialized&&null!==this.config}}const $=new I;class P{async collect(){return null}clearCache(){}async isAvailable(){return!1}}return i})());
|
|
1
|
+
!function(t,i){"object"==typeof exports&&"object"==typeof module?module.exports=i():"function"==typeof define&&define.amd?define([],i):"object"==typeof exports?exports.FintechRisk=i():t.FintechRisk=i()}(this,()=>(()=>{"use strict";var t={d:(i,e)=>{for(var s in e)t.o(e,s)&&!t.o(i,s)&&Object.defineProperty(i,s,{enumerable:!0,get:e[s]})},o:(t,i)=>Object.prototype.hasOwnProperty.call(t,i),r:t=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"t",{value:!0})}},i={};t.r(i),t.d(i,{BehavioralCollector:()=>a,DeviceCollector:()=>e,FingerprintJSCollector:()=>O,Keverd:()=>P,KeverdSDK:()=>x,KeystrokeMonitor:()=>n,KinematicEngine:()=>s});class e{constructor(){this.cachedDeviceInfo=null}collect(){if(this.cachedDeviceInfo)return this.cachedDeviceInfo;const t=this.generateDeviceFingerprint(),i=this.generateDeviceId(t);return this.cachedDeviceInfo={deviceId:i,fingerprint:t,manufacturer:this.getManufacturer(),model:this.getModel(),brand:this.getBrand(),device:this.getDevice(),product:this.getProduct(),hardware:this.getHardware(),sdkVersion:"1.0.0",osVersion:this.getOSVersion(),screenWidth:String(screen.width),screenHeight:String(screen.height),screenDensity:this.getScreenDensity(),locale:navigator.language||navigator.languages?.[0]||"en",timezone:Intl.DateTimeFormat().resolvedOptions().timeZone},this.cachedDeviceInfo}generateDeviceFingerprint(){const t=[],i=this.getCanvasFingerprint();i&&t.push(i);const e=this.getWebGLFingerprint();if(e&&t.push(e),t.push(navigator.userAgent),t.push(navigator.language||navigator.languages?.[0]||""),t.push(`${screen.width}x${screen.height}x${screen.colorDepth}`),t.push(String((new Date).getTimezoneOffset())),t.push(navigator.platform),t.push(String(navigator.hardwareConcurrency||0)),"deviceMemory"in navigator&&t.push(String(navigator.deviceMemory)),"maxTouchPoints"in navigator&&t.push(String(navigator.maxTouchPoints)),navigator.plugins&&navigator.plugins.length>0){const i=Array.from(navigator.plugins).slice(0,3).map(t=>t.name).join(",");t.push(i)}const s=t.join("|");return this.hashString(s)}getCanvasFingerprint(){try{const t=document.createElement("canvas"),i=t.getContext("2d");return i?(t.width=200,t.height=50,i.textBaseline="top",i.font="14px Arial",i.fillStyle="#f60",i.fillRect(125,1,62,20),i.fillStyle="#069",i.fillText("KeverdFingerprint",2,15),i.fillStyle="rgba(102, 204, 0, 0.7)",i.fillText("KeverdFingerprint",4,17),this.hashString(t.toDataURL())):""}catch(t){return""}}getWebGLFingerprint(){try{const t=document.createElement("canvas"),i=t.getContext("webgl")||t.getContext("experimental-webgl");if(!i)return"";const e=i.getExtension("WEBGL_debug_renderer_info");if(e){const t=i.getParameter(e.UNMASKED_VENDOR_WEBGL),s=i.getParameter(e.UNMASKED_RENDERER_WEBGL);return this.hashString(`${t}|${s}`)}const s=i.getParameter(i.VERSION),n=i.getParameter(i.VENDOR);return this.hashString(`${s}|${n}`)}catch(t){return""}}generateDeviceId(t){return t.substring(0,32)}getManufacturer(){const t=navigator.userAgent.toLowerCase();if(t.includes("iphone")||t.includes("ipad"))return"Apple";if(t.includes("android")){const i=t.match(/(?:^|\s)([a-z]+)(?:\s|$)/);return i?i[1].charAt(0).toUpperCase()+i[1].slice(1):void 0}}getModel(){const t=navigator.userAgent.match(/(iPhone|iPad|Android)[\s\/]+([\w]+)/i);return t?t[2]:void 0}getBrand(){return this.getManufacturer()}getDevice(){const t=navigator.userAgent.toLowerCase();return t.includes("mobile")?"mobile":t.includes("tablet")?"tablet":"desktop"}getProduct(){const t=navigator.userAgent.match(/(iPhone|iPad|Android|Windows|Mac|Linux)/i);return t?t[1]:void 0}getHardware(){const t=navigator.userAgent.match(/\(([^)]+)\)/);return t?t[1]:void 0}getOSVersion(){const t=navigator.userAgent,i=[/OS\s+([\d_]+)/i,/Android\s+([\d.]+)/i,/Windows\s+([\d.]+)/i,/Mac\s+OS\s+X\s+([\d_]+)/i,/Linux/i];for(const e of i){const i=t.match(e);if(i)return i[1]?.replace(/_/g,".")||i[0]}}getScreenDensity(){if(window.devicePixelRatio)return String(window.devicePixelRatio)}hashString(t){return this.sha256LikeHash(t)}sha256LikeHash(t){const i=[];let e=5381;for(let i=0;i<t.length;i++)e=(e<<5)+e+t.charCodeAt(i),e&=4294967295;i.push(e);let s=0;for(let i=t.length-1;i>=0;i--)s=(s<<7)-s+t.charCodeAt(i),s&=4294967295;i.push(s);let n=0;for(let i=0;i<t.length;i++)n^=t.charCodeAt(i)<<i%4*8,n&=4294967295;i.push(n);let r=0;for(let i=0;i<t.length;i++)r=31*r+t.charCodeAt(i)&4294967295;i.push(r);let o=0;for(let i=0;i<t.length;i++){o=o+(4294967295&(t.charCodeAt(i)<<i%16|t.charCodeAt(i)>>>32-i%16))&4294967295}i.push(o);let a=2166136261;for(let i=0;i<t.length;i++)a=16777619*(a^t.charCodeAt(i)),a&=4294967295;i.push(a);let h=0;for(let i=0;i<t.length;i++)h=h+t.charCodeAt(i)*(i+1)&4294967295;i.push(h);let c=0;for(let i=0;i<t.length;i+=2){c=(c<<3)-c+(t.charCodeAt(i)+256*(t.charCodeAt(i+1)||0)),c&=4294967295}i.push(c);return i.map(t=>Math.abs(t).toString(16).padStart(8,"0")).join("").substring(0,64).padEnd(64,"0")}clearCache(){this.cachedDeviceInfo=null}}class s{constructor(t={}){this.featureVectors=[],this.pointerQueue=[],this.lastVelocity=0,this.lastAcceleration=0,this.lastAngle=0,this.lastPoint=null,this.secondLastPoint=null,this.rafId=null,this.maxSwipeVelocity=0,this.isActive=!1,this.clickCount=0,this.rightClickCount=0,this.doubleClickCount=0,this.totalMouseDistance=0,this.lastClickTime=0,this.scrollDistance=0,this.lastScrollTop=0,this.touchEventCount=0,this.mouseMoveHandler=t=>this.enqueuePoint(t,"move"),this.mouseDownHandler=t=>{this.enqueuePoint(t,"down"),this.handleClick(t)},this.mouseUpHandler=t=>this.enqueuePoint(t,"up"),this.contextMenuHandler=t=>this.handleRightClick(t),this.scrollHandler=()=>this.handleScroll(),this.touchStartHandler=()=>this.handleTouch(),this.touchMoveHandler=()=>this.handleTouch(),this.touchEndHandler=()=>this.handleTouch(),this.onEvent=t.onEvent,this.maskValue=t.maskValue??-1}start(){this.isActive||"undefined"==typeof document||(document.addEventListener("mousemove",this.mouseMoveHandler,{passive:!0}),document.addEventListener("mousedown",this.mouseDownHandler,{passive:!0}),document.addEventListener("mouseup",this.mouseUpHandler,{passive:!0}),document.addEventListener("contextmenu",this.contextMenuHandler,{passive:!0}),window.addEventListener("scroll",this.scrollHandler,{passive:!0}),document.addEventListener("touchstart",this.touchStartHandler,{passive:!0}),document.addEventListener("touchmove",this.touchMoveHandler,{passive:!0}),document.addEventListener("touchend",this.touchEndHandler,{passive:!0}),this.lastScrollTop=window.pageYOffset||document.documentElement.scrollTop,this.isActive=!0)}stop(){this.isActive&&"undefined"!=typeof document&&(document.removeEventListener("mousemove",this.mouseMoveHandler),document.removeEventListener("mousedown",this.mouseDownHandler),document.removeEventListener("mouseup",this.mouseUpHandler),document.removeEventListener("contextmenu",this.contextMenuHandler),window.removeEventListener("scroll",this.scrollHandler),document.removeEventListener("touchstart",this.touchStartHandler),document.removeEventListener("touchmove",this.touchMoveHandler),document.removeEventListener("touchend",this.touchEndHandler),null!==this.rafId&&(cancelAnimationFrame(this.rafId),this.rafId=null),this.isActive=!1)}getVectors(){return this.featureVectors}getSuspiciousSwipeVelocity(){return this.maxSwipeVelocity}getMouseSignals(){const t=this.featureVectors.length>0?this.featureVectors.reduce((t,i)=>t+i.velocity,0)/this.featureVectors.length:0,i=window.pageYOffset||document.documentElement.scrollTop,e=Math.abs(i-this.lastScrollTop),s=i>this.lastScrollTop?"down":"up";return{totalDistance:this.totalMouseDistance,averageVelocity:t,clickCount:this.clickCount,rightClickCount:this.rightClickCount,doubleClickCount:this.doubleClickCount,scrollDistance:this.scrollDistance+e,scrollDirection:s,touchEvents:this.touchEventCount}}reset(){this.featureVectors=[],this.pointerQueue=[],this.lastVelocity=0,this.lastAcceleration=0,this.lastAngle=0,this.lastPoint=null,this.secondLastPoint=null,this.maxSwipeVelocity=0,this.clickCount=0,this.rightClickCount=0,this.doubleClickCount=0,this.totalMouseDistance=0,this.lastClickTime=0,this.scrollDistance=0,this.lastScrollTop=0,this.touchEventCount=0}enqueuePoint(t,i){const e={x:t.clientX,y:t.clientY,timestamp:performance.now(),type:i};this.pointerQueue.push(e),this.pointerQueue.length>200&&this.pointerQueue.shift(),this.onEvent&&this.onEvent("move"===i?"mousemove":"down"===i?"mousedown":"mouseup"),this.scheduleProcess()}scheduleProcess(){null===this.rafId&&(this.rafId=requestAnimationFrame(()=>{this.rafId=null,this.processQueue(),this.pointerQueue.length>0&&this.scheduleProcess()}))}processQueue(){for(;this.pointerQueue.length>0;){const t=this.pointerQueue.shift();this.computeFeatures(t),this.secondLastPoint=this.lastPoint,this.lastPoint=t}}computeFeatures(t){if(!this.lastPoint)return this.lastPoint=t,void(this.lastAngle=0);const i=t.timestamp-this.lastPoint.timestamp;if(i<=0)return;const e=t.x-this.lastPoint.x,s=t.y-this.lastPoint.y,n=Math.sqrt(e*e+s*s);this.totalMouseDistance+=n;const r=n/i,o=(r-this.lastVelocity)/i,a=(o-this.lastAcceleration)/i,h=Math.atan2(s,e),c=this.normalizeAngle(h-this.lastAngle)/i,l=this.calculateCurvature(t);this.featureVectors.push({timestamp:t.timestamp,velocity:r,acceleration:o,jerk:a,curvature:l,angularVelocity:c}),this.maxSwipeVelocity=Math.max(this.maxSwipeVelocity,r),r>2.5&&this.featureVectors.push({timestamp:t.timestamp,velocity:r,acceleration:o,jerk:a,curvature:l,angularVelocity:1.2*c}),this.featureVectors.length>200&&this.featureVectors.splice(0,this.featureVectors.length-200),this.lastVelocity=r,this.lastAcceleration=o,this.lastAngle=h}calculateCurvature(t){if(!this.lastPoint||!this.secondLastPoint)return 0;const i=this.secondLastPoint,e=this.lastPoint,s=t,n=Math.hypot(s.x-i.x,s.y-i.y),r=Math.hypot(e.x-i.x,e.y-i.y)+Math.hypot(s.x-e.x,s.y-e.y);return 0===n?0:(r-n)/n}normalizeAngle(t){for(;t>Math.PI;)t-=2*Math.PI;for(;t<-Math.PI;)t+=2*Math.PI;return t}handleClick(t){const i=performance.now();i-this.lastClickTime<500?this.doubleClickCount++:this.clickCount++,this.lastClickTime=i}handleRightClick(t){this.rightClickCount++}handleScroll(){const t=window.pageYOffset||document.documentElement.scrollTop,i=Math.abs(t-this.lastScrollTop);this.scrollDistance+=i,this.lastScrollTop=t}handleTouch(){this.touchEventCount++}}class n{constructor(t={}){this.keyDownTimes=new Map,this.lastKeyUpTime=null,this.lastKeyDownTime=null,this.featureVectors=[],this.dwellTimes=[],this.flightTimes=[],this.digraphLatencies=[],this.isActive=!1,this.keydownCount=0,this.keyupCount=0,this.specialKeyCount=0,this.lastKeystrokeTime=null,this.pauseCount=0,this.PAUSE_THRESHOLD=2e3,this.keystrokeTimestamps=[],this.keyDownHandler=t=>this.handleKeyDown(t),this.keyUpHandler=t=>this.handleKeyUp(t),this.onEvent=t.onEvent}start(){this.isActive||"undefined"==typeof document||(document.addEventListener("keydown",this.keyDownHandler,{passive:!0,capture:!0}),document.addEventListener("keyup",this.keyUpHandler,{passive:!0,capture:!0}),this.isActive=!0)}stop(){this.isActive&&"undefined"!=typeof document&&(document.removeEventListener("keydown",this.keyDownHandler,!0),document.removeEventListener("keyup",this.keyUpHandler,!0),this.isActive=!1)}getVectors(){return this.featureVectors}getDwellTimes(t=50){return this.dwellTimes.slice(-t)}getFlightTimes(t=50){return this.flightTimes.slice(-t)}getKeyboardSignals(){let t=0;if(this.keystrokeTimestamps.length>1){const i=(this.keystrokeTimestamps[this.keystrokeTimestamps.length-1]-this.keystrokeTimestamps[0])/6e4;i>0&&(t=this.keystrokeTimestamps.length/i)}const i=this.keydownCount,e=i>0?this.getBackspaceCount()/i:0;return{keydownCount:this.keydownCount,keyupCount:this.keyupCount,specialKeyCount:this.specialKeyCount,typingSpeed:t,pauseCount:this.pauseCount,backspaceRatio:e}}getBackspaceCount(){return 0}reset(){this.keyDownTimes.clear(),this.lastKeyUpTime=null,this.lastKeyDownTime=null,this.featureVectors=[],this.dwellTimes=[],this.flightTimes=[],this.digraphLatencies=[],this.keydownCount=0,this.keyupCount=0,this.specialKeyCount=0,this.lastKeystrokeTime=null,this.pauseCount=0,this.keystrokeTimestamps=[]}handleKeyDown(t){if(!this.isTargetField(t))return;const i=performance.now();if(this.keydownCount++,this.keystrokeTimestamps.push(i),(t.ctrlKey||t.altKey||t.shiftKey||t.metaKey)&&this.specialKeyCount++,null!==this.lastKeystrokeTime&&i-this.lastKeystrokeTime>this.PAUSE_THRESHOLD&&this.pauseCount++,this.lastKeystrokeTime=i,null!==this.lastKeyUpTime){const t=i-this.lastKeyUpTime;this.flightTimes.push(t),this.appendVector({dwellTime:-1,flightTime:t,digraphLatency:-1,timestamp:i})}if(null!==this.lastKeyDownTime){const t=i-this.lastKeyDownTime;this.digraphLatencies.push(t),this.appendVector({dwellTime:-1,flightTime:-1,digraphLatency:t,timestamp:i})}this.lastKeyDownTime=i,this.keyDownTimes.set(t.code,i),this.onEvent&&this.onEvent("keydown")}handleKeyUp(t){if(!this.isTargetField(t))return;const i=performance.now();this.keyupCount++;const e=this.keyDownTimes.get(t.code);if(void 0!==e){const s=i-e;this.dwellTimes.push(s),this.appendVector({dwellTime:s,flightTime:-1,digraphLatency:-1,timestamp:i}),this.keyDownTimes.delete(t.code)}this.lastKeyUpTime=i,this.onEvent&&this.onEvent("keyup")}appendVector(t){this.featureVectors.push(t),this.featureVectors.length>200&&this.featureVectors.splice(0,this.featureVectors.length-200)}isTargetField(t){const i=t.target;if(!i)return!1;return i.isContentEditable||["INPUT","TEXTAREA"].includes(i.tagName)}}const r=-1,o=["velocity","acceleration","jerk","curvature","angularVelocity","dwell","flight","digraphLatency"];class a{constructor(){this.isActive=!1,this.sessionEvents=[],this.trackEvent=t=>{this.sessionEvents.push({type:t,timestamp:performance.now()}),this.sessionEvents.length>500&&this.sessionEvents.shift()},this.kinematicEngine=new s({onEvent:this.trackEvent}),this.keystrokeMonitor=new n({onEvent:this.trackEvent})}start(){this.isActive||(this.kinematicEngine.start(),this.keystrokeMonitor.start(),this.isActive=!0)}stop(){this.isActive&&(this.kinematicEngine.stop(),this.keystrokeMonitor.stop(),this.isActive=!1)}reset(){this.sessionEvents=[],this.kinematicEngine.reset(),this.keystrokeMonitor.reset()}getData(){const t=this.kinematicEngine.getVectors(),i=this.keystrokeMonitor.getVectors(),e=[...t.map(t=>({timestamp:t.timestamp,values:[t.velocity,t.acceleration,t.jerk,t.curvature,t.angularVelocity,r,r,r]})),...i.map(t=>({timestamp:t.timestamp,values:[r,r,r,r,r,t.dwellTime,t.flightTime,t.digraphLatency]}))].sort((t,i)=>t.timestamp-i.timestamp),s=this.buildSequence(e),n=this.kinematicEngine.getSuspiciousSwipeVelocity(),o=this.calculateSessionEntropy();return{typing_dwell_ms:this.keystrokeMonitor.getDwellTimes(),typing_flight_ms:this.keystrokeMonitor.getFlightTimes(),swipe_velocity:n,suspicious_swipe_velocity:n,session_entropy:o,behavioral_vectors:s}}buildSequence(t){const i=[],e=Math.max(0,t.length-50),s=t.slice(e);for(const t of s)i.push(t.values);for(;i.length<50;)i.unshift(new Array(o.length).fill(r));return{featureNames:[...o],windowSize:50,maskValue:r,sequence:i}}calculateSessionEntropy(){if(0===this.sessionEvents.length)return 0;const t={};this.sessionEvents.forEach(i=>{t[i.type]=(t[i.type]||0)+1});const i=this.sessionEvents.length;return Object.values(t).reduce((t,e)=>{const s=e/i;return s>0?t-s*Math.log2(s):t},0)}getMouseSignals(){return this.kinematicEngine.getMouseSignals()}getKeyboardSignals(){return this.keystrokeMonitor.getKeyboardSignals()}}class h{constructor(){this.cachedFingerprint=null}collect(){if(this.cachedFingerprint)return this.cachedFingerprint;const t=performance.now();try{const i=document.createElement("canvas");i.width=200,i.height=50;const e=i.getContext("2d");if(!e)return null;e.textBaseline="top",e.font="14px Arial",e.textBaseline="alphabetic",e.fillStyle="#f60",e.fillRect(125,1,62,20),e.fillStyle="#069",e.fillText("KeverdFingerprint",2,15),e.fillStyle="rgba(102, 204, 0, 0.7)",e.fillText("KeverdFingerprint",4,17);const s=e.createLinearGradient(0,0,200,50);s.addColorStop(0,"rgba(255, 0, 0, 0.5)"),s.addColorStop(1,"rgba(0, 0, 255, 0.5)"),e.fillStyle=s,e.fillRect(0,0,200,50),e.strokeStyle="#000",e.lineWidth=2,e.beginPath(),e.arc(100,25,20,0,2*Math.PI),e.stroke(),e.font="12px Verdana",e.fillStyle="#000",e.fillText("CanvasFP",150,30);const n=i.toDataURL(),r=this.hashString(n),o=performance.now()-t;return this.cachedFingerprint={value:r,duration:Math.round(100*o)/100},this.cachedFingerprint}catch(t){return null}}hashString(t){let i=0;for(let e=0;e<t.length;e++){i=(i<<5)-i+t.charCodeAt(e),i&=i}return Math.abs(i).toString(16).padStart(8,"0")}clearCache(){this.cachedFingerprint=null}}class c{constructor(){this.cachedFingerprint=null}collect(){if(this.cachedFingerprint)return this.cachedFingerprint;const t=performance.now();try{const i=document.createElement("canvas"),e=i.getContext("webgl")||i.getContext("experimental-webgl");if(!e)return null;const s=e.getExtension("WEBGL_debug_renderer_info");let n=null,r=null;s?(n=e.getParameter(s.UNMASKED_VENDOR_WEBGL)||null,r=e.getParameter(s.UNMASKED_RENDERER_WEBGL)||null):(n=e.getParameter(e.VENDOR)||null,r=e.getParameter(e.RENDERER)||null);const o=e.getParameter(e.VERSION)||null,a=e.getParameter(e.SHADING_LANGUAGE_VERSION)||null,h=[];try{const t=e.getSupportedExtensions();t&&h.push(...t)}catch(t){}const c={maxTextureSize:e.getParameter(e.MAX_TEXTURE_SIZE),maxVertexAttribs:e.getParameter(e.MAX_VERTEX_ATTRIBS),maxViewportDims:e.getParameter(e.MAX_VIEWPORT_DIMS),maxTextureImageUnits:e.getParameter(e.MAX_TEXTURE_IMAGE_UNITS),maxCombinedTextureImageUnits:e.getParameter(e.MAX_COMBINED_TEXTURE_IMAGE_UNITS),maxFragmentUniformVectors:e.getParameter(e.MAX_FRAGMENT_UNIFORM_VECTORS),maxVaryingVectors:e.getParameter(e.MAX_VARYING_VECTORS),aliasedLineWidthRange:e.getParameter(e.ALIASED_LINE_WIDTH_RANGE),aliasedPointSizeRange:e.getParameter(e.ALIASED_POINT_SIZE_RANGE)},l={};try{const t=e.createShader(e.VERTEX_SHADER);if(t){e.shaderSource(t,"precision mediump float;"),e.compileShader(t);const i=e.createShader(e.FRAGMENT_SHADER);i&&(e.shaderSource(i,"precision mediump float;"),e.compileShader(i),l.float=e.getShaderPrecisionFormat(e.FRAGMENT_SHADER,e.HIGH_FLOAT)?.precision?.toString()||"unknown",l.int=e.getShaderPrecisionFormat(e.FRAGMENT_SHADER,e.HIGH_INT)?.precision?.toString()||"unknown")}}catch(t){}const u=performance.now()-t;return this.cachedFingerprint={vendor:n,renderer:r,version:o,shadingLanguageVersion:a,extensions:h.sort(),parameters:c,precision:l,duration:Math.round(100*u)/100},this.cachedFingerprint}catch(t){return null}}clearCache(){this.cachedFingerprint=null}}class l{constructor(){this.cachedFingerprint=null}async collect(){if(this.cachedFingerprint)return this.cachedFingerprint;const t=performance.now();try{const i=window.AudioContext||window.webkitAudioContext||window.mozAudioContext;if(!i)return null;const e=new i,s=e.createOscillator(),n=e.createAnalyser(),r=e.createGain(),o=e.createScriptProcessor(4096,1,1);return n.fftSize=2048,n.smoothingTimeConstant=.8,s.connect(n),n.connect(o),o.connect(r),r.connect(e.destination),s.type="triangle",s.frequency.value=1e4,new Promise(i=>{const n=[];let a=0;o.onaudioprocess=r=>{const o=r.inputBuffer.getChannelData(0);let h=0;for(let t=0;t<o.length;t++)h+=o[t]*o[t];const c=Math.sqrt(h/o.length);if(n.push(c),a++,a>=5){s.stop(),e.close();const r=this.calculateFingerprint(n),o=performance.now()-t;this.cachedFingerprint={value:r,duration:Math.round(100*o)/100},i(this.cachedFingerprint)}},s.start(0),r.gain.value=0,setTimeout(()=>{if(!this.cachedFingerprint){s.stop(),e.close();const n=this.getFallbackFingerprint(e),r=performance.now()-t;this.cachedFingerprint={value:n,duration:Math.round(100*r)/100},i(this.cachedFingerprint)}},1e3)})}catch(t){return null}}calculateFingerprint(t){if(0===t.length)return 0;const i=t.reduce((t,i)=>t+i,0)/t.length,e=t.reduce((t,e)=>t+Math.pow(e-i,2),0)/t.length,s=Math.sqrt(e),n=1e6*i+1e3*s+t.length;return Math.round(100*n)/100}getFallbackFingerprint(t){const i=t.sampleRate||44100,e=t.state||"unknown",s=(i.toString()+e).split("").reduce((t,i)=>(t<<5)-t+i.charCodeAt(0),0);return Math.abs(s)}clearCache(){this.cachedFingerprint=null}}class u{constructor(){this.cachedFingerprint=null,this.testFonts=["Arial","Verdana","Times New Roman","Courier New","Georgia","Palatino","Garamond","Bookman","Comic Sans MS","Trebuchet MS","Arial Black","Impact","Tahoma","Lucida Console","Lucida Sans Unicode","MS Sans Serif","MS Serif","Symbol","Webdings","Wingdings","Monaco","Menlo","Consolas","Courier","Helvetica","Helvetica Neue","Roboto","Open Sans","Lato","Montserrat"]}collect(){if(this.cachedFingerprint)return this.cachedFingerprint;const t=performance.now();try{const i=document.createElement("canvas").getContext("2d");if(!i)return null;const e="monospace",s="mmmmmmmmmmlli",n="72px";i.font=`${n} ${e}`;const r=i.measureText(s).width,o=[],a=[];for(const t of this.testFonts){i.font=`${n} ${t}, ${e}`;const h=i.measureText(s).width;Math.abs(h-r)>1?o.push(t):a.push(t)}const h=performance.now()-t;return this.cachedFingerprint={availableFonts:o.sort(),missingFonts:a.sort(),duration:Math.round(100*h)/100},this.cachedFingerprint}catch(t){return null}}clearCache(){this.cachedFingerprint=null}}class d{constructor(){this.cachedFingerprint=null}async collect(){if(this.cachedFingerprint)return this.cachedFingerprint;const t=performance.now();try{if(!navigator.mediaDevices||!navigator.mediaDevices.enumerateDevices)return null;let i=!1;try{const t=await navigator.mediaDevices.getUserMedia({audio:!0,video:!1});i=!0,t.getTracks().forEach(t=>t.stop())}catch(t){i=!1}const e=await navigator.mediaDevices.enumerateDevices(),s=[],n=[],r=[];e.forEach(t=>{const e={deviceId:t.deviceId,kind:t.kind,label:i?t.label:"",groupId:t.groupId,toJSON:()=>({deviceId:t.deviceId,kind:t.kind,label:i?t.label:"",groupId:t.groupId})};switch(t.kind){case"audioinput":s.push(e);break;case"audiooutput":n.push(e);break;case"videoinput":r.push(e)}});const o=performance.now()-t;return this.cachedFingerprint={audioInputs:s,audioOutputs:n,videoInputs:r,hasPermission:i,duration:Math.round(100*o)/100},this.cachedFingerprint}catch(t){return null}}clearCache(){this.cachedFingerprint=null}}class m{constructor(){this.cachedFingerprint=null}collect(){if(this.cachedFingerprint)return this.cachedFingerprint;const t=performance.now(),i={width:screen.width,height:screen.height,availWidth:screen.availWidth,availHeight:screen.availHeight,colorDepth:screen.colorDepth,pixelDepth:screen.pixelDepth,pixelRatio:window.devicePixelRatio||1,orientation:this.getOrientation(),orientationAngle:this.getOrientationAngle(),duration:0};return i.duration=Math.round(100*(performance.now()-t))/100,this.cachedFingerprint=i,i}getOrientation(){if("orientation"in screen){const t=screen.orientation;if(t&&t.type)return t.type}if("orientation"in window){const t=window.orientation;if(void 0!==t){if(0===t||180===t)return"portrait";if(90===t||-90===t)return"landscape"}}if(window.matchMedia){if(window.matchMedia("(orientation: portrait)").matches)return"portrait";if(window.matchMedia("(orientation: landscape)").matches)return"landscape"}return null}getOrientationAngle(){if("orientation"in screen){const t=screen.orientation;if(t&&"number"==typeof t.angle)return t.angle}if("orientation"in window){const t=window.orientation;if("number"==typeof t)return t}return null}clearCache(){this.cachedFingerprint=null}}class p{constructor(){this.cachedFingerprint=null}collect(){if(this.cachedFingerprint)return this.cachedFingerprint;const t=performance.now(),i=Intl.DateTimeFormat().resolvedOptions().timeZone,e=(new Date).getTimezoneOffset(),s=Intl.DateTimeFormat().resolvedOptions(),n=s.locale,r=navigator.languages||[navigator.language],o=this.getDateFormat(),a=this.getTimeFormat(),h=this.getNumberFormat(),c=s.calendar||null,l={timezone:i,timezoneOffset:e,locale:n,locales:r.slice(0,5),dateFormat:o,timeFormat:a,numberFormat:h,calendar:c,duration:0};return l.duration=Math.round(100*(performance.now()-t))/100,this.cachedFingerprint=l,l}getDateFormat(){try{const t=(new Intl.DateTimeFormat).format(new Date(2023,0,15));return t.includes("/")?"numeric":t.includes("-")?"iso":t.includes(".")?"european":"unknown"}catch{return"unknown"}}getTimeFormat(){try{const t=new Intl.DateTimeFormat(void 0,{hour:"numeric",minute:"numeric"}).format(new Date(2023,0,15,13,30));return t.toLowerCase().includes("am")||t.toLowerCase().includes("pm")?"12h":"24h"}catch{return"unknown"}}getNumberFormat(){try{const t=(new Intl.NumberFormat).format(1234.56);return t.includes(",")?"european":t.includes(".")?"american":"unknown"}catch{return"unknown"}}clearCache(){this.cachedFingerprint=null}}class g{constructor(){this.cachedFingerprint=null}collect(){if(this.cachedFingerprint)return this.cachedFingerprint;const t=performance.now();try{if(!navigator.plugins||0===navigator.plugins.length)return null;const i=[],e=new Set;for(let t=0;t<Math.min(navigator.plugins.length,10);t++){const s=navigator.plugins[t];if(!s)continue;const n=[];for(let t=0;t<Math.min(s.length,5);t++){const i=s[t];i&&i.type&&(n.push(i.type),e.add(i.type))}i.push({name:s.name||"Unknown",description:s.description||"",mimeTypes:n})}const s={plugins:i,mimeTypes:Array.from(e).sort(),duration:0};return s.duration=Math.round(100*(performance.now()-t))/100,this.cachedFingerprint=s,s}catch(t){return null}}clearCache(){this.cachedFingerprint=null}}class w{constructor(){this.cachedFingerprint=null}async collect(){if(this.cachedFingerprint)return this.cachedFingerprint;const t=performance.now();try{const i=await this.getBatteryManager();if(!i)return null;const e={level:i.level,charging:i.charging,chargingTime:i.chargingTime,dischargingTime:i.dischargingTime,duration:0};return e.duration=Math.round(100*(performance.now()-t))/100,this.cachedFingerprint=e,e}catch(t){return null}}async getBatteryManager(){if("getBattery"in navigator)try{return await navigator.getBattery()}catch(t){}if("webkitGetBattery"in navigator)try{return await navigator.webkitGetBattery()}catch(t){}if("mozGetBattery"in navigator)try{return await navigator.mozGetBattery()}catch(t){}return null}clearCache(){this.cachedFingerprint=null}}class f{constructor(){this.cachedFingerprint=null}async collect(){if(this.cachedFingerprint)return this.cachedFingerprint;const t=performance.now(),i={localStorage:await this.checkLocalStorage(),sessionStorage:await this.checkSessionStorage(),indexedDB:this.checkIndexedDB(),webSQL:this.checkWebSQL(),duration:0};return i.duration=Math.round(100*(performance.now()-t))/100,this.cachedFingerprint=i,i}async checkLocalStorage(){let t=!1,i=null,e=null;try{const s="__localStorage_test__";if(localStorage.setItem(s,s),localStorage.removeItem(s),t=!0,"storage"in navigator&&"estimate"in navigator.storage)try{const t=await navigator.storage.estimate();t&&(i=t.quota||null,e=t.usage||null)}catch(t){}}catch(i){t=!1}return{available:t,quota:i,usage:e}}async checkSessionStorage(){let t=!1,i=null,e=null;try{const s="__sessionStorage_test__";if(sessionStorage.setItem(s,s),sessionStorage.removeItem(s),t=!0,"storage"in navigator&&"estimate"in navigator.storage)try{const t=await navigator.storage.estimate();t&&(i=t.quota||null,e=t.usage||null)}catch(t){}}catch(i){t=!1}return{available:t,quota:i,usage:e}}checkIndexedDB(){return{available:"indexedDB"in window&&!!window.indexedDB}}checkWebSQL(){return{available:"openDatabase"in window&&!!window.openDatabase}}clearCache(){this.cachedFingerprint=null}}class v{constructor(){this.cachedFingerprint=null}collect(){if(this.cachedFingerprint)return this.cachedFingerprint;const t=performance.now(),i={hardwareConcurrency:navigator.hardwareConcurrency||0,deviceMemory:this.getDeviceMemory(),performanceMemory:this.getPerformanceMemory(),duration:0};return i.duration=Math.round(100*(performance.now()-t))/100,this.cachedFingerprint=i,i}getDeviceMemory(){return"deviceMemory"in navigator&&navigator.deviceMemory?navigator.deviceMemory:null}getPerformanceMemory(){if("memory"in performance){const t=performance.memory;return{jsHeapSizeLimit:t.jsHeapSizeLimit||null,totalJSHeapSize:t.totalJSHeapSize||null,usedJSHeapSize:t.usedJSHeapSize||null}}return{jsHeapSizeLimit:null,totalJSHeapSize:null,usedJSHeapSize:null}}clearCache(){this.cachedFingerprint=null}}class y{constructor(){this.cachedFingerprint=null}collect(){if(this.cachedFingerprint)return this.cachedFingerprint;const t=performance.now(),i={maxTouchPoints:navigator.maxTouchPoints||0,touchSupport:this.checkTouchSupport(),pointerSupport:this.checkPointerSupport(),pointerTypes:this.getPointerTypes(),duration:0};return i.duration=Math.round(100*(performance.now()-t))/100,this.cachedFingerprint=i,i}checkTouchSupport(){return"ontouchstart"in window||navigator.maxTouchPoints>0||!!window.DocumentTouch&&document instanceof window.DocumentTouch}checkPointerSupport(){return"PointerEvent"in window||"MSPointerEvent"in window}getPointerTypes(){const t=[];return"PointerEvent"in window&&(navigator.maxTouchPoints>0&&t.push("touch"),t.push("mouse"),"pen"in navigator&&t.push("pen")),t}clearCache(){this.cachedFingerprint=null}}class S{constructor(){this.cachedFingerprint=null}async collect(){if(this.cachedFingerprint)return this.cachedFingerprint;const t=performance.now();try{if(!("permissions"in navigator))return null;const i=navigator.permissions,e={camera:await this.queryPermission(i,"camera"),microphone:await this.queryPermission(i,"microphone"),notifications:await this.queryPermission(i,"notifications"),geolocation:await this.queryPermission(i,"geolocation"),persistentStorage:await this.queryPermission(i,"persistent-storage"),duration:0};return e.duration=Math.round(100*(performance.now()-t))/100,this.cachedFingerprint=e,e}catch(t){return null}}async queryPermission(t,i){try{return(await t.query({name:i})).state||null}catch(t){return null}}clearCache(){this.cachedFingerprint=null}}class b{constructor(){this.cachedFingerprint=null}async collect(){if(this.cachedFingerprint)return this.cachedFingerprint;const t=performance.now();try{const i=window.RTCPeerConnection||window.webkitRTCPeerConnection||window.mozRTCPeerConnection;if(!i)return null;const e=[];let s=null;const n=new i({iceServers:[{urls:"stun:stun.l.google.com:19302"}]});n.onicecandidate=t=>{if(t.candidate){const i=t.candidate.candidate.match(/([0-9]{1,3}\.){3}[0-9]{1,3}/);if(i){const t=i[0];this.isLocalIP(t)?e.includes(t)||e.push(t):s=t}}},n.createDataChannel("");const r=await n.createOffer();await n.setLocalDescription(r),await new Promise(t=>{const i=setTimeout(()=>{t()},2e3);n.onicegatheringstatechange=()=>{"complete"===n.iceGatheringState&&(clearTimeout(i),t())},"complete"===n.iceGatheringState&&(clearTimeout(i),t())}),n.close();const o={localIPs:e.sort(),publicIP:s,duration:0};return o.duration=Math.round(100*(performance.now()-t))/100,this.cachedFingerprint=o,o}catch(t){return null}}isLocalIP(t){if("127.0.0.1"===t||"::1"===t)return!0;const i=t.split(".");if(4===i.length){const t=parseInt(i[0],10),e=parseInt(i[1],10);if(10===t)return!0;if(172===t&&e>=16&&e<=31)return!0;if(192===t&&168===e)return!0;if(169===t&&254===e)return!0}return!1}clearCache(){this.cachedFingerprint=null}}class C{generate(t){const i=[];t.canvas?.value&&i.push(`canvas:${t.canvas.value}`),t.webgl&&(t.webgl.vendor&&i.push(`webgl_vendor:${t.webgl.vendor}`),t.webgl.renderer&&i.push(`webgl_renderer:${t.webgl.renderer}`),t.webgl.extensions.length>0&&i.push(`webgl_ext:${t.webgl.extensions.slice(0,10).join(",")}`)),t.audio?.value&&i.push(`audio:${t.audio.value}`),t.screen&&(i.push(`screen:${t.screen.width}x${t.screen.height}x${t.screen.pixelRatio}`),i.push(`color:${t.screen.colorDepth}`)),t.timezone&&(i.push(`tz:${t.timezone.timezone}`),i.push(`locale:${t.timezone.locale}`)),t.cpu&&(i.push(`cpu:${t.cpu.hardwareConcurrency}`),t.cpu.deviceMemory&&i.push(`memory:${t.cpu.deviceMemory}`)),t.touch&&i.push(`touch:${t.touch.maxTouchPoints}`),i.push(`ua:${navigator.userAgent}`),i.push(`lang:${navigator.language}`),i.push(`platform:${navigator.platform}`),t.fonts&&t.fonts.availableFonts.length>0&&i.push(`fonts:${t.fonts.availableFonts.slice(0,20).join(",")}`);const e=i.join("|");return this.sha256Hash(e)}calculateConfidence(t){let i=0,e=0;const s={canvas:20,webgl:20,audio:15,screen:10,timezone:10,cpu:10,fonts:10,touch:5,storage:5,permissions:5,webrtc:5,mediaDevices:5,battery:3,plugins:3};return Object.keys(s).forEach(n=>{e+=s[n],t[n]&&(i+=s[n])}),e>0?Math.min(i/e,1):0}sha256Hash(t){return"undefined"!=typeof crypto&&crypto.subtle,this.sha256LikeHash(t)}sha256LikeHash(t){const i=[];let e=5381;for(let i=0;i<t.length;i++)e=(e<<5)+e+t.charCodeAt(i),e&=4294967295;i.push(e);let s=0;for(let i=t.length-1;i>=0;i--)s=(s<<7)-s+t.charCodeAt(i),s&=4294967295;i.push(s);let n=0;for(let i=0;i<t.length;i++)n^=t.charCodeAt(i)<<i%4*8,n&=4294967295;i.push(n);let r=0;for(let i=0;i<t.length;i++)r=31*r+t.charCodeAt(i)&4294967295;i.push(r);let o=0;for(let i=0;i<t.length;i++){o=o+(4294967295&(t.charCodeAt(i)<<i%16|t.charCodeAt(i)>>>32-i%16))&4294967295}i.push(o);let a=2166136261;for(let i=0;i<t.length;i++)a=16777619*(a^t.charCodeAt(i)),a&=4294967295;i.push(a);let h=0;for(let i=0;i<t.length;i++)h=h+t.charCodeAt(i)*(i+1)&4294967295;i.push(h);let c=0;for(let i=0;i<t.length;i+=2){c=(c<<3)-c+(t.charCodeAt(i)+256*(t.charCodeAt(i+1)||0)),c&=4294967295}i.push(c);return i.map(t=>Math.abs(t).toString(16).padStart(8,"0")).join("").substring(0,64).padEnd(64,"0")}}class k{constructor(){this.cachedData=null,this.collectionStartTime=0,this.collectors={canvas:new h,webgl:new c,audio:new l,fonts:new u,mediaDevices:new d,screen:new m,timezone:new p,plugins:new g,battery:new w,storage:new f,cpu:new v,touch:new y,permissions:new S,webrtc:new b},this.visitorIDGenerator=new C}async collect(){if(this.cachedData)return this.cachedData;this.collectionStartTime=performance.now();const t={};try{t.canvas=this.collectors.canvas.collect()||void 0}catch(t){}try{t.webgl=this.collectors.webgl.collect()||void 0}catch(t){}try{t.fonts=this.collectors.fonts.collect()||void 0}catch(t){}try{t.screen=this.collectors.screen.collect()}catch(t){}try{t.timezone=this.collectors.timezone.collect()}catch(t){}try{t.plugins=this.collectors.plugins.collect()||void 0}catch(t){}try{t.cpu=this.collectors.cpu.collect()}catch(t){}try{t.touch=this.collectors.touch.collect()}catch(t){}try{t.audio=await this.collectors.audio.collect()||void 0}catch(t){}try{t.mediaDevices=await this.collectors.mediaDevices.collect()||void 0}catch(t){}try{t.battery=await this.collectors.battery.collect()||void 0}catch(t){}try{t.storage=await this.collectors.storage.collect()}catch(t){}try{t.permissions=await this.collectors.permissions.collect()||void 0}catch(t){}try{t.webrtc=await this.collectors.webrtc.collect()||void 0}catch(t){}const i=this.visitorIDGenerator.generate(t),e=this.visitorIDGenerator.calculateConfidence(t);return this.cachedData={visitorId:i,confidence:Math.round(1e3*e)/1e3,components:t,version:"1.0.0",timestamp:Date.now()},this.cachedData}async getVisitorId(){return(await this.collect()).visitorId}clearCache(){this.cachedData=null,Object.values(this.collectors).forEach(t=>{t&&"function"==typeof t.clearCache&&t.clearCache()})}getStats(){if(!this.cachedData)return{componentsCollected:0,totalComponents:13,collectionTime:0};const t=Object.keys(this.cachedData.components).length,i=performance.now()-this.collectionStartTime;return{componentsCollected:t,totalComponents:13,collectionTime:Math.round(100*i)/100}}}class M{constructor(){this.cachedSignals=null}collect(){if(this.cachedSignals)return this.cachedSignals;const t={isIncognito:this.detectIncognito(),isVPN:!1,isAutomated:this.detectAutomation(),hasAdBlocker:this.detectAdBlocker()};return this.cachedSignals=t,t}detectIncognito(){try{if("storage"in navigator&&"estimate"in navigator.storage)try{navigator.storage.estimate().then(()=>{}).catch(()=>{})}catch{return!0}if("storage"in navigator&&navigator.storage,navigator,window.chrome&&window.chrome.runtime&&!window.chrome.runtime.onConnect)return!0;try{const t="__incognito_test__";localStorage.setItem(t,"test"),localStorage.removeItem(t)}catch{return!0}return!1}catch(t){return!1}}detectAutomation(){try{if(!0===navigator.webdriver)return!0;if(window.chrome&&window.chrome.runtime&&window.chrome.runtime.onConnect){if(window.chrome.runtime.onConnect.hasListeners())return!0}if(!(window.chrome||window.safari||window.Notification&&window.DeviceMotionEvent))return!0;try{const t=document.createElement("canvas"),i=t.getContext("2d");if(i){i.textBaseline="top",i.font="14px Arial",i.fillText("Automation test",2,2);if(t.toDataURL().length<100)return!0}}catch{}return!!(window.__nightmare||window.__phantomas||window.Buffer)}catch(t){return!1}}detectAdBlocker(){try{const t=document.createElement("div");t.innerHTML=" ",t.className="adsbox",t.style.position="absolute",t.style.left="-9999px",document.body.appendChild(t),setTimeout(()=>{const i=0===t.offsetHeight||0===t.offsetWidth;return document.body.removeChild(t),i},100);const i=Array.from(document.getElementsByTagName("script"));return i.filter(t=>t.src&&t.src.includes("ads")&&!t.textContent).length>0||!!(window.uBlock||window.adblock||window.BlockAdBlock)}catch(t){return!1}}clearCache(){this.cachedSignals=null}}class T{constructor(){this.cachedCapabilities=null}collect(){if(this.cachedCapabilities)return this.cachedCapabilities;const t={hasWebGL:this.checkWebGL(),hasCanvas:this.checkCanvas(),hasWebRTC:this.checkWebRTC(),hasServiceWorker:this.checkServiceWorker(),hasIndexedDB:this.checkIndexedDB(),hasLocalStorage:this.checkLocalStorage(),hasSessionStorage:this.checkSessionStorage(),cookieEnabled:navigator.cookieEnabled,doNotTrack:"1"===navigator.doNotTrack||"yes"===navigator.doNotTrack};return this.cachedCapabilities=t,t}checkWebGL(){try{const t=document.createElement("canvas");return!(!t.getContext("webgl")&&!t.getContext("experimental-webgl"))}catch{return!1}}checkCanvas(){try{return!!document.createElement("canvas").getContext("2d")}catch{return!1}}checkWebRTC(){return!!((window.RTCPeerConnection||window.webkitRTCPeerConnection||window.mozRTCPeerConnection)&&navigator.mediaDevices&&navigator.mediaDevices.getUserMedia)}checkServiceWorker(){return"serviceWorker"in navigator}checkIndexedDB(){return"indexedDB"in window}checkLocalStorage(){try{const t="__localStorage_test__";return localStorage.setItem(t,t),localStorage.removeItem(t),!0}catch{return!1}}checkSessionStorage(){try{const t="__sessionStorage_test__";return sessionStorage.setItem(t,t),sessionStorage.removeItem(t),!0}catch{return!1}}clearCache(){this.cachedCapabilities=null}}class D{constructor(){this.cachedSignals=null}collect(){if(this.cachedSignals)return this.cachedSignals;const t={hardwareConcurrency:navigator.hardwareConcurrency||0,deviceMemory:this.getDeviceMemory(),maxTouchPoints:navigator.maxTouchPoints||0,connectionType:this.getConnectionType(),effectiveType:this.getEffectiveType(),downlink:this.getDownlink(),rtt:this.getRTT(),saveData:this.getSaveData()};return this.cachedSignals=t,t}getDeviceMemory(){return"deviceMemory"in navigator&&navigator.deviceMemory?navigator.deviceMemory:null}getConnectionType(){const t=navigator.connection||navigator.mozConnection||navigator.webkitConnection;return t&&t.type?t.type:null}getEffectiveType(){const t=navigator.connection||navigator.mozConnection||navigator.webkitConnection;return t&&t.effectiveType?t.effectiveType:null}getDownlink(){const t=navigator.connection||navigator.mozConnection||navigator.webkitConnection;return t&&t.downlink?t.downlink:null}getRTT(){const t=navigator.connection||navigator.mozConnection||navigator.webkitConnection;return t&&t.rtt?t.rtt:null}getSaveData(){const t=navigator.connection||navigator.mozConnection||navigator.webkitConnection;return t&&void 0!==t.saveData?t.saveData:null}clearCache(){this.cachedSignals=null}}class _{constructor(){this.focusCount=0,this.blurCount=0,this.copyCount=0,this.pasteCount=0,this.cutCount=0,this.fieldFocusOrder=[],this.fieldFocusTimes=new Map,this.backspaceCount=0,this.deleteCount=0,this.autofillDetected=!1,this.autocompleteDetected=!1,this.isActive=!1,this.focusHandler=t=>this.handleFocus(t),this.blurHandler=t=>this.handleBlur(t),this.copyHandler=t=>this.handleCopy(t),this.pasteHandler=t=>this.handlePaste(t),this.cutHandler=t=>this.handleCut(t),this.keydownHandler=t=>this.handleKeyDown(t),this.inputHandler=t=>this.handleInput(t)}start(){this.isActive||"undefined"==typeof document||(document.addEventListener("focus",this.focusHandler,!0),document.addEventListener("blur",this.blurHandler,!0),document.addEventListener("copy",this.copyHandler,!0),document.addEventListener("paste",this.pasteHandler,!0),document.addEventListener("cut",this.cutHandler,!0),document.addEventListener("keydown",this.keydownHandler,!0),document.addEventListener("input",this.inputHandler,!0),this.isActive=!0)}stop(){this.isActive&&"undefined"!=typeof document&&(document.removeEventListener("focus",this.focusHandler,!0),document.removeEventListener("blur",this.blurHandler,!0),document.removeEventListener("copy",this.copyHandler,!0),document.removeEventListener("paste",this.pasteHandler,!0),document.removeEventListener("cut",this.cutHandler,!0),document.removeEventListener("keydown",this.keydownHandler,!0),document.removeEventListener("input",this.inputHandler,!0),this.isActive=!1)}getData(){const t={};return this.fieldFocusTimes.forEach((i,e)=>{t[e]=i}),{focusCount:this.focusCount,blurCount:this.blurCount,copyCount:this.copyCount,pasteCount:this.pasteCount,cutCount:this.cutCount,autofillDetected:this.autofillDetected,autocompleteDetected:this.autocompleteDetected,fieldFocusOrder:[...this.fieldFocusOrder],timePerField:t,backspaceCount:this.backspaceCount,deleteCount:this.deleteCount}}reset(){this.focusCount=0,this.blurCount=0,this.copyCount=0,this.pasteCount=0,this.cutCount=0,this.fieldFocusOrder=[],this.fieldFocusTimes.clear(),this.backspaceCount=0,this.deleteCount=0,this.autofillDetected=!1,this.autocompleteDetected=!1}handleFocus(t){const i=t.target;if(!this.isFormField(i))return;this.focusCount++;const e=this.getFieldId(i);e&&!this.fieldFocusOrder.includes(e)&&this.fieldFocusOrder.push(e),this.fieldFocusTimes.set(e||"unknown",Date.now())}handleBlur(t){const i=t.target;if(!this.isFormField(i))return;this.blurCount++;const e=this.getFieldId(i);if(e){const t=this.fieldFocusTimes.get(e)||Date.now(),i=Date.now()-t;this.fieldFocusTimes.set(e,i)}}handleCopy(t){const i=t.target;this.isFormField(i)&&this.copyCount++}handlePaste(t){const i=t.target;this.isFormField(i)&&this.pasteCount++}handleCut(t){const i=t.target;this.isFormField(i)&&this.cutCount++}handleKeyDown(t){const i=t.target;this.isFormField(i)&&("Backspace"===t.key?this.backspaceCount++:"Delete"===t.key&&this.deleteCount++)}handleInput(t){const i=t.target;if(!this.isFormField(i))return;i.value&&"password"===i.type&&(this.autofillDetected=!0),i.hasAttribute("autocomplete")&&"off"!==i.getAttribute("autocomplete")&&(this.autocompleteDetected=!0)}isFormField(t){if(!t)return!1;const i=t.tagName.toLowerCase();return"input"===i||"textarea"===i||"select"===i||t.isContentEditable}getFieldId(t){return t.id?t.id:"name"in t&&t.name?t.name:t.getAttribute("data-field-id")?t.getAttribute("data-field-id"):null}}class ${constructor(){this.pageLoadTime=0,this.timeToFirstInteraction=0,this.startTime=Date.now(),this.firstInteractionTime=null,this.maxScrollDepth=0,this.clickCount=0,this.linkClickCount=0,this.imageViewCount=0,this.videoPlayCount=0,this.isActive=!1,this.clickHandler=t=>this.handleClick(t),this.scrollHandler=()=>this.handleScroll(),this.loadHandler=()=>this.handleLoad(),this.imageLoadHandler=()=>this.handleImageLoad(),this.videoPlayHandler=()=>this.handleVideoPlay(),this.startTime=performance.now()}start(){this.isActive||"undefined"==typeof document||("complete"===document.readyState?this.pageLoadTime=performance.now()-this.startTime:window.addEventListener("load",this.loadHandler),document.addEventListener("click",this.clickHandler,!0),window.addEventListener("scroll",this.scrollHandler,{passive:!0}),document.addEventListener("load",this.imageLoadHandler,!0),document.addEventListener("play",this.videoPlayHandler,!0),this.isActive=!0)}stop(){this.isActive&&"undefined"!=typeof document&&(window.removeEventListener("load",this.loadHandler),document.removeEventListener("click",this.clickHandler,!0),window.removeEventListener("scroll",this.scrollHandler),document.removeEventListener("load",this.imageLoadHandler,!0),document.removeEventListener("play",this.videoPlayHandler,!0),this.isActive=!1)}getData(){const t=Date.now()-this.startTime,i=this.calculateScrollDepth();return{pageLoadTime:this.pageLoadTime,timeToFirstInteraction:this.firstInteractionTime?this.firstInteractionTime-this.startTime:0,timeOnPage:t,scrollDepth:i,clickCount:this.clickCount,linkClickCount:this.linkClickCount,imageViewCount:this.imageViewCount,videoPlayCount:this.videoPlayCount}}reset(){this.pageLoadTime=0,this.timeToFirstInteraction=0,this.startTime=Date.now(),this.firstInteractionTime=null,this.maxScrollDepth=0,this.clickCount=0,this.linkClickCount=0,this.imageViewCount=0,this.videoPlayCount=0}handleLoad(){this.pageLoadTime=performance.now()-this.startTime}handleClick(t){this.firstInteractionTime||(this.firstInteractionTime=performance.now()),this.clickCount++;const i=t.target;("a"===i.tagName.toLowerCase()||i.closest("a"))&&this.linkClickCount++}handleScroll(){const t=this.calculateScrollDepth();this.maxScrollDepth=Math.max(this.maxScrollDepth,t)}handleImageLoad(){this.imageViewCount++}handleVideoPlay(){this.videoPlayCount++}calculateScrollDepth(){if("undefined"==typeof window||"undefined"==typeof document)return 0;const t=window.innerHeight||document.documentElement.clientHeight,i=Math.max(document.body.scrollHeight,document.body.offsetHeight,document.documentElement.clientHeight,document.documentElement.scrollHeight,document.documentElement.offsetHeight),e=window.pageYOffset||document.documentElement.scrollTop;if(0===i)return 0;const s=e+t;return Math.min(s/i,1)}}const I="https://api.keverd.com";class x{constructor(){this.config=null,this.isInitialized=!1,this.sessionId=null,this.ghostInterval=null,this.ghostStartTime=null,this.ghostSignalCount=0,this.MIN_GHOST_SIGNALS=10,this.MAX_GHOST_COLLECTION_TIME=6e5,this.deviceCollector=new e,this.behavioralCollector=new a,this.fingerprintManager=new k,this.privacySignalCollector=new M,this.browserCapabilityCollector=new T,this.hardwareSignalCollector=new D,this.formInteractionCollector=new _,this.pageInteractionCollector=new $}init(t){this.isInitialized?this.config:(this.config="string"==typeof t?{apiKey:t,debug:!1}:{debug:!1,...t},this.behavioralCollector.start(),this.formInteractionCollector.start(),this.pageInteractionCollector.start(),this.sessionId=this.generateSessionId(),this.isInitialized=!0,this.config.debug,this.startSession().catch(()=>{}),this.startGhostSignalCollection())}startGhostSignalCollection(){if(this.ghostInterval)return;if(!this.config)return;this.ghostStartTime=Date.now(),this.ghostSignalCount=0;const t=3e4,i=()=>{const i=Date.now(),e=this.ghostStartTime?i-this.ghostStartTime:0,s=this.ghostSignalCount>=this.MIN_GHOST_SIGNALS,n=e>=this.MAX_GHOST_COLLECTION_TIME;if(s||n)return this.config,void this.stopGhostSignalCollection();const r=this.ghostStartTime?i-this.ghostStartTime:t;this.sendGhostSignals(r).catch(t=>{this.config}),this.ghostSignalCount++,this.ghostStartTime=i};setTimeout(()=>{i(),this.ghostInterval=setInterval(()=>{i()},t)},t)}stopGhostSignalCollection(){this.ghostInterval&&(clearInterval(this.ghostInterval),this.ghostInterval=null,this.ghostStartTime=null)}async sendGhostSignals(t){if(!this.isInitialized||!this.config)return;const i=this.deviceCollector.collect(),e=this.behavioralCollector.getData(),s=await this.fingerprintManager.collect(),n={visitorId:s.visitorId,confidence:s.confidence,components:s.components},r=this.privacySignalCollector.collect(),o=this.browserCapabilityCollector.collect(),a=this.hardwareSignalCollector.collect(),h=this.formInteractionCollector.getData(),c=this.behavioralCollector.getMouseSignals(),l=this.behavioralCollector.getKeyboardSignals(),u=this.pageInteractionCollector.getData(),d={connectionType:a.connectionType||void 0,effectiveType:a.effectiveType||void 0,downlink:a.downlink||void 0,rtt:a.rtt||void 0,saveData:a.saveData||void 0},m={sessionId:this.sessionId||void 0,timestamp:(new Date).toISOString()},p={userId:this.config.userId,device:i,session:m,behavioral:e,duration_ms:t,fingerprintjs:n||void 0,privacySignals:r,browserCapabilities:o,hardwareSignals:a,formInteractions:h,mouseSignals:c,keyboardSignals:l,pageInteractions:u,networkSignals:d,useCase:"ghost"},g=`${I}/fingerprint/ghost`,w={"Content-Type":"application/json","X-SDK-Source":"javascript"},f=this.config.apiKey;f&&(w["x-keverd-key"]=f,w["X-API-KEY"]=f,w.Authorization=`Bearer ${f}`),await fetch(g,{method:"POST",headers:w,body:JSON.stringify(p)}).catch(()=>{})}async getVisitorData(){if(!this.isInitialized||!this.config)throw new Error("Keverd SDK not initialized. Call init() first.");try{const t=this.deviceCollector.collect(),i=this.behavioralCollector.getData(),e=await this.fingerprintManager.collect(),s={visitorId:e.visitorId,confidence:e.confidence,components:e.components},n=this.privacySignalCollector.collect(),r=this.browserCapabilityCollector.collect(),o=this.hardwareSignalCollector.collect(),a=this.formInteractionCollector.getData(),h=this.behavioralCollector.getMouseSignals(),c=this.behavioralCollector.getKeyboardSignals(),l=this.pageInteractionCollector.getData(),u={connectionType:o.connectionType||void 0,effectiveType:o.effectiveType||void 0,downlink:o.downlink||void 0,rtt:o.rtt||void 0,saveData:o.saveData||void 0},d={sessionId:this.sessionId||void 0,timestamp:(new Date).toISOString()},m={userId:this.config.userId,device:t,session:d,behavioral:i,fingerprintjs:s||void 0,privacySignals:n,browserCapabilities:r,hardwareSignals:o,formInteractions:a,mouseSignals:h,keyboardSignals:c,pageInteractions:l,networkSignals:u,useCase:"general"};return await this.sendFingerprintRequest(m)}catch(t){const i=t instanceof Error?t.message:"Unknown error";throw this.config.debug,new Error(`Failed to get visitor data: ${i}`)}}async createTransactionID(t){return(await this.getVisitorData()).session_id}async verifyLogin(t,i){if(!this.isInitialized||!this.config)throw new Error("Keverd SDK not initialized. Call init() first.");return await this.sendVerifyRequest("login",{userId:t,metadata:i})}async verifyCheckout(t,i,e){if(!this.isInitialized||!this.config)throw new Error("Keverd SDK not initialized. Call init() first.");return await this.sendVerifyRequest("checkout",{amount:t,currency:i,metadata:e})}async verifyRegistration(t){if(!this.isInitialized||!this.config)throw new Error("Keverd SDK not initialized. Call init() first.");return await this.sendVerifyRequest("registration",{metadata:t})}async verifyPasswordReset(t,i){if(!this.isInitialized||!this.config)throw new Error("Keverd SDK not initialized. Call init() first.");return await this.sendVerifyRequest("password_reset",{email:t,metadata:i})}async verifyAccountChange(t,i){if(!this.isInitialized||!this.config)throw new Error("Keverd SDK not initialized. Call init() first.");return await this.sendVerifyRequest("account_change",{changeType:t,metadata:i})}async sendVerifyRequest(t,i){if(!this.config)throw new Error("SDK not initialized");const e=this.deviceCollector.collect(),s=this.behavioralCollector.getData(),n=await this.fingerprintManager.collect(),r={visitorId:n.visitorId,confidence:n.confidence,components:n.components},o=this.privacySignalCollector.collect(),a=this.browserCapabilityCollector.collect(),h=this.hardwareSignalCollector.collect(),c=this.formInteractionCollector.getData(),l=this.behavioralCollector.getMouseSignals(),u=this.behavioralCollector.getKeyboardSignals(),d=this.pageInteractionCollector.getData(),m={connectionType:h.connectionType||void 0,effectiveType:h.effectiveType||void 0,downlink:h.downlink||void 0,rtt:h.rtt||void 0,saveData:h.saveData||void 0},p={sessionId:this.sessionId||void 0,timestamp:(new Date).toISOString()},g={userId:i.userId||this.config.userId,device:e,session:p,behavioral:s,fingerprintjs:r||void 0,privacySignals:o,browserCapabilities:a,hardwareSignals:h,formInteractions:c,mouseSignals:l,keyboardSignals:u,pageInteractions:d,networkSignals:m,useCase:t};i.metadata&&Object.assign(g,i.metadata),void 0!==i.amount&&(g.amount=i.amount),i.currency&&(g.currency=i.currency),i.email&&(g.email=i.email),i.changeType&&(g.changeType=i.changeType);const w=`${I}/fingerprint/verify/${t}`,f={"Content-Type":"application/json","X-SDK-Source":"javascript"},v=this.config.apiKey;v&&(f["x-keverd-key"]=v,f["X-API-KEY"]=v,f.Authorization=`Bearer ${v}`);const y=await fetch(w,{method:"POST",headers:f,body:JSON.stringify(g)});if(!y.ok){const t=await y.text().catch(()=>"Unknown error");throw new Error(`HTTP ${y.status}: ${t}`)}return await y.json()}async sendFingerprintRequest(t){if(!this.config)throw new Error("SDK not initialized");const i=`${I}/fingerprint/score`,e={"Content-Type":"application/json","X-SDK-Source":"javascript"},s=this.config.apiKey;s&&(e["x-keverd-key"]=s,e["X-API-KEY"]=s,e.Authorization=`Bearer ${s}`);const n=await fetch(i,{method:"POST",headers:e,body:JSON.stringify(t)});if(!n.ok){const t=await n.text().catch(()=>"Unknown error");throw new Error(`HTTP ${n.status}: ${t}`)}return await n.json()}generateSessionId(){return`${Date.now()}_${Math.random().toString(36).substr(2,9)}`}i(){const t=navigator.userAgent;return t.includes("Chrome")?"Chrome":t.includes("Firefox")?"Firefox":t.includes("Safari")&&!t.includes("Chrome")?"Safari":t.includes("Edge")?"Edge":t.includes("Opera")?"Opera":void 0}h(){const t=navigator.userAgent;return t.includes("Windows")?"Windows":t.includes("Mac OS")?"macOS":t.includes("Linux")?"Linux":t.includes("Android")?"Android":t.includes("iOS")||t.includes("iPhone")||t.includes("iPad")?"iOS":void 0}async startSession(t,i,e){if(!this.isInitialized||!this.config)throw new Error("Keverd SDK not initialized. Call init() first.");this.sessionId||(this.sessionId=this.generateSessionId());try{const s=`${I}/dashboard/sessions/start`,n={"Content-Type":"application/json"},r=this.config.apiKey;r&&(n["x-keverd-key"]=r,n["X-API-KEY"]=r,n.Authorization=`Bearer ${r}`);const o=this.deviceCollector.collect();await fetch(s,{method:"POST",headers:n,body:JSON.stringify({session_id:this.sessionId,user_id:t||this.config.userId,device_hash:i||o.fingerprint,metadata:e||{},user_agent:navigator.userAgent,browser:this.i(),os:this.h(),platform:"web",sdk_type:"web",sdk_source:"javascript"})}),this.config.debug}catch(t){this.config.debug}}async endSession(){if(this.isInitialized&&this.config&&this.sessionId)try{const t=`${I}/dashboard/sessions/${this.sessionId}/end`,i={"Content-Type":"application/json"},e=this.config.apiKey;e&&(i["x-keverd-key"]=e,i["X-API-KEY"]=e,i.Authorization=`Bearer ${e}`),await fetch(t,{method:"POST",headers:i}),this.config.debug}catch(t){this.config.debug}}async pauseSession(){if(this.isInitialized&&this.config&&this.sessionId)try{const t=`${I}/dashboard/sessions/${this.sessionId}/pause`,i={"Content-Type":"application/json"},e=this.config.apiKey;e&&(i["x-keverd-key"]=e,i["X-API-KEY"]=e,i.Authorization=`Bearer ${e}`),await fetch(t,{method:"POST",headers:i}),this.config.debug}catch(t){this.config.debug}}async resumeSession(){if(this.isInitialized&&this.config&&this.sessionId)try{const t=`${I}/dashboard/sessions/${this.sessionId}/resume`,i={"Content-Type":"application/json"},e=this.config.apiKey;e&&(i["x-keverd-key"]=e,i["X-API-KEY"]=e,i.Authorization=`Bearer ${e}`),await fetch(t,{method:"POST",headers:i}),this.config.debug}catch(t){this.config.debug}}async getSessionStatus(){if(!this.isInitialized||!this.config||!this.sessionId)return null;try{const t=`${I}/dashboard/sessions/${this.sessionId}/status`,i={},e=this.config.apiKey;e&&(i["x-keverd-key"]=e,i["X-API-KEY"]=e,i.Authorization=`Bearer ${e}`);const s=await fetch(t,{method:"GET",headers:i});return s.ok?await s.json():null}catch(t){return this.config.debug,null}}async destroy(){this.sessionId&&await this.endSession(),this.behavioralCollector.stop(),this.formInteractionCollector.stop(),this.pageInteractionCollector.stop(),this.fingerprintManager.clearCache(),this.isInitialized=!1,this.stopGhostSignalCollection(),this.ghostSignalCount=0,this.config,this.config=null,this.sessionId=null}isReady(){return this.isInitialized&&null!==this.config}}const P=new x;class O{async collect(){return null}clearCache(){}async isAvailable(){return!1}}return i})());
|
package/dist/types.d.ts
CHANGED
|
@@ -139,6 +139,7 @@ export interface FingerprintRequest {
|
|
|
139
139
|
device: DeviceInfo;
|
|
140
140
|
session?: SessionInfo;
|
|
141
141
|
behavioral?: BehavioralData;
|
|
142
|
+
duration_ms?: number;
|
|
142
143
|
fingerprintjs?: FingerprintJSData;
|
|
143
144
|
privacySignals?: PrivacySignals;
|
|
144
145
|
browserCapabilities?: BrowserCapabilities;
|
|
@@ -183,7 +184,6 @@ export interface FingerprintResponse {
|
|
|
183
184
|
}
|
|
184
185
|
export interface SDKConfig {
|
|
185
186
|
apiKey: string;
|
|
186
|
-
endpoint?: string;
|
|
187
187
|
userId?: string;
|
|
188
188
|
debug?: boolean;
|
|
189
189
|
}
|