@axeptio/behavior-detection 1.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 +828 -0
- package/dist/behavior-detection.esm.min.js +2 -0
- package/dist/behavior-detection.esm.min.js.map +7 -0
- package/dist/behavior-detection.min.js +2 -0
- package/dist/behavior-detection.min.js.map +7 -0
- package/dist/behavior-detector.d.ts +102 -0
- package/dist/browser.d.ts +33 -0
- package/dist/cjs/behavior-detector.d.ts +102 -0
- package/dist/cjs/behavior-detector.js +315 -0
- package/dist/cjs/browser.d.ts +33 -0
- package/dist/cjs/browser.js +226 -0
- package/dist/cjs/index.d.ts +38 -0
- package/dist/cjs/index.js +55 -0
- package/dist/cjs/math-utils.d.ts +84 -0
- package/dist/cjs/math-utils.js +141 -0
- package/dist/cjs/strategies/click.d.ts +39 -0
- package/dist/cjs/strategies/click.js +173 -0
- package/dist/cjs/strategies/environment.d.ts +52 -0
- package/dist/cjs/strategies/environment.js +148 -0
- package/dist/cjs/strategies/index.d.ts +18 -0
- package/dist/cjs/strategies/index.js +36 -0
- package/dist/cjs/strategies/keyboard.d.ts +43 -0
- package/dist/cjs/strategies/keyboard.js +233 -0
- package/dist/cjs/strategies/mouse.d.ts +39 -0
- package/dist/cjs/strategies/mouse.js +159 -0
- package/dist/cjs/strategies/resize.d.ts +21 -0
- package/dist/cjs/strategies/resize.js +97 -0
- package/dist/cjs/strategies/scroll.d.ts +37 -0
- package/dist/cjs/strategies/scroll.js +149 -0
- package/dist/cjs/strategies/tap.d.ts +38 -0
- package/dist/cjs/strategies/tap.js +214 -0
- package/dist/cjs/strategy.d.ts +107 -0
- package/dist/cjs/strategy.js +33 -0
- package/dist/cjs/types.d.ts +168 -0
- package/dist/cjs/types.js +26 -0
- package/dist/esm/behavior-detector.d.ts +102 -0
- package/dist/esm/behavior-detector.js +311 -0
- package/dist/esm/browser.d.ts +33 -0
- package/dist/esm/browser.js +224 -0
- package/dist/esm/index.d.ts +38 -0
- package/dist/esm/index.js +36 -0
- package/dist/esm/math-utils.d.ts +84 -0
- package/dist/esm/math-utils.js +127 -0
- package/dist/esm/strategies/click.d.ts +39 -0
- package/dist/esm/strategies/click.js +169 -0
- package/dist/esm/strategies/environment.d.ts +52 -0
- package/dist/esm/strategies/environment.js +144 -0
- package/dist/esm/strategies/index.d.ts +18 -0
- package/dist/esm/strategies/index.js +19 -0
- package/dist/esm/strategies/keyboard.d.ts +43 -0
- package/dist/esm/strategies/keyboard.js +229 -0
- package/dist/esm/strategies/mouse.d.ts +39 -0
- package/dist/esm/strategies/mouse.js +155 -0
- package/dist/esm/strategies/resize.d.ts +21 -0
- package/dist/esm/strategies/resize.js +93 -0
- package/dist/esm/strategies/scroll.d.ts +37 -0
- package/dist/esm/strategies/scroll.js +145 -0
- package/dist/esm/strategies/tap.d.ts +38 -0
- package/dist/esm/strategies/tap.js +210 -0
- package/dist/esm/strategy.d.ts +107 -0
- package/dist/esm/strategy.js +29 -0
- package/dist/esm/types.d.ts +168 -0
- package/dist/esm/types.js +23 -0
- package/dist/index.d.ts +38 -0
- package/dist/math-utils.d.ts +84 -0
- package/dist/strategies/click.d.ts +39 -0
- package/dist/strategies/environment.d.ts +52 -0
- package/dist/strategies/index.d.ts +18 -0
- package/dist/strategies/keyboard.d.ts +43 -0
- package/dist/strategies/mouse.d.ts +39 -0
- package/dist/strategies/resize.d.ts +21 -0
- package/dist/strategies/scroll.d.ts +37 -0
- package/dist/strategies/tap.d.ts +38 -0
- package/dist/strategy.d.ts +107 -0
- package/dist/types.d.ts +168 -0
- package/package.json +60 -0
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use strict";(()=>{var I=class{constructor(t){this.strategies=new Map,this.isTracking=!1,this.isPausedByVisibility=!1,this.tickInterval=null,this.tickIntervalMs=1e3,this.pauseOnHidden=!0,this.visibilityChangeHandler=null,this.confidenceScore=0,this.CONFIDENCE_TARGET=1,this.CONFIDENCE_DECAY=.95,t?.interval&&(this.tickIntervalMs=t.interval),t?.pauseOnHidden!==void 0&&(this.pauseOnHidden=t.pauseOnHidden)}addStrategy(t,e){let s={strategy:t,weight:e??t.defaultWeight,enabled:!0};return this.strategies.set(t.name,s),t.setEventCallback&&t.setEventCallback(n=>{this.onStrategyEvent(n,s.weight)}),this.isTracking&&t.start(),this}onStrategyEvent(t,e){this.confidenceScore*=this.CONFIDENCE_DECAY;let s=t.weight*e;this.confidenceScore=Math.min(this.CONFIDENCE_TARGET,this.confidenceScore+s)}removeStrategy(t){let e=this.strategies.get(t);return e&&(this.isTracking&&e.strategy.stop(),this.strategies.delete(t)),this}setStrategyEnabled(t,e){let s=this.strategies.get(t);return s&&(s.enabled=e,!e&&this.isTracking&&s.strategy.stop(),e&&this.isTracking&&s.strategy.start()),this}getStrategies(){return this.strategies}start(){if(!this.isTracking){if(this.isTracking=!0,this.pauseOnHidden&&typeof document<"u"&&(this.visibilityChangeHandler=this.handleVisibilityChange.bind(this),document.addEventListener("visibilitychange",this.visibilityChangeHandler),document.hidden)){this.isPausedByVisibility=!0;return}for(let[t,e]of this.strategies)e.enabled&&e.strategy.start();this.startTick()}}stop(){if(this.isTracking){this.isTracking=!1,this.isPausedByVisibility=!1,this.visibilityChangeHandler&&typeof document<"u"&&(document.removeEventListener("visibilitychange",this.visibilityChangeHandler),this.visibilityChangeHandler=null);for(let[t,e]of this.strategies)e.strategy.stop();this.stopTick()}}reset(){this.confidenceScore=0;for(let[t,e]of this.strategies)e.strategy.reset()}async score(t={}){let e=this.calculateStrategyScore(),s={score:e.overall};return t.breakdown&&(s.breakdown=e),s}isActive(){return this.isTracking}isPaused(){return this.isPausedByVisibility}getEventCount(){var t,e;let s={};for(let[n,r]of this.strategies){let i=(e=(t=r.strategy).getDebugInfo)===null||e===void 0?void 0:e.call(t);i?.eventCount!==void 0&&(s[n]=i.eventCount)}return s}getStrategyDebugInfo(){let t={};for(let[e,s]of this.strategies)s.strategy.getDebugInfo&&(t[e]=s.strategy.getDebugInfo());return t}getConfidence(){return Math.min(1,this.confidenceScore)}hasConfidentData(t=.3){return this.getConfidence()>=t}destroy(){this.stop(),this.strategies.clear()}handleVisibilityChange(){if(this.isTracking){if(document.hidden){if(!this.isPausedByVisibility){this.isPausedByVisibility=!0;for(let[t,e]of this.strategies)e.enabled&&e.strategy.stop();this.stopTick()}}else if(this.isPausedByVisibility){this.isPausedByVisibility=!1;for(let[t,e]of this.strategies)e.enabled&&e.strategy.start();this.startTick()}}}startTick(){this.tickInterval===null&&(this.tickInterval=window.setInterval(()=>{let t=Date.now();for(let[e,s]of this.strategies)s.enabled&&s.strategy.onTick&&s.strategy.onTick(t)},this.tickIntervalMs))}stopTick(){this.tickInterval!==null&&(clearInterval(this.tickInterval),this.tickInterval=null)}calculateStrategyScore(){let t={},e={},s=0,n=0;for(let[i,a]of this.strategies){if(!a.enabled)continue;let c=a.strategy.score();t[i]=c,e[i]=a.weight,c!=null&&(s+=a.weight,n+=c*a.weight)}let r=s>0?n/s:.5;return{overall:Math.max(0,Math.min(1,r)),factors:t,weights:e}}};var d=class{constructor(){this.eventCallback=null}setEventCallback(t){this.eventCallback=t}notifyEvent(t){this.eventCallback&&this.eventCallback({strategy:this.name,weight:t,timestamp:Date.now()})}};function W(l,t=0,e=1){return 1/(1+Math.exp(-e*(l-t)))}function p(l,t=0,e=1){return 1-W(l,t,e)}function v(l,t=0,e=1){let s=-Math.pow(l-t,2)/(2*e*e);return Math.exp(s)}function S(l){if(l.length===0)return{mean:0,variance:0,stdDev:0,cv:0};let t=l.reduce((r,i)=>r+i,0)/l.length,e=l.reduce((r,i)=>r+(i-t)**2,0)/l.length,s=Math.sqrt(e),n=t>0?s/t:0;return{mean:t,variance:e,stdDev:s,cv:n}}function y(l){if(l.length<2)return;let t=new Set(l.map(n=>Math.round(n/10))).size,e=t===1;return{statistics:S(l),uniqueCount:t,allIdentical:e}}function w(l){return l<.05?.1:l>2?.3:v(l,.45,.35)}var E=class extends d{constructor(t){super(),this.name="mouse",this.defaultWeight=.3,this.distanceSeries=[],this.angleSeries=[],this.lastPosition=null,this.lastAngle=0,this.cumulativeAngle=0,this.rollingWindowMs=5e3,this.listener=null,this.leaveListener=null,this.isActive=!1,this.screenDiagonal=1,t?.rollingWindow!==void 0&&(this.rollingWindowMs=t.rollingWindow)}start(){if(this.isActive)return;this.isActive=!0;let t=window.innerWidth,e=window.innerHeight;this.screenDiagonal=Math.sqrt(t*t+e*e),this.listener=s=>{let n=s,r=Date.now(),i={x:n.clientX,y:n.clientY};if(this.lastPosition){let a=i.x-this.lastPosition.x,c=i.y-this.lastPosition.y,g=Math.sqrt(a*a+c*c)/this.screenDiagonal;if(g>.001){let m=Math.atan2(c,a),u=m-this.lastAngle;for(;u>Math.PI;)u-=2*Math.PI;for(;u<-Math.PI;)u+=2*Math.PI;this.cumulativeAngle+=u,this.lastAngle=m,this.distanceSeries.push({value:g,timestamp:r}),this.angleSeries.push({value:this.cumulativeAngle,timestamp:r}),this.notifyEvent(Math.min(1,g*100))}let h=r-this.rollingWindowMs;for(;this.distanceSeries.length>0&&this.distanceSeries[0].timestamp<h;)this.distanceSeries.shift(),this.angleSeries.shift()}this.lastPosition=i},document.addEventListener("mousemove",this.listener,{passive:!0}),this.leaveListener=()=>{this.distanceSeries=[],this.angleSeries=[],this.lastPosition=null,this.lastAngle=0,this.cumulativeAngle=0},document.addEventListener("mouseleave",this.leaveListener,{passive:!0})}stop(){this.isActive&&(this.isActive=!1,this.listener&&(document.removeEventListener("mousemove",this.listener),this.listener=null),this.leaveListener&&(document.removeEventListener("mouseleave",this.leaveListener),this.leaveListener=null))}reset(){this.distanceSeries=[],this.angleSeries=[],this.lastPosition=null,this.lastAngle=0,this.cumulativeAngle=0}score(){if(!(this.distanceSeries.length<10))return this.detectMousePatterns()}detectMousePatterns(){if(this.distanceSeries.length<10)return;let t=0,e=0,s=this.distanceSeries.map(r=>r.value);if(s.length>=3){let r=S(s);t+=v(r.cv,.9,.35),e++}let n=this.angleSeries.map(r=>r.value);if(n.length>=3){let r=[];for(let a=1;a<n.length;a++)r.push(Math.abs(n[a]-n[a-1]));let i=r.reduce((a,c)=>a+c,0)/r.length;t+=v(i,.15,.12),e++}return e>0?t/e:void 0}getDebugInfo(){return{eventCount:this.distanceSeries.length,rollingWindow:this.rollingWindowMs,isActive:this.isActive,distanceSeries:this.distanceSeries,angleSeries:this.angleSeries}}};var L=class extends d{constructor(t){super(),this.name="scroll",this.defaultWeight=.15,this.distanceSeries=[],this.velocitySeries=[],this.lastScrollY=null,this.lastTimestamp=0,this.rollingWindowMs=5e3,this.documentHeight=1,this.listener=null,this.isActive=!1,t?.rollingWindow!==void 0&&(this.rollingWindowMs=t.rollingWindow)}start(){this.isActive||(this.isActive=!0,this.documentHeight=Math.max(document.body.scrollHeight,document.documentElement.scrollHeight,1),this.listener=t=>{let e=window.scrollY,s=Date.now();if(this.lastScrollY===null){this.lastScrollY=e,this.lastTimestamp=s;return}let n=e-this.lastScrollY,r=s-this.lastTimestamp;if(n===0)return;let i=Math.abs(n)/this.documentHeight;if(r>0){let a=i/r;this.distanceSeries.push({value:i,timestamp:s}),this.velocitySeries.push({value:a,timestamp:s}),this.notifyEvent(Math.min(1,i*10));let c=s-this.rollingWindowMs;for(;this.distanceSeries.length>0&&this.distanceSeries[0].timestamp<c;)this.distanceSeries.shift(),this.velocitySeries.shift()}this.lastScrollY=e,this.lastTimestamp=s},window.addEventListener("scroll",this.listener,{passive:!0}))}stop(){this.isActive&&(this.isActive=!1,this.listener&&(window.removeEventListener("scroll",this.listener),this.listener=null))}reset(){this.distanceSeries=[],this.velocitySeries=[],this.lastScrollY=null,this.lastTimestamp=0}score(){if(!(this.distanceSeries.length<2))return this.detectScrollPatterns()}detectScrollPatterns(){if(this.distanceSeries.length<2)return;let t=0,e=0,s=this.distanceSeries.map(i=>i.value);if(s.length>=2&&new Set(s.map(a=>Math.round(a*1e3))).size===1)return .05;if(s.length>=2){let i=S(s);t+=v(i.cv,1,.4),e++}let n=this.velocitySeries.map(i=>i.value);if(n.length>=2){let i=S(n);t+=v(i.cv,1.2,.5),e++}let r=s.filter(i=>i>.1).length;if(s.length>0){let i=r/s.length;t+=p(i,.3,15),e++}return e>0?t/e:void 0}getDebugInfo(){return{eventCount:this.distanceSeries.length,rollingWindow:this.rollingWindowMs,isActive:this.isActive,distanceSeries:this.distanceSeries,velocitySeries:this.velocitySeries}}};var b=class extends d{constructor(t){super(),this.name="click",this.defaultWeight=.3,this.events=[],this.targetSelectors=["button","a",'input[type="submit"]','[role="button"]'],this.lastMousePosition=null,this.mouseListener=null,this.clickListeners=new Map,this.isActive=!1,t?.targetSelectors&&(this.targetSelectors=t.targetSelectors)}start(){this.isActive||(this.isActive=!0,this.mouseListener=t=>{let e=t;this.lastMousePosition={x:e.clientX,y:e.clientY}},document.addEventListener("mousemove",this.mouseListener,{passive:!0}),this.attachClickListeners())}addTarget(t){this.targetSelectors.includes(t)||(this.targetSelectors.push(t),this.isActive&&this.attachClickListenersForSelector(t))}attachClickListeners(){this.targetSelectors.forEach(t=>{this.attachClickListenersForSelector(t)})}attachClickListenersForSelector(t){document.querySelectorAll(t).forEach(s=>{if(this.clickListeners.has(s))return;let n=r=>{var i,a;let c=r,o=s.getBoundingClientRect(),g=o.top>=0&&o.left>=0&&o.bottom<=window.innerHeight&&o.right<=window.innerWidth,h;if(!this.lastMousePosition)h="no-mouse-data";else{let m=this.lastMousePosition.x,u=this.lastMousePosition.y;if(!(m>=o.left&&m<=o.right&&u>=o.top&&u<=o.bottom))h="outside";else{let f=o.left+o.width/2,D=o.top+o.height/2;Math.sqrt((m-f)**2+(u-D)**2)<2?h="dead-center":h="over-element"}}this.events.push({clickX:c.clientX,clickY:c.clientY,mouseX:(i=this.lastMousePosition)===null||i===void 0?void 0:i.x,mouseY:(a=this.lastMousePosition)===null||a===void 0?void 0:a.y,rect:o,inViewport:g,position:h,timestamp:Date.now()}),this.notifyEvent(1)};s.addEventListener("click",n),this.clickListeners.set(s,n)})}stop(){this.isActive&&(this.isActive=!1,this.mouseListener&&(document.removeEventListener("mousemove",this.mouseListener),this.mouseListener=null),this.clickListeners.forEach((t,e)=>{e.removeEventListener("click",t)}),this.clickListeners.clear())}reset(){this.events=[],this.lastMousePosition=null}score(){if(this.events.length===0)return;let t=0;for(let e of this.events)switch(e.position){case"no-mouse-data":t+=0;break;case"outside":t+=0;break;case"dead-center":t+=.5;break;case"over-element":t+=1;break}return t/this.events.length}getDebugInfo(){return{eventCount:this.events.length,positions:{noMouseData:this.events.filter(t=>t.position==="no-mouse-data").length,outside:this.events.filter(t=>t.position==="outside").length,deadCenter:this.events.filter(t=>t.position==="dead-center").length,overElement:this.events.filter(t=>t.position==="over-element").length},inViewport:this.events.filter(t=>t.inViewport).length,trackedElements:this.clickListeners.size}}};var k=class extends d{constructor(t){super(),this.name="tap",this.defaultWeight=.35,this.events=[],this.targetSelectors=["button","a",'input[type="submit"]','[role="button"]'],this.touchStartListeners=new Map,this.touchEndListeners=new Map,this.activeTouches=new Map,this.isActive=!1,t?.targetSelectors&&(this.targetSelectors=t.targetSelectors)}start(){this.isActive||(this.isActive=!0,this.attachTouchListeners())}addTarget(t){this.targetSelectors.includes(t)||(this.targetSelectors.push(t),this.isActive&&this.attachTouchListenersForSelector(t))}attachTouchListeners(){this.targetSelectors.forEach(t=>{this.attachTouchListenersForSelector(t)})}attachTouchListenersForSelector(t){document.querySelectorAll(t).forEach(s=>{if(this.touchStartListeners.has(s))return;let n=i=>{let a=i;if(a.touches.length!==1)return;let c=a.touches[0];this.activeTouches.set(c.identifier,{x:c.clientX,y:c.clientY,timestamp:Date.now(),element:s})},r=i=>{let a=i;if(a.changedTouches.length!==1)return;let c=a.changedTouches[0],o=this.activeTouches.get(c.identifier);if(!o||o.element!==s)return;let g=Date.now(),h=g-o.timestamp,m=c.clientX-o.x,u=c.clientY-o.y,B=Math.sqrt(m*m+u*u),f=s.getBoundingClientRect(),D=f.top>=0&&f.left>=0&&f.bottom<=window.innerHeight&&f.right<=window.innerWidth,C=c.clientX,A=c.clientY,F=C>=f.left&&C<=f.right&&A>=f.top&&A<=f.bottom,P;if(!F)P="outside";else{let H=f.left+f.width/2,Y=f.top+f.height/2;P=Math.sqrt((C-H)**2+(A-Y)**2)<2?"dead-center":"over-element"}this.events.push({x:C,y:A,rect:f,inViewport:D,position:P,duration:h,movement:B,timestamp:g}),this.notifyEvent(1),this.activeTouches.delete(c.identifier)};s.addEventListener("touchstart",n,{passive:!0}),s.addEventListener("touchend",r,{passive:!0}),this.touchStartListeners.set(s,n),this.touchEndListeners.set(s,r)})}stop(){this.isActive&&(this.isActive=!1,this.touchStartListeners.forEach((t,e)=>{e.removeEventListener("touchstart",t)}),this.touchStartListeners.clear(),this.touchEndListeners.forEach((t,e)=>{e.removeEventListener("touchend",t)}),this.touchEndListeners.clear(),this.activeTouches.clear())}reset(){this.events=[],this.activeTouches.clear()}score(){if(this.events.length===0)return;let t=0,e=0,s=0;for(let i of this.events)switch(i.position){case"outside":s+=0;break;case"dead-center":s+=.5;break;case"over-element":s+=1;break}t+=s/this.events.length,e++;let n=this.events.map(i=>i.duration);if(n.length>=2){let i=y(n);if(i){let{statistics:a,allIdentical:c}=i;if(c)return .05;t+=w(a.cv),e++,t+=v(a.mean,95,40),e++}}let r=this.events.map(i=>i.movement);if(r.length>0){let i=r.reduce((a,c)=>a+c,0)/r.length;t+=v(i,2,3),e++}if(this.events.length>=3){let i=[];for(let c=1;c<this.events.length;c++)i.push(this.events[c].timestamp-this.events[c-1].timestamp);let a=y(i);a&&!a.allIdentical&&(t+=w(a.statistics.cv),e++)}return e>0?t/e:void 0}getDebugInfo(){return{eventCount:this.events.length,positions:{outside:this.events.filter(t=>t.position==="outside").length,deadCenter:this.events.filter(t=>t.position==="dead-center").length,overElement:this.events.filter(t=>t.position==="over-element").length},durations:this.events.map(t=>t.duration),movements:this.events.map(t=>t.movement),inViewport:this.events.filter(t=>t.inViewport).length,trackedElements:this.touchStartListeners.size}}};var x=class extends d{constructor(t){super(),this.name="keyboard",this.defaultWeight=.1,this.events=[],this.targetSelectors=['input[type="text"]','input[type="email"]',"textarea"],this.focusedElement=null,this.focusedElementSelector="",this.lastEventTimestamp=0,this.sessionPauseThreshold=1e3,this.downListener=null,this.upListener=null,this.focusListeners=new Map,this.blurListeners=new Map,this.isActive=!1,t?.targetSelectors&&(this.targetSelectors=t.targetSelectors)}start(){this.isActive||(this.isActive=!0,this.attachFocusListeners(),this.downListener=t=>{if(!this.focusedElement)return;let e=Date.now(),s=t;this.lastEventTimestamp>0&&e-this.lastEventTimestamp>this.sessionPauseThreshold&&(this.events=[]),this.events.push({key:s.key,type:"down",timestamp:e,targetElement:this.focusedElementSelector}),this.notifyEvent(.8),this.lastEventTimestamp=e},this.upListener=t=>{if(!this.focusedElement)return;let e=Date.now(),s=t;this.lastEventTimestamp>0&&e-this.lastEventTimestamp>this.sessionPauseThreshold&&(this.events=[]),this.events.push({key:s.key,type:"up",timestamp:e,targetElement:this.focusedElementSelector}),this.lastEventTimestamp=e},document.addEventListener("keydown",this.downListener),document.addEventListener("keyup",this.upListener))}addTarget(t){this.targetSelectors.includes(t)||(this.targetSelectors.push(t),this.isActive&&this.attachFocusListenersForSelector(t))}attachFocusListeners(){this.targetSelectors.forEach(t=>{this.attachFocusListenersForSelector(t)})}attachFocusListenersForSelector(t){document.querySelectorAll(t).forEach(s=>{if(this.focusListeners.has(s))return;let n=()=>{this.focusedElement=s,this.focusedElementSelector=t},r=()=>{this.focusedElement=null,this.focusedElementSelector=""};s.addEventListener("focus",n),s.addEventListener("blur",r),this.focusListeners.set(s,n),this.blurListeners.set(s,r)})}stop(){this.isActive&&(this.isActive=!1,this.downListener&&(document.removeEventListener("keydown",this.downListener),this.downListener=null),this.upListener&&(document.removeEventListener("keyup",this.upListener),this.upListener=null),this.focusListeners.forEach((t,e)=>{e.removeEventListener("focus",t)}),this.focusListeners.clear(),this.blurListeners.forEach((t,e)=>{e.removeEventListener("blur",t)}),this.blurListeners.clear(),this.focusedElement=null)}reset(){this.events=[],this.focusedElement=null,this.focusedElementSelector="",this.lastEventTimestamp=0}score(){if(this.events.length<6)return;let t=this.events.filter(o=>o.type==="down");if(t.length<3)return;let e=0,s=0,n=[];for(let o=1;o<t.length;o++)n.push(t[o].timestamp-t[o-1].timestamp);let r=y(n);if(r){let{statistics:o,allIdentical:g}=r;if(g)return .1;let h=w(o.cv);if(e+=h,s++,h<=.1)return h}let i=[];for(let o=0;o<this.events.length-1;o++)this.events[o].type==="down"&&this.events[o+1].type==="up"&&this.events[o].key===this.events[o+1].key&&i.push(this.events[o+1].timestamp-this.events[o].timestamp);let a=y(i);if(a){let{statistics:o,allIdentical:g}=a;if(g)return .1;if(o.mean<5)e+=.1,s++;else{let h=w(o.cv);if(e+=h,s++,h<=.1)return h}}let c=this.events.filter(o=>o.key==="Backspace").length;if(c>0){let o=c/t.length;o>.05&&o<.3?(e+=1,s++):o>0&&(e+=.8,s++)}return s>0?e/s:void 0}getDebugInfo(){let t=[];for(let e=0;e<this.events.length-1;e++)this.events[e].type==="down"&&this.events[e+1].type==="up"&&this.events[e].key===this.events[e+1].key&&t.push(this.events[e+1].timestamp-this.events[e].timestamp);return{eventCount:this.events.length,downEvents:this.events.filter(e=>e.type==="down").length,upEvents:this.events.filter(e=>e.type==="up").length,backspaceCount:this.events.filter(e=>e.key==="Backspace").length,pressDurations:t,focusedElement:this.focusedElementSelector,trackedElements:this.focusListeners.size}}};var T=class extends d{constructor(){super(...arguments),this.name="environment",this.defaultWeight=.08,this.data=null}start(){this.captureEnvironment()}stop(){}reset(){this.data=null}onTick(t){this.captureEnvironment()}score(){if(!this.data)return;let t=this.data,e=0,s=0;e+=t.suspiciousDimensions?.1:1,e+=t.suspiciousRatio?.2:1,e+=t.featureInconsistency?.3:1,s+=3;let n=[t.hasWebGL,t.hasLocalStorage,t.hasSessionStorage,t.hasIndexedDB].filter(Boolean).length;return e+=n/4,s++,e+=p(t.plugins,-2,-.5),e+=t.plugins>0?1:.1,s+=2,e+=v(t.devicePixelRatio,2,1.5),e+=t.colorDepth===24||t.colorDepth===32?1:.4,s+=2,s>0?e/s:void 0}isMobileDevice(){let t=navigator.maxTouchPoints>0||"ontouchstart"in window,e=/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent),s=window.innerWidth<768&&window.innerHeight<1024;return t&&s||e}captureEnvironment(){try{let t=!1;try{let u=document.createElement("canvas");t=!!(u.getContext("webgl")||u.getContext("experimental-webgl"))}catch{t=!1}let e=!!(window.RTCPeerConnection||window.mozRTCPeerConnection||window.webkitRTCPeerConnection),s=this.isMobileDevice(),n=window.innerWidth,r=window.innerHeight,i=window.screen.width,a=window.screen.height,c=n===800&&r===600||n===1024&&r===768||n===1280&&r===720||i===800&&a===600,o=n*r/(i*a),g=o===1||o<.1||o>1,h=typeof localStorage<"u"&&typeof sessionStorage<"u",m=navigator.plugins.length===0&&navigator.mimeTypes.length===0||!t||!h;this.data={screenWidth:i,screenHeight:a,windowWidth:n,windowHeight:r,devicePixelRatio:window.devicePixelRatio,colorDepth:window.screen.colorDepth,userAgent:navigator.userAgent,platform:navigator.platform,language:navigator.language,languages:navigator.languages?Array.from(navigator.languages):[navigator.language],hardwareConcurrency:navigator.hardwareConcurrency,maxTouchPoints:navigator.maxTouchPoints||0,vendor:navigator.vendor,hasWebGL:t,hasWebRTC:e,hasLocalStorage:typeof localStorage<"u",hasSessionStorage:typeof sessionStorage<"u",hasIndexedDB:"indexedDB"in window,plugins:navigator.plugins.length,mimeTypes:navigator.mimeTypes.length,suspiciousRatio:g,suspiciousDimensions:c,featureInconsistency:m,isMobile:s,timestamp:Date.now()}}catch(t){console.warn("Failed to capture environment:",t)}}getDebugInfo(){return this.data}isMobile(){var t,e;return(e=(t=this.data)===null||t===void 0?void 0:t.isMobile)!==null&&e!==void 0?e:null}};var M=class extends d{constructor(){super(...arguments),this.name="resize",this.defaultWeight=.02,this.events=[],this.listener=null,this.isActive=!1,this.lastMousePosition=null,this.mouseListener=null}start(){this.isActive||(this.isActive=!0,this.mouseListener=t=>{let e=t;this.lastMousePosition={x:e.clientX,y:e.clientY}},document.addEventListener("mousemove",this.mouseListener,{passive:!0}),this.listener=()=>{var t,e;let s=(t=this.lastMousePosition)===null||t===void 0?void 0:t.x,n=(e=this.lastMousePosition)===null||e===void 0?void 0:e.y,r=!1;s!==void 0&&n!==void 0&&(r=s<50||s>window.innerWidth-50||n<50||n>window.innerHeight-50),this.events.push({width:window.innerWidth,height:window.innerHeight,mouseX:s,mouseY:n,mouseNearEdge:r,timestamp:Date.now()})},window.addEventListener("resize",this.listener))}stop(){this.isActive&&(this.isActive=!1,this.listener&&(window.removeEventListener("resize",this.listener),this.listener=null),this.mouseListener&&(document.removeEventListener("mousemove",this.mouseListener),this.mouseListener=null))}reset(){this.events=[]}score(){if(this.events.length===0)return;let t=0,e=0;t+=p(this.events.length,5,.5),e++;let s=this.events.filter(n=>n.mouseX!==void 0);if(s.length>0){let n=s.filter(r=>r.mouseNearEdge).length;t+=W(n/s.length,.5,8),e++}return e>0?t/e:void 0}getDebugInfo(){return{eventCount:this.events.length,withMouseData:this.events.filter(t=>t.mouseX!==void 0).length}}};var _={sampleRates:{mouseMove:.1,scroll:1,keypress:1},rollingWindows:{mouseMove:3e4,scroll:3e4},weights:{mouseMovement:.3,clickAccuracy:.3,scrollBehavior:.15,keyboardTiming:.1,tabActivity:.05,resizeBehavior:.02,environmentFingerprint:.08},customScorers:{},clickMouseHistoryWindow:1e3,useWebWorker:!1};})();
|
|
2
|
+
//# sourceMappingURL=behavior-detection.esm.min.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["esm/behavior-detector.js", "esm/strategy.js", "esm/math-utils.js", "esm/strategies/mouse.js", "esm/strategies/scroll.js", "esm/strategies/click.js", "esm/strategies/tap.js", "esm/strategies/keyboard.js", "esm/strategies/environment.js", "esm/strategies/resize.js", "esm/types.js"],
|
|
4
|
+
"sourcesContent": ["/**\n * Main class for behavior detection\n * Uses modular strategy pattern for tree-shakeable, autonomous detection modules\n */\nexport class BehaviorDetector {\n constructor(tickOptions) {\n // Strategy mode\n this.strategies = new Map();\n this.isTracking = false;\n this.isPausedByVisibility = false;\n this.tickInterval = null;\n this.tickIntervalMs = 1000; // Default: 1 second\n this.pauseOnHidden = true;\n this.visibilityChangeHandler = null;\n // Confidence tracking\n this.confidenceScore = 0;\n this.CONFIDENCE_TARGET = 1.0; // Target confidence for reliable classification\n this.CONFIDENCE_DECAY = 0.95; // Per event decay to prevent infinite growth\n if (tickOptions === null || tickOptions === void 0 ? void 0 : tickOptions.interval) {\n this.tickIntervalMs = tickOptions.interval;\n }\n if ((tickOptions === null || tickOptions === void 0 ? void 0 : tickOptions.pauseOnHidden) !== undefined) {\n this.pauseOnHidden = tickOptions.pauseOnHidden;\n }\n }\n /**\n * Add a detection strategy\n */\n addStrategy(strategy, weight) {\n const config = {\n strategy,\n weight: weight !== null && weight !== void 0 ? weight : strategy.defaultWeight,\n enabled: true,\n };\n this.strategies.set(strategy.name, config);\n // Set up event callback for confidence tracking\n if (strategy.setEventCallback) {\n strategy.setEventCallback((event) => {\n this.onStrategyEvent(event, config.weight);\n });\n }\n // If already tracking, start this strategy immediately\n if (this.isTracking) {\n strategy.start();\n }\n return this;\n }\n /**\n * Handle event from strategy - update confidence\n */\n onStrategyEvent(event, strategyWeight) {\n // Apply decay to existing confidence to prevent infinite growth\n this.confidenceScore *= this.CONFIDENCE_DECAY;\n // Add weighted contribution from this event\n // eventWeight (0-1) * strategyWeight (e.g. 0.3 for mouse) = contribution\n const contribution = event.weight * strategyWeight;\n this.confidenceScore = Math.min(this.CONFIDENCE_TARGET, this.confidenceScore + contribution);\n }\n /**\n * Remove a detection strategy\n */\n removeStrategy(name) {\n const config = this.strategies.get(name);\n if (config) {\n if (this.isTracking) {\n config.strategy.stop();\n }\n this.strategies.delete(name);\n }\n return this;\n }\n /**\n * Enable/disable a strategy\n */\n setStrategyEnabled(name, enabled) {\n const config = this.strategies.get(name);\n if (config) {\n config.enabled = enabled;\n // If tracking and being disabled, stop it\n if (!enabled && this.isTracking) {\n config.strategy.stop();\n }\n // If tracking and being enabled, start it\n if (enabled && this.isTracking) {\n config.strategy.start();\n }\n }\n return this;\n }\n /**\n * Get all registered strategies\n */\n getStrategies() {\n return this.strategies;\n }\n /**\n * Start tracking\n */\n start() {\n if (this.isTracking)\n return;\n this.isTracking = true;\n // Set up visibility change listener\n if (this.pauseOnHidden && typeof document !== 'undefined') {\n this.visibilityChangeHandler = this.handleVisibilityChange.bind(this);\n document.addEventListener('visibilitychange', this.visibilityChangeHandler);\n // Check initial visibility state\n if (document.hidden) {\n this.isPausedByVisibility = true;\n return; // Don't start strategies if already hidden\n }\n }\n // Start all enabled strategies\n for (const [_, config] of this.strategies) {\n if (config.enabled) {\n config.strategy.start();\n }\n }\n // Start tick mechanism\n this.startTick();\n }\n /**\n * Stop tracking\n */\n stop() {\n if (!this.isTracking)\n return;\n this.isTracking = false;\n this.isPausedByVisibility = false;\n // Remove visibility change listener\n if (this.visibilityChangeHandler && typeof document !== 'undefined') {\n document.removeEventListener('visibilitychange', this.visibilityChangeHandler);\n this.visibilityChangeHandler = null;\n }\n // Stop all strategies\n for (const [_, config] of this.strategies) {\n config.strategy.stop();\n }\n // Stop tick\n this.stopTick();\n }\n /**\n * Reset all data\n */\n reset() {\n this.confidenceScore = 0;\n for (const [_, config] of this.strategies) {\n config.strategy.reset();\n }\n }\n /**\n * Calculate human likelihood score\n */\n async score(options = {}) {\n const breakdown = this.calculateStrategyScore();\n const result = {\n score: breakdown.overall,\n };\n if (options.breakdown) {\n result.breakdown = breakdown;\n }\n // Note: auditTrail not available in strategy mode\n // Each strategy manages its own data independently\n return result;\n }\n /**\n * Check if currently tracking\n */\n isActive() {\n return this.isTracking;\n }\n /**\n * Check if currently paused due to tab visibility\n */\n isPaused() {\n return this.isPausedByVisibility;\n }\n /**\n * Get event count from all strategies\n */\n getEventCount() {\n var _a, _b;\n const counts = {};\n for (const [name, config] of this.strategies) {\n const debug = (_b = (_a = config.strategy).getDebugInfo) === null || _b === void 0 ? void 0 : _b.call(_a);\n if ((debug === null || debug === void 0 ? void 0 : debug.eventCount) !== undefined) {\n counts[name] = debug.eventCount;\n }\n }\n return counts;\n }\n /**\n * Get debug info from all strategies\n */\n getStrategyDebugInfo() {\n const debug = {};\n for (const [name, config] of this.strategies) {\n if (config.strategy.getDebugInfo) {\n debug[name] = config.strategy.getDebugInfo();\n }\n }\n return debug;\n }\n /**\n * Get current confidence score (0-1)\n * Represents how much interaction data we've collected\n * Higher confidence = more reliable classification\n */\n getConfidence() {\n return Math.min(1, this.confidenceScore);\n }\n /**\n * Check if confidence is above threshold for reliable classification\n * @param threshold - Minimum confidence (0-1), default 0.3\n */\n hasConfidentData(threshold = 0.3) {\n return this.getConfidence() >= threshold;\n }\n /**\n * Cleanup resources\n */\n destroy() {\n this.stop();\n this.strategies.clear();\n }\n /**\n * Handle visibility change events\n */\n handleVisibilityChange() {\n if (!this.isTracking)\n return;\n if (document.hidden) {\n // Tab became hidden - pause detection\n if (!this.isPausedByVisibility) {\n this.isPausedByVisibility = true;\n // Stop all strategies\n for (const [_, config] of this.strategies) {\n if (config.enabled) {\n config.strategy.stop();\n }\n }\n // Stop tick\n this.stopTick();\n }\n }\n else {\n // Tab became visible - resume detection\n if (this.isPausedByVisibility) {\n this.isPausedByVisibility = false;\n // Restart all enabled strategies\n for (const [_, config] of this.strategies) {\n if (config.enabled) {\n config.strategy.start();\n }\n }\n // Restart tick\n this.startTick();\n }\n }\n }\n /**\n * Start tick mechanism for strategies\n */\n startTick() {\n if (this.tickInterval !== null)\n return;\n this.tickInterval = window.setInterval(() => {\n const now = Date.now();\n for (const [_, config] of this.strategies) {\n if (config.enabled && config.strategy.onTick) {\n config.strategy.onTick(now);\n }\n }\n }, this.tickIntervalMs);\n }\n /**\n * Stop tick mechanism\n */\n stopTick() {\n if (this.tickInterval !== null) {\n clearInterval(this.tickInterval);\n this.tickInterval = null;\n }\n }\n /**\n * Calculate score using strategies\n */\n calculateStrategyScore() {\n const factors = {};\n const weights = {};\n let totalWeight = 0;\n let weightedSum = 0;\n for (const [name, config] of this.strategies) {\n if (!config.enabled)\n continue;\n const score = config.strategy.score();\n factors[name] = score;\n weights[name] = config.weight;\n if (score !== undefined && score !== null) {\n totalWeight += config.weight;\n weightedSum += score * config.weight;\n }\n }\n const overall = totalWeight > 0 ? weightedSum / totalWeight : 0.5;\n return {\n overall: Math.max(0, Math.min(1, overall)),\n factors,\n weights,\n };\n }\n}\n", "/**\n * Detection Strategy Interface\n * Each strategy is a fully autonomous module responsible for:\n * - Registering its own event listeners\n * - Managing its own state and events\n * - Responding to lifecycle events (start/stop)\n * - Optionally receiving tick updates for polling-based detection\n */\n/**\n * Base class for detection strategies\n * Handles event callback pattern to avoid repetition\n */\nexport class BaseStrategy {\n constructor() {\n this.eventCallback = null;\n }\n setEventCallback(callback) {\n this.eventCallback = callback;\n }\n notifyEvent(weight) {\n if (this.eventCallback) {\n this.eventCallback({\n strategy: this.name,\n weight,\n timestamp: Date.now()\n });\n }\n }\n}\n", "/**\n * Mathematical utility functions for continuous scoring\n * Replaces magic number if-else chains with smooth mathematical functions\n */\n/**\n * Sigmoid function - Maps any value to [0, 1] with smooth S-curve\n * @param x - Input value\n * @param midpoint - Value that maps to 0.5\n * @param steepness - How steep the curve is (higher = steeper)\n */\nexport function sigmoid(x, midpoint = 0, steepness = 1) {\n return 1 / (1 + Math.exp(-steepness * (x - midpoint)));\n}\n/**\n * Inverse sigmoid - High values map to low scores\n */\nexport function inverseSigmoid(x, midpoint = 0, steepness = 1) {\n return 1 - sigmoid(x, midpoint, steepness);\n}\n/**\n * Gaussian (bell curve) - Peak at ideal value, falls off on both sides\n * @param x - Input value\n * @param ideal - Optimal value (peak of curve)\n * @param width - How wide the acceptable range is\n */\nexport function gaussian(x, ideal = 0, width = 1) {\n const exponent = -Math.pow(x - ideal, 2) / (2 * width * width);\n return Math.exp(exponent);\n}\n/**\n * Exponential decay - High values get penalized exponentially\n */\nexport function exponentialDecay(x, decayRate = 0.1) {\n return Math.exp(-decayRate * x);\n}\n/**\n * Normalize value to [0, 1] range\n */\nexport function normalize(value, min = 0, max = 1) {\n if (max === min)\n return 0.5;\n return Math.max(0, Math.min(1, (value - min) / (max - min)));\n}\n/**\n * Clamp value to [0, 1]\n */\nexport function clamp01(value) {\n return Math.max(0, Math.min(1, value));\n}\n/**\n * Calculate statistical metrics for an array of numbers\n * @param values - Array of numerical values\n * @returns Statistical metrics (mean, variance, stdDev, cv)\n */\nexport function calculateStatistics(values) {\n if (values.length === 0) {\n return { mean: 0, variance: 0, stdDev: 0, cv: 0 };\n }\n const mean = values.reduce((a, b) => a + b, 0) / values.length;\n const variance = values.reduce((sum, v) => sum + (v - mean) ** 2, 0) / values.length;\n const stdDev = Math.sqrt(variance);\n const cv = mean > 0 ? stdDev / mean : 0;\n return { mean, variance, stdDev, cv };\n}\n/**\n * Analyze timing intervals for bot-like patterns\n * Returns raw analysis data without scoring - caller decides heuristics\n *\n * @param intervals - Array of time intervals (ms)\n * @returns Analysis of interval patterns including stats and uniqueness\n */\nexport function analyzeIntervals(intervals) {\n if (intervals.length < 2)\n return undefined;\n // Check for identical intervals (round to 10ms to account for floating point)\n const uniqueCount = new Set(intervals.map(i => Math.round(i / 10))).size;\n const allIdentical = uniqueCount === 1;\n // Calculate statistics\n const statistics = calculateStatistics(intervals);\n return {\n statistics,\n uniqueCount,\n allIdentical,\n };\n}\n/**\n * Score coefficient of variation\n * Maps CV to human-likeness score using Gaussian\n * Ideal CV is around 0.4-0.5 (moderate variation)\n */\nexport function scoreCoefficientOfVariation(cv) {\n // Too low (<0.1) = bot-like (too consistent)\n // Too high (>1.5) = random noise\n // Ideal = 0.4-0.6 (natural human variation)\n if (cv < 0.05)\n return 0.1; // Almost zero variation - definitely bot\n if (cv > 2.0)\n return 0.3; // Too random\n // Gaussian centered at 0.45 with width of 0.35\n return gaussian(cv, 0.45, 0.35);\n}\n/**\n * Score entropy - Higher is better (more random = more human)\n * Uses sigmoid to smoothly map entropy to score\n */\nexport function scoreEntropy(normalizedEntropy) {\n // Entropy of 0.7+ is very human\n // Entropy < 0.3 is very bot-like\n return sigmoid(normalizedEntropy, 0.5, 8); // Steep curve at midpoint 0.5\n}\n/**\n * Score autocorrelation - Lower is better (less periodic = more human)\n */\nexport function scoreAutocorrelation(autocorr) {\n // Low autocorrelation (<0.2) is natural\n // High autocorrelation (>0.6) is periodic/bot-like\n return inverseSigmoid(autocorr, 0.4, 10);\n}\n/**\n * Score jerk - Lower is better (smoother = more human)\n */\nexport function scoreJerk(avgJerk) {\n // Human jerk typically < 0.01\n // Bot jerk often > 0.1\n // Use inverse sigmoid\n return inverseSigmoid(avgJerk, 0.05, 50);\n}\n", "/**\n * Mouse Movement Detection Strategy\n * Autonomous module that manages its own mouse event listeners and state\n * Tracks distance and angle to detect unnatural jumps and sharp turns\n */\nimport { BaseStrategy } from '../strategy';\nimport { calculateStatistics, gaussian } from '../math-utils';\nexport class MouseStrategy extends BaseStrategy {\n constructor(options) {\n super();\n this.name = 'mouse';\n this.defaultWeight = 0.30;\n this.distanceSeries = [];\n this.angleSeries = [];\n this.lastPosition = null;\n this.lastAngle = 0;\n this.cumulativeAngle = 0;\n this.rollingWindowMs = 5000;\n this.listener = null;\n this.leaveListener = null;\n this.isActive = false;\n this.screenDiagonal = 1;\n if ((options === null || options === void 0 ? void 0 : options.rollingWindow) !== undefined)\n this.rollingWindowMs = options.rollingWindow;\n }\n start() {\n if (this.isActive)\n return;\n this.isActive = true;\n // Calculate screen diagonal for normalization (distance relative to screen size)\n const width = window.innerWidth;\n const height = window.innerHeight;\n this.screenDiagonal = Math.sqrt(width * width + height * height);\n this.listener = (e) => {\n const mouseEvent = e;\n const now = Date.now();\n const currentPos = { x: mouseEvent.clientX, y: mouseEvent.clientY };\n // Calculate distance and angle from previous position\n if (this.lastPosition) {\n const dx = currentPos.x - this.lastPosition.x;\n const dy = currentPos.y - this.lastPosition.y;\n const pixelDistance = Math.sqrt(dx * dx + dy * dy);\n // Normalize distance to screen diagonal (0-1 range)\n // A full diagonal movement = 1.0, a 10px movement on 2000px screen = 0.005\n const normalizedDistance = pixelDistance / this.screenDiagonal;\n // Only record if movement is meaningful (> 0.001 = ~2px on 2000px screen)\n if (normalizedDistance > 0.001) {\n const rawAngle = Math.atan2(dy, dx); // -PI to PI\n // Unwrap angle to avoid discontinuities (e.g., circles)\n let angleDiff = rawAngle - this.lastAngle;\n // Normalize difference to -PI to PI\n while (angleDiff > Math.PI)\n angleDiff -= 2 * Math.PI;\n while (angleDiff < -Math.PI)\n angleDiff += 2 * Math.PI;\n this.cumulativeAngle += angleDiff;\n this.lastAngle = rawAngle;\n // Store normalized distance (not raw pixels)\n this.distanceSeries.push({ value: normalizedDistance, timestamp: now });\n this.angleSeries.push({ value: this.cumulativeAngle, timestamp: now });\n // Notify detector for confidence tracking\n this.notifyEvent(Math.min(1, normalizedDistance * 100));\n }\n // Apply rolling window efficiently: remove old events from start\n // Since events are chronological, we only check from the beginning\n const cutoff = now - this.rollingWindowMs;\n while (this.distanceSeries.length > 0 && this.distanceSeries[0].timestamp < cutoff) {\n this.distanceSeries.shift();\n this.angleSeries.shift(); // Keep both arrays in sync\n }\n }\n this.lastPosition = currentPos;\n };\n document.addEventListener('mousemove', this.listener, { passive: true });\n // Clear data when mouse leaves the window (discontinuous tracking)\n this.leaveListener = () => {\n this.distanceSeries = [];\n this.angleSeries = [];\n this.lastPosition = null;\n this.lastAngle = 0;\n this.cumulativeAngle = 0;\n };\n document.addEventListener('mouseleave', this.leaveListener, { passive: true });\n }\n stop() {\n if (!this.isActive)\n return;\n this.isActive = false;\n if (this.listener) {\n document.removeEventListener('mousemove', this.listener);\n this.listener = null;\n }\n if (this.leaveListener) {\n document.removeEventListener('mouseleave', this.leaveListener);\n this.leaveListener = null;\n }\n }\n reset() {\n this.distanceSeries = [];\n this.angleSeries = [];\n this.lastPosition = null;\n this.lastAngle = 0;\n this.cumulativeAngle = 0;\n }\n score() {\n if (this.distanceSeries.length < 10)\n return undefined;\n // Mouse-specific pattern detection (optimized for normalized continuous data)\n // Generic smoothness detector is calibrated for discrete events, not continuous movement\n return this.detectMousePatterns();\n }\n /**\n * Mouse-specific pattern detection\n * Detects bot-like patterns: constant velocity, linear paths\n */\n detectMousePatterns() {\n if (this.distanceSeries.length < 10)\n return undefined;\n let score = 0;\n let factors = 0;\n // 1. VELOCITY CONSISTENCY - Bots often move at constant speed\n const distances = this.distanceSeries.map(p => p.value);\n if (distances.length >= 3) {\n const stats = calculateStatistics(distances);\n // Real human movement has high variation (CV ~0.8-1.2)\n // page.mouse.move() with steps has lower CV (~0.4-0.6)\n // Narrower gaussian to be strict\n score += gaussian(stats.cv, 0.9, 0.35);\n factors++;\n }\n // 2. DIRECTION CHANGES - Bots often have too few or too many sharp turns\n const angles = this.angleSeries.map(p => p.value);\n if (angles.length >= 3) {\n const angleChanges = [];\n for (let i = 1; i < angles.length; i++) {\n angleChanges.push(Math.abs(angles[i] - angles[i - 1]));\n }\n const avgChange = angleChanges.reduce((a, b) => a + b, 0) / angleChanges.length;\n // Real humans have moderate but varied direction changes\n // page.mouse.move() linear interpolation has very small, consistent changes\n score += gaussian(avgChange, 0.15, 0.12);\n factors++;\n }\n return factors > 0 ? score / factors : undefined;\n }\n getDebugInfo() {\n return {\n eventCount: this.distanceSeries.length,\n rollingWindow: this.rollingWindowMs,\n isActive: this.isActive,\n distanceSeries: this.distanceSeries,\n angleSeries: this.angleSeries,\n };\n }\n}\n", "/**\n * Scroll Behavior Detection Strategy\n * Autonomous module managing scroll event listeners\n * Tracks normalized scroll distance and velocity patterns\n */\nimport { BaseStrategy } from '../strategy';\nimport { calculateStatistics, gaussian, inverseSigmoid } from '../math-utils';\nexport class ScrollStrategy extends BaseStrategy {\n constructor(options) {\n super();\n this.name = 'scroll';\n this.defaultWeight = 0.15;\n this.distanceSeries = [];\n this.velocitySeries = [];\n this.lastScrollY = null;\n this.lastTimestamp = 0;\n this.rollingWindowMs = 5000;\n this.documentHeight = 1;\n this.listener = null;\n this.isActive = false;\n if ((options === null || options === void 0 ? void 0 : options.rollingWindow) !== undefined)\n this.rollingWindowMs = options.rollingWindow;\n }\n start() {\n if (this.isActive)\n return;\n this.isActive = true;\n // Calculate document height for normalization\n this.documentHeight = Math.max(document.body.scrollHeight, document.documentElement.scrollHeight, 1);\n this.listener = (_e) => {\n const scrollY = window.scrollY;\n const now = Date.now();\n // Always update last position on first event\n if (this.lastScrollY === null) {\n this.lastScrollY = scrollY;\n this.lastTimestamp = now;\n return;\n }\n const pixelDelta = scrollY - this.lastScrollY;\n const deltaTime = now - this.lastTimestamp;\n // Skip if no actual scroll happened\n if (pixelDelta === 0) {\n return;\n }\n // Normalize scroll distance to document height (0-1 range)\n const normalizedDistance = Math.abs(pixelDelta) / this.documentHeight;\n // Record all scroll movements (no threshold - let pattern detection decide)\n if (deltaTime > 0) {\n const velocity = normalizedDistance / deltaTime; // normalized units per ms\n // Store as time series\n this.distanceSeries.push({ value: normalizedDistance, timestamp: now });\n this.velocitySeries.push({ value: velocity, timestamp: now });\n // Notify detector for confidence tracking\n this.notifyEvent(Math.min(1, normalizedDistance * 10));\n // Apply rolling window efficiently\n const cutoff = now - this.rollingWindowMs;\n while (this.distanceSeries.length > 0 && this.distanceSeries[0].timestamp < cutoff) {\n this.distanceSeries.shift();\n this.velocitySeries.shift();\n }\n }\n this.lastScrollY = scrollY;\n this.lastTimestamp = now;\n };\n // Listen on window for scroll events (document scrolling)\n window.addEventListener('scroll', this.listener, { passive: true });\n }\n stop() {\n if (!this.isActive)\n return;\n this.isActive = false;\n if (this.listener) {\n window.removeEventListener('scroll', this.listener);\n this.listener = null;\n }\n }\n reset() {\n this.distanceSeries = [];\n this.velocitySeries = [];\n this.lastScrollY = null;\n this.lastTimestamp = 0;\n }\n score() {\n if (this.distanceSeries.length < 2)\n return undefined;\n // Scroll-specific pattern detection\n return this.detectScrollPatterns();\n }\n /**\n * Scroll-specific pattern detection\n * Detects bot-like patterns: constant deltas, instant jumps, too smooth\n */\n detectScrollPatterns() {\n if (this.distanceSeries.length < 2)\n return undefined;\n let score = 0;\n let factors = 0;\n // 1. IDENTICAL DELTAS - Smoking gun for bots\n const distances = this.distanceSeries.map(p => p.value);\n if (distances.length >= 2) {\n // Check if all distances are identical (tolerance for floating point)\n const uniqueDistances = new Set(distances.map(d => Math.round(d * 1000))).size;\n if (uniqueDistances === 1) {\n // All scroll amounts identical = definite bot\n return 0.05;\n }\n }\n // 2. DISTANCE CONSISTENCY - Bots often scroll same amount repeatedly\n if (distances.length >= 2) {\n const stats = calculateStatistics(distances);\n // Real humans have high CV (>0.8) due to natural scroll acceleration/deceleration\n // Simple automation has lower CV even with varied amounts\n // Gaussian centered high with narrow width - be strict\n score += gaussian(stats.cv, 1.0, 0.4);\n factors++;\n }\n // 3. VELOCITY VARIATION - Humans have highly variable scroll speeds\n const velocities = this.velocitySeries.map(p => p.value);\n if (velocities.length >= 2) {\n const stats = calculateStatistics(velocities);\n // Human velocity is very chaotic (acceleration/deceleration)\n // Automation has more consistent velocity even with delays\n score += gaussian(stats.cv, 1.2, 0.5);\n factors++;\n }\n // 4. INSTANT JUMPS - Detect programmatic scrollTo\n const instantJumps = distances.filter(d => d > 0.1).length; // >10% of document in one event\n if (distances.length > 0) {\n const jumpRatio = instantJumps / distances.length;\n // Penalize high jump ratio (programmatic scrollTo)\n score += inverseSigmoid(jumpRatio, 0.3, 15);\n factors++;\n }\n return factors > 0 ? score / factors : undefined;\n }\n getDebugInfo() {\n return {\n eventCount: this.distanceSeries.length,\n rollingWindow: this.rollingWindowMs,\n isActive: this.isActive,\n distanceSeries: this.distanceSeries,\n velocitySeries: this.velocitySeries,\n };\n }\n}\n", "/**\n * Click Behavior Detection Strategy\n * Monitors specific elements for click positioning patterns\n */\nimport { BaseStrategy } from '../strategy';\nexport class ClickStrategy extends BaseStrategy {\n constructor(options) {\n super();\n this.name = 'click';\n this.defaultWeight = 0.30;\n this.events = [];\n this.targetSelectors = ['button', 'a', 'input[type=\"submit\"]', '[role=\"button\"]'];\n this.lastMousePosition = null;\n this.mouseListener = null;\n this.clickListeners = new Map();\n this.isActive = false;\n if (options === null || options === void 0 ? void 0 : options.targetSelectors) {\n this.targetSelectors = options.targetSelectors;\n }\n }\n start() {\n if (this.isActive)\n return;\n this.isActive = true;\n // Track mouse position globally\n this.mouseListener = (e) => {\n const mouseEvent = e;\n this.lastMousePosition = {\n x: mouseEvent.clientX,\n y: mouseEvent.clientY,\n };\n };\n document.addEventListener('mousemove', this.mouseListener, { passive: true });\n // Find all matching elements and attach listeners\n this.attachClickListeners();\n }\n /**\n * Add a new target selector at runtime\n */\n addTarget(selector) {\n if (!this.targetSelectors.includes(selector)) {\n this.targetSelectors.push(selector);\n // Attach listeners if already active\n if (this.isActive) {\n this.attachClickListenersForSelector(selector);\n }\n }\n }\n attachClickListeners() {\n this.targetSelectors.forEach(selector => {\n this.attachClickListenersForSelector(selector);\n });\n }\n attachClickListenersForSelector(selector) {\n const elements = document.querySelectorAll(selector);\n elements.forEach(element => {\n if (this.clickListeners.has(element))\n return; // Already attached\n const listener = (e) => {\n var _a, _b;\n const clickEvent = e;\n const rect = element.getBoundingClientRect();\n // Check if element is in viewport\n const inViewport = (rect.top >= 0 &&\n rect.left >= 0 &&\n rect.bottom <= window.innerHeight &&\n rect.right <= window.innerWidth);\n // Analyze click position\n let position;\n if (!this.lastMousePosition) {\n position = 'no-mouse-data'; // Bot - no mouse movement\n }\n else {\n const mx = this.lastMousePosition.x;\n const my = this.lastMousePosition.y;\n // Check if mouse was over element\n const overElement = (mx >= rect.left &&\n mx <= rect.right &&\n my >= rect.top &&\n my <= rect.bottom);\n if (!overElement) {\n position = 'outside'; // Bot - mouse not over target\n }\n else {\n // Check if dead center (suspicious)\n const centerX = rect.left + rect.width / 2;\n const centerY = rect.top + rect.height / 2;\n const distanceFromCenter = Math.sqrt((mx - centerX) ** 2 + (my - centerY) ** 2);\n // Dead center = within 2px of center\n if (distanceFromCenter < 2) {\n position = 'dead-center'; // Suspicious - too perfect\n }\n else {\n position = 'over-element'; // Human - somewhere on the button\n }\n }\n }\n this.events.push({\n clickX: clickEvent.clientX,\n clickY: clickEvent.clientY,\n mouseX: (_a = this.lastMousePosition) === null || _a === void 0 ? void 0 : _a.x,\n mouseY: (_b = this.lastMousePosition) === null || _b === void 0 ? void 0 : _b.y,\n rect,\n inViewport,\n position,\n timestamp: Date.now(),\n });\n // Notify detector - clicks are high-value events\n this.notifyEvent(1.0);\n };\n element.addEventListener('click', listener);\n this.clickListeners.set(element, listener);\n });\n }\n stop() {\n if (!this.isActive)\n return;\n this.isActive = false;\n // Remove mouse listener\n if (this.mouseListener) {\n document.removeEventListener('mousemove', this.mouseListener);\n this.mouseListener = null;\n }\n // Remove all click listeners\n this.clickListeners.forEach((listener, element) => {\n element.removeEventListener('click', listener);\n });\n this.clickListeners.clear();\n }\n reset() {\n this.events = [];\n this.lastMousePosition = null;\n }\n score() {\n if (this.events.length === 0)\n return undefined;\n let totalScore = 0;\n for (const click of this.events) {\n switch (click.position) {\n case 'no-mouse-data':\n totalScore += 0.0; // Bot - no mouse movement\n break;\n case 'outside':\n totalScore += 0.0; // Bot - mouse not over target\n break;\n case 'dead-center':\n totalScore += 0.5; // Suspicious - too perfect\n break;\n case 'over-element':\n totalScore += 1.0; // Human - natural click\n break;\n }\n }\n return totalScore / this.events.length;\n }\n getDebugInfo() {\n return {\n eventCount: this.events.length,\n positions: {\n noMouseData: this.events.filter(e => e.position === 'no-mouse-data').length,\n outside: this.events.filter(e => e.position === 'outside').length,\n deadCenter: this.events.filter(e => e.position === 'dead-center').length,\n overElement: this.events.filter(e => e.position === 'over-element').length,\n },\n inViewport: this.events.filter(e => e.inViewport).length,\n trackedElements: this.clickListeners.size,\n };\n }\n}\n", "/**\n * Tap Behavior Detection Strategy (Mobile)\n * Monitors touch interactions on specific elements\n * Analyzes tap duration, precision, movement, and timing patterns\n */\nimport { BaseStrategy } from '../strategy';\nimport { analyzeIntervals, scoreCoefficientOfVariation, gaussian } from '../math-utils';\nexport class TapStrategy extends BaseStrategy {\n constructor(options) {\n super();\n this.name = 'tap';\n this.defaultWeight = 0.35;\n this.events = [];\n this.targetSelectors = ['button', 'a', 'input[type=\"submit\"]', '[role=\"button\"]'];\n this.touchStartListeners = new Map();\n this.touchEndListeners = new Map();\n this.activeTouches = new Map();\n this.isActive = false;\n if (options === null || options === void 0 ? void 0 : options.targetSelectors) {\n this.targetSelectors = options.targetSelectors;\n }\n }\n start() {\n if (this.isActive)\n return;\n this.isActive = true;\n this.attachTouchListeners();\n }\n addTarget(selector) {\n if (!this.targetSelectors.includes(selector)) {\n this.targetSelectors.push(selector);\n if (this.isActive) {\n this.attachTouchListenersForSelector(selector);\n }\n }\n }\n attachTouchListeners() {\n this.targetSelectors.forEach(selector => {\n this.attachTouchListenersForSelector(selector);\n });\n }\n attachTouchListenersForSelector(selector) {\n const elements = document.querySelectorAll(selector);\n elements.forEach(element => {\n if (this.touchStartListeners.has(element))\n return;\n const startListener = (e) => {\n const touchEvent = e;\n // Only track first touch (ignore multi-touch)\n if (touchEvent.touches.length !== 1)\n return;\n const touch = touchEvent.touches[0];\n this.activeTouches.set(touch.identifier, {\n x: touch.clientX,\n y: touch.clientY,\n timestamp: Date.now(),\n element,\n });\n };\n const endListener = (e) => {\n const touchEvent = e;\n if (touchEvent.changedTouches.length !== 1)\n return;\n const touch = touchEvent.changedTouches[0];\n const startData = this.activeTouches.get(touch.identifier);\n if (!startData || startData.element !== element)\n return;\n const now = Date.now();\n const duration = now - startData.timestamp;\n const dx = touch.clientX - startData.x;\n const dy = touch.clientY - startData.y;\n const movement = Math.sqrt(dx * dx + dy * dy);\n const rect = element.getBoundingClientRect();\n const inViewport = (rect.top >= 0 &&\n rect.left >= 0 &&\n rect.bottom <= window.innerHeight &&\n rect.right <= window.innerWidth);\n // Analyze tap position\n const tx = touch.clientX;\n const ty = touch.clientY;\n const overElement = (tx >= rect.left &&\n tx <= rect.right &&\n ty >= rect.top &&\n ty <= rect.bottom);\n let position;\n if (!overElement) {\n position = 'outside';\n }\n else {\n const centerX = rect.left + rect.width / 2;\n const centerY = rect.top + rect.height / 2;\n const distanceFromCenter = Math.sqrt((tx - centerX) ** 2 + (ty - centerY) ** 2);\n // Dead center = within 2px\n position = distanceFromCenter < 2 ? 'dead-center' : 'over-element';\n }\n this.events.push({\n x: tx,\n y: ty,\n rect,\n inViewport,\n position,\n duration,\n movement,\n timestamp: now,\n });\n // Notify detector - taps are high-value events\n this.notifyEvent(1.0);\n this.activeTouches.delete(touch.identifier);\n };\n element.addEventListener('touchstart', startListener, { passive: true });\n element.addEventListener('touchend', endListener, { passive: true });\n this.touchStartListeners.set(element, startListener);\n this.touchEndListeners.set(element, endListener);\n });\n }\n stop() {\n if (!this.isActive)\n return;\n this.isActive = false;\n this.touchStartListeners.forEach((listener, element) => {\n element.removeEventListener('touchstart', listener);\n });\n this.touchStartListeners.clear();\n this.touchEndListeners.forEach((listener, element) => {\n element.removeEventListener('touchend', listener);\n });\n this.touchEndListeners.clear();\n this.activeTouches.clear();\n }\n reset() {\n this.events = [];\n this.activeTouches.clear();\n }\n score() {\n if (this.events.length === 0)\n return undefined;\n let score = 0;\n let factors = 0;\n // 1. Position accuracy\n let positionScore = 0;\n for (const tap of this.events) {\n switch (tap.position) {\n case 'outside':\n positionScore += 0.0; // Bot\n break;\n case 'dead-center':\n positionScore += 0.5; // Suspicious\n break;\n case 'over-element':\n positionScore += 1.0; // Human\n break;\n }\n }\n score += positionScore / this.events.length;\n factors++;\n // 2. Tap duration variation - Humans have natural variation (50-150ms typical)\n const durations = this.events.map(e => e.duration);\n if (durations.length >= 2) {\n const durationAnalysis = analyzeIntervals(durations);\n if (durationAnalysis) {\n const { statistics, allIdentical } = durationAnalysis;\n // All identical = bot\n if (allIdentical) {\n return 0.05;\n }\n // Human tap durations have moderate CV (~0.3-0.5)\n score += scoreCoefficientOfVariation(statistics.cv);\n factors++;\n // Ideal duration: 70-120ms\n score += gaussian(statistics.mean, 95, 40);\n factors++;\n }\n }\n // 3. Tap movement - Real fingers move slightly (1-5px), bots are often 0px\n const movements = this.events.map(e => e.movement);\n if (movements.length > 0) {\n const avgMovement = movements.reduce((a, b) => a + b, 0) / movements.length;\n // Some movement is natural (1-5px), too much is a swipe, zero is suspicious\n score += gaussian(avgMovement, 2, 3);\n factors++;\n }\n // 4. Tap interval timing - Time between taps should vary naturally\n if (this.events.length >= 3) {\n const intervals = [];\n for (let i = 1; i < this.events.length; i++) {\n intervals.push(this.events[i].timestamp - this.events[i - 1].timestamp);\n }\n const intervalAnalysis = analyzeIntervals(intervals);\n if (intervalAnalysis && !intervalAnalysis.allIdentical) {\n score += scoreCoefficientOfVariation(intervalAnalysis.statistics.cv);\n factors++;\n }\n }\n return factors > 0 ? score / factors : undefined;\n }\n getDebugInfo() {\n return {\n eventCount: this.events.length,\n positions: {\n outside: this.events.filter(e => e.position === 'outside').length,\n deadCenter: this.events.filter(e => e.position === 'dead-center').length,\n overElement: this.events.filter(e => e.position === 'over-element').length,\n },\n durations: this.events.map(e => e.duration),\n movements: this.events.map(e => e.movement),\n inViewport: this.events.filter(e => e.inViewport).length,\n trackedElements: this.touchStartListeners.size,\n };\n }\n}\n", "/**\n * Keyboard Timing Detection Strategy\n * Monitors typing in specific input fields\n * Analyzes keydown/keyup timing and micro-variations\n */\nimport { BaseStrategy } from '../strategy';\nimport { analyzeIntervals, scoreCoefficientOfVariation } from '../math-utils';\nexport class KeyboardStrategy extends BaseStrategy {\n constructor(options) {\n super();\n this.name = 'keyboard';\n this.defaultWeight = 0.10;\n this.events = [];\n this.targetSelectors = ['input[type=\"text\"]', 'input[type=\"email\"]', 'textarea'];\n this.focusedElement = null;\n this.focusedElementSelector = '';\n this.lastEventTimestamp = 0;\n this.sessionPauseThreshold = 1000;\n this.downListener = null;\n this.upListener = null;\n this.focusListeners = new Map();\n this.blurListeners = new Map();\n this.isActive = false;\n if (options === null || options === void 0 ? void 0 : options.targetSelectors) {\n this.targetSelectors = options.targetSelectors;\n }\n }\n start() {\n if (this.isActive)\n return;\n this.isActive = true;\n // Attach focus/blur listeners to all matching elements\n this.attachFocusListeners();\n // Key event listeners (only track when an input is focused)\n this.downListener = (e) => {\n if (!this.focusedElement)\n return; // No input focused\n const now = Date.now();\n const keyEvent = e;\n // Clear events if pause > 1s (new typing session)\n if (this.lastEventTimestamp > 0 && now - this.lastEventTimestamp > this.sessionPauseThreshold) {\n this.events = [];\n }\n this.events.push({\n key: keyEvent.key,\n type: 'down',\n timestamp: now,\n targetElement: this.focusedElementSelector,\n });\n // Notify detector - keystrokes are valuable events\n this.notifyEvent(0.8);\n this.lastEventTimestamp = now;\n };\n this.upListener = (e) => {\n if (!this.focusedElement)\n return; // No input focused\n const now = Date.now();\n const keyEvent = e;\n // Clear events if pause > 1s (new typing session)\n if (this.lastEventTimestamp > 0 && now - this.lastEventTimestamp > this.sessionPauseThreshold) {\n this.events = [];\n }\n this.events.push({\n key: keyEvent.key,\n type: 'up',\n timestamp: now,\n targetElement: this.focusedElementSelector,\n });\n this.lastEventTimestamp = now;\n };\n document.addEventListener('keydown', this.downListener);\n document.addEventListener('keyup', this.upListener);\n }\n /**\n * Add a new target selector at runtime\n */\n addTarget(selector) {\n if (!this.targetSelectors.includes(selector)) {\n this.targetSelectors.push(selector);\n if (this.isActive) {\n this.attachFocusListenersForSelector(selector);\n }\n }\n }\n attachFocusListeners() {\n this.targetSelectors.forEach(selector => {\n this.attachFocusListenersForSelector(selector);\n });\n }\n attachFocusListenersForSelector(selector) {\n const elements = document.querySelectorAll(selector);\n elements.forEach(element => {\n if (this.focusListeners.has(element))\n return; // Already attached\n const focusListener = () => {\n this.focusedElement = element;\n this.focusedElementSelector = selector;\n };\n const blurListener = () => {\n this.focusedElement = null;\n this.focusedElementSelector = '';\n };\n element.addEventListener('focus', focusListener);\n element.addEventListener('blur', blurListener);\n this.focusListeners.set(element, focusListener);\n this.blurListeners.set(element, blurListener);\n });\n }\n stop() {\n if (!this.isActive)\n return;\n this.isActive = false;\n if (this.downListener) {\n document.removeEventListener('keydown', this.downListener);\n this.downListener = null;\n }\n if (this.upListener) {\n document.removeEventListener('keyup', this.upListener);\n this.upListener = null;\n }\n // Remove focus/blur listeners\n this.focusListeners.forEach((listener, element) => {\n element.removeEventListener('focus', listener);\n });\n this.focusListeners.clear();\n this.blurListeners.forEach((listener, element) => {\n element.removeEventListener('blur', listener);\n });\n this.blurListeners.clear();\n this.focusedElement = null;\n }\n reset() {\n this.events = [];\n this.focusedElement = null;\n this.focusedElementSelector = '';\n this.lastEventTimestamp = 0;\n }\n score() {\n if (this.events.length < 6)\n return undefined; // Need at least 3 key pairs\n const downEvents = this.events.filter(e => e.type === 'down');\n if (downEvents.length < 3)\n return undefined;\n let score = 0;\n let factors = 0;\n // 1. Analyze keystroke intervals (time between keydown events)\n const keystrokeIntervals = [];\n for (let i = 1; i < downEvents.length; i++) {\n keystrokeIntervals.push(downEvents[i].timestamp - downEvents[i - 1].timestamp);\n }\n const keystrokeAnalysis = analyzeIntervals(keystrokeIntervals);\n if (keystrokeAnalysis) {\n const { statistics, allIdentical } = keystrokeAnalysis;\n // Keyboard-specific heuristics for keystroke timing\n if (allIdentical) {\n return 0.1; // All identical - bot!\n }\n const keystrokeScore = scoreCoefficientOfVariation(statistics.cv);\n score += keystrokeScore;\n factors++;\n // Early return if bot detected\n if (keystrokeScore <= 0.1)\n return keystrokeScore;\n }\n // 2. Analyze press durations (keydown-to-keyup duration)\n const pressDurations = [];\n for (let i = 0; i < this.events.length - 1; i++) {\n if (this.events[i].type === 'down' && this.events[i + 1].type === 'up' &&\n this.events[i].key === this.events[i + 1].key) {\n pressDurations.push(this.events[i + 1].timestamp - this.events[i].timestamp);\n }\n }\n const pressDurationAnalysis = analyzeIntervals(pressDurations);\n if (pressDurationAnalysis) {\n const { statistics, allIdentical } = pressDurationAnalysis;\n // Keyboard-specific heuristics for press duration\n if (allIdentical) {\n return 0.1; // All identical - bot!\n }\n // Check for suspiciously fast key releases (bots often have <5ms press duration)\n if (statistics.mean < 5) {\n score += 0.1; // Too fast = bot (instant release)\n factors++;\n }\n else {\n const pressDurationScore = scoreCoefficientOfVariation(statistics.cv);\n score += pressDurationScore;\n factors++;\n // Early return if bot detected\n if (pressDurationScore <= 0.1)\n return pressDurationScore;\n }\n }\n // 3. Bonus for backspace usage (human error correction)\n const backspaceCount = this.events.filter(e => e.key === 'Backspace').length;\n if (backspaceCount > 0) {\n // Natural human behavior - making corrections\n const backspaceRatio = backspaceCount / downEvents.length;\n if (backspaceRatio > 0.05 && backspaceRatio < 0.3) {\n score += 1.0; // Reasonable error correction\n factors++;\n }\n else if (backspaceRatio > 0) {\n score += 0.8; // Some backspaces\n factors++;\n }\n }\n return factors > 0 ? score / factors : undefined;\n }\n getDebugInfo() {\n // Calculate press durations for visualization\n const pressDurations = [];\n for (let i = 0; i < this.events.length - 1; i++) {\n if (this.events[i].type === 'down' && this.events[i + 1].type === 'up' &&\n this.events[i].key === this.events[i + 1].key) {\n pressDurations.push(this.events[i + 1].timestamp - this.events[i].timestamp);\n }\n }\n return {\n eventCount: this.events.length,\n downEvents: this.events.filter(e => e.type === 'down').length,\n upEvents: this.events.filter(e => e.type === 'up').length,\n backspaceCount: this.events.filter(e => e.key === 'Backspace').length,\n pressDurations, // For graphing\n focusedElement: this.focusedElementSelector,\n trackedElements: this.focusListeners.size,\n };\n }\n}\n", "/**\n * Environment Fingerprinting Strategy\n * Captures browser environment on initialization and tick updates\n */\nimport { BaseStrategy } from '../strategy';\nimport { inverseSigmoid, gaussian } from '../math-utils';\nexport class EnvironmentStrategy extends BaseStrategy {\n constructor() {\n super(...arguments);\n this.name = 'environment';\n this.defaultWeight = 0.08;\n this.data = null;\n }\n start() {\n this.captureEnvironment();\n }\n stop() {\n // Environment data persists\n }\n reset() {\n this.data = null;\n }\n onTick(_timestamp) {\n // Re-capture environment periodically to detect changes\n this.captureEnvironment();\n }\n score() {\n if (!this.data)\n return undefined;\n const env = this.data;\n let score = 0;\n let factors = 0;\n // Suspicious indicators\n score += env.suspiciousDimensions ? 0.1 : 1.0;\n score += env.suspiciousRatio ? 0.2 : 1.0;\n score += env.featureInconsistency ? 0.3 : 1.0;\n factors += 3;\n // Browser features\n const featureCount = [\n env.hasWebGL,\n env.hasLocalStorage,\n env.hasSessionStorage,\n env.hasIndexedDB,\n ].filter(Boolean).length;\n score += featureCount / 4;\n factors++;\n // Plugins\n score += inverseSigmoid(env.plugins, -2, -0.5);\n score += (env.plugins > 0 ? 1.0 : 0.1);\n factors += 2;\n // Device\n score += gaussian(env.devicePixelRatio, 2, 1.5);\n score += (env.colorDepth === 24 || env.colorDepth === 32) ? 1.0 : 0.4;\n factors += 2;\n return factors > 0 ? score / factors : undefined;\n }\n isMobileDevice() {\n // Multiple checks for mobile detection\n const hasTouchScreen = navigator.maxTouchPoints > 0 || 'ontouchstart' in window;\n const mobileUA = /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent);\n const smallScreen = window.innerWidth < 768 && window.innerHeight < 1024;\n return (hasTouchScreen && smallScreen) || mobileUA;\n }\n captureEnvironment() {\n try {\n // WebGL detection\n let hasWebGL = false;\n try {\n const canvas = document.createElement('canvas');\n hasWebGL = !!(canvas.getContext('webgl') || canvas.getContext('experimental-webgl'));\n }\n catch (e) {\n hasWebGL = false;\n }\n // WebRTC detection\n const hasWebRTC = !!(window.RTCPeerConnection ||\n window.mozRTCPeerConnection ||\n window.webkitRTCPeerConnection);\n // Mobile detection\n const isMobile = this.isMobileDevice();\n const windowWidth = window.innerWidth;\n const windowHeight = window.innerHeight;\n const screenWidth = window.screen.width;\n const screenHeight = window.screen.height;\n // Suspicious dimensions\n const suspiciousDimensions = (windowWidth === 800 && windowHeight === 600) ||\n (windowWidth === 1024 && windowHeight === 768) ||\n (windowWidth === 1280 && windowHeight === 720) ||\n (screenWidth === 800 && screenHeight === 600);\n // Suspicious ratio\n const windowScreenRatio = (windowWidth * windowHeight) / (screenWidth * screenHeight);\n const suspiciousRatio = windowScreenRatio === 1.0 ||\n windowScreenRatio < 0.1 ||\n windowScreenRatio > 1.0;\n // Feature inconsistency\n const hasStorage = typeof localStorage !== 'undefined' && typeof sessionStorage !== 'undefined';\n const featureInconsistency = (navigator.plugins.length === 0 && navigator.mimeTypes.length === 0) ||\n !hasWebGL ||\n !hasStorage;\n this.data = {\n screenWidth,\n screenHeight,\n windowWidth,\n windowHeight,\n devicePixelRatio: window.devicePixelRatio,\n colorDepth: window.screen.colorDepth,\n userAgent: navigator.userAgent,\n platform: navigator.platform,\n language: navigator.language,\n languages: navigator.languages ? Array.from(navigator.languages) : [navigator.language],\n hardwareConcurrency: navigator.hardwareConcurrency,\n maxTouchPoints: navigator.maxTouchPoints || 0,\n vendor: navigator.vendor,\n hasWebGL,\n hasWebRTC,\n hasLocalStorage: typeof localStorage !== 'undefined',\n hasSessionStorage: typeof sessionStorage !== 'undefined',\n hasIndexedDB: 'indexedDB' in window,\n plugins: navigator.plugins.length,\n mimeTypes: navigator.mimeTypes.length,\n suspiciousRatio,\n suspiciousDimensions,\n featureInconsistency,\n isMobile,\n timestamp: Date.now(),\n };\n }\n catch (error) {\n console.warn('Failed to capture environment:', error);\n }\n }\n getDebugInfo() {\n return this.data;\n }\n /**\n * Check if current device is mobile\n * Returns true if mobile, false otherwise\n * Returns null if environment hasn't been captured yet\n */\n isMobile() {\n var _a, _b;\n return (_b = (_a = this.data) === null || _a === void 0 ? void 0 : _a.isMobile) !== null && _b !== void 0 ? _b : null;\n }\n}\n", "/**\n * Resize Behavior Detection Strategy\n */\nimport { BaseStrategy } from '../strategy';\nimport { inverseSigmoid, sigmoid } from '../math-utils';\nexport class ResizeStrategy extends BaseStrategy {\n constructor() {\n super(...arguments);\n this.name = 'resize';\n this.defaultWeight = 0.02;\n this.events = [];\n this.listener = null;\n this.isActive = false;\n this.lastMousePosition = null;\n this.mouseListener = null;\n }\n start() {\n if (this.isActive)\n return;\n this.isActive = true;\n // Track mouse for resize detection\n this.mouseListener = (e) => {\n const mouseEvent = e;\n this.lastMousePosition = {\n x: mouseEvent.clientX,\n y: mouseEvent.clientY,\n };\n };\n document.addEventListener('mousemove', this.mouseListener, { passive: true });\n // Track resizes\n this.listener = () => {\n var _a, _b;\n const mouseX = (_a = this.lastMousePosition) === null || _a === void 0 ? void 0 : _a.x;\n const mouseY = (_b = this.lastMousePosition) === null || _b === void 0 ? void 0 : _b.y;\n let mouseNearEdge = false;\n if (mouseX !== undefined && mouseY !== undefined) {\n const edgeThreshold = 50;\n mouseNearEdge = (mouseX < edgeThreshold ||\n mouseX > window.innerWidth - edgeThreshold ||\n mouseY < edgeThreshold ||\n mouseY > window.innerHeight - edgeThreshold);\n }\n this.events.push({\n width: window.innerWidth,\n height: window.innerHeight,\n mouseX,\n mouseY,\n mouseNearEdge,\n timestamp: Date.now(),\n });\n };\n window.addEventListener('resize', this.listener);\n }\n stop() {\n if (!this.isActive)\n return;\n this.isActive = false;\n if (this.listener) {\n window.removeEventListener('resize', this.listener);\n this.listener = null;\n }\n if (this.mouseListener) {\n document.removeEventListener('mousemove', this.mouseListener);\n this.mouseListener = null;\n }\n }\n reset() {\n this.events = [];\n }\n score() {\n if (this.events.length === 0)\n return undefined;\n let score = 0;\n let factors = 0;\n // Frequency\n score += inverseSigmoid(this.events.length, 5, 0.5);\n factors++;\n // Mouse near edge\n const withMouse = this.events.filter(e => e.mouseX !== undefined);\n if (withMouse.length > 0) {\n const nearEdge = withMouse.filter(e => e.mouseNearEdge).length;\n score += sigmoid(nearEdge / withMouse.length, 0.5, 8);\n factors++;\n }\n return factors > 0 ? score / factors : undefined;\n }\n getDebugInfo() {\n return {\n eventCount: this.events.length,\n withMouseData: this.events.filter(e => e.mouseX !== undefined).length,\n };\n }\n}\n", "export const DEFAULT_SETTINGS = {\n sampleRates: {\n mouseMove: 0.1, // Track 10% of mouse moves\n scroll: 1.0, // Track ALL scrolls - critical for detection\n keypress: 1.0, // Track all keypresses\n },\n rollingWindows: {\n mouseMove: 30000,\n scroll: 30000,\n },\n weights: {\n mouseMovement: 0.30, // Increased - continuous behavioral signal\n clickAccuracy: 0.30, // Increased - critical behavioral signal\n scrollBehavior: 0.15, // Unchanged\n keyboardTiming: 0.10, // Slightly reduced\n tabActivity: 0.05, // Unchanged\n resizeBehavior: 0.02, // Reduced - less reliable\n environmentFingerprint: 0.08, // Reduced - static signal, one-time check\n },\n customScorers: {},\n clickMouseHistoryWindow: 1000,\n useWebWorker: false, // Will implement Web Worker support in phase 2\n};\n"],
|
|
5
|
+
"mappings": "mBAIO,IAAMA,EAAN,KAAuB,CAC1B,YAAYC,EAAa,CAErB,KAAK,WAAa,IAAI,IACtB,KAAK,WAAa,GAClB,KAAK,qBAAuB,GAC5B,KAAK,aAAe,KACpB,KAAK,eAAiB,IACtB,KAAK,cAAgB,GACrB,KAAK,wBAA0B,KAE/B,KAAK,gBAAkB,EACvB,KAAK,kBAAoB,EACzB,KAAK,iBAAmB,IACsCA,GAAY,WACtE,KAAK,eAAiBA,EAAY,UAEyBA,GAAY,gBAAmB,SAC1F,KAAK,cAAgBA,EAAY,cAEzC,CAIA,YAAYC,EAAUC,EAAQ,CAC1B,IAAMC,EAAS,CACX,SAAAF,EACA,OAAQC,GAAgDD,EAAS,cACjE,QAAS,EACb,EACA,YAAK,WAAW,IAAIA,EAAS,KAAME,CAAM,EAErCF,EAAS,kBACTA,EAAS,iBAAkBG,GAAU,CACjC,KAAK,gBAAgBA,EAAOD,EAAO,MAAM,CAC7C,CAAC,EAGD,KAAK,YACLF,EAAS,MAAM,EAEZ,IACX,CAIA,gBAAgBG,EAAOC,EAAgB,CAEnC,KAAK,iBAAmB,KAAK,iBAG7B,IAAMC,EAAeF,EAAM,OAASC,EACpC,KAAK,gBAAkB,KAAK,IAAI,KAAK,kBAAmB,KAAK,gBAAkBC,CAAY,CAC/F,CAIA,eAAeC,EAAM,CACjB,IAAMJ,EAAS,KAAK,WAAW,IAAII,CAAI,EACvC,OAAIJ,IACI,KAAK,YACLA,EAAO,SAAS,KAAK,EAEzB,KAAK,WAAW,OAAOI,CAAI,GAExB,IACX,CAIA,mBAAmBA,EAAMC,EAAS,CAC9B,IAAML,EAAS,KAAK,WAAW,IAAII,CAAI,EACvC,OAAIJ,IACAA,EAAO,QAAUK,EAEb,CAACA,GAAW,KAAK,YACjBL,EAAO,SAAS,KAAK,EAGrBK,GAAW,KAAK,YAChBL,EAAO,SAAS,MAAM,GAGvB,IACX,CAIA,eAAgB,CACZ,OAAO,KAAK,UAChB,CAIA,OAAQ,CACJ,GAAI,MAAK,WAIT,IAFA,KAAK,WAAa,GAEd,KAAK,eAAiB,OAAO,SAAa,MAC1C,KAAK,wBAA0B,KAAK,uBAAuB,KAAK,IAAI,EACpE,SAAS,iBAAiB,mBAAoB,KAAK,uBAAuB,EAEtE,SAAS,QAAQ,CACjB,KAAK,qBAAuB,GAC5B,MACJ,CAGJ,OAAW,CAACM,EAAGN,CAAM,IAAK,KAAK,WACvBA,EAAO,SACPA,EAAO,SAAS,MAAM,EAI9B,KAAK,UAAU,EACnB,CAIA,MAAO,CACH,GAAK,KAAK,WAEV,MAAK,WAAa,GAClB,KAAK,qBAAuB,GAExB,KAAK,yBAA2B,OAAO,SAAa,MACpD,SAAS,oBAAoB,mBAAoB,KAAK,uBAAuB,EAC7E,KAAK,wBAA0B,MAGnC,OAAW,CAACM,EAAGN,CAAM,IAAK,KAAK,WAC3BA,EAAO,SAAS,KAAK,EAGzB,KAAK,SAAS,EAClB,CAIA,OAAQ,CACJ,KAAK,gBAAkB,EACvB,OAAW,CAACM,EAAGN,CAAM,IAAK,KAAK,WAC3BA,EAAO,SAAS,MAAM,CAE9B,CAIA,MAAM,MAAMO,EAAU,CAAC,EAAG,CACtB,IAAMC,EAAY,KAAK,uBAAuB,EACxCC,EAAS,CACX,MAAOD,EAAU,OACrB,EACA,OAAID,EAAQ,YACRE,EAAO,UAAYD,GAIhBC,CACX,CAIA,UAAW,CACP,OAAO,KAAK,UAChB,CAIA,UAAW,CACP,OAAO,KAAK,oBAChB,CAIA,eAAgB,CACZ,IAAIC,EAAIC,EACR,IAAMC,EAAS,CAAC,EAChB,OAAW,CAACR,EAAMJ,CAAM,IAAK,KAAK,WAAY,CAC1C,IAAMa,GAASF,GAAMD,EAAKV,EAAO,UAAU,gBAAkB,MAAQW,IAAO,OAAS,OAASA,EAAG,KAAKD,CAAE,EACrDG,GAAM,aAAgB,SACrED,EAAOR,CAAI,EAAIS,EAAM,WAE7B,CACA,OAAOD,CACX,CAIA,sBAAuB,CACnB,IAAMC,EAAQ,CAAC,EACf,OAAW,CAACT,EAAMJ,CAAM,IAAK,KAAK,WAC1BA,EAAO,SAAS,eAChBa,EAAMT,CAAI,EAAIJ,EAAO,SAAS,aAAa,GAGnD,OAAOa,CACX,CAMA,eAAgB,CACZ,OAAO,KAAK,IAAI,EAAG,KAAK,eAAe,CAC3C,CAKA,iBAAiBC,EAAY,GAAK,CAC9B,OAAO,KAAK,cAAc,GAAKA,CACnC,CAIA,SAAU,CACN,KAAK,KAAK,EACV,KAAK,WAAW,MAAM,CAC1B,CAIA,wBAAyB,CACrB,GAAK,KAAK,YAEV,GAAI,SAAS,QAET,GAAI,CAAC,KAAK,qBAAsB,CAC5B,KAAK,qBAAuB,GAE5B,OAAW,CAACR,EAAGN,CAAM,IAAK,KAAK,WACvBA,EAAO,SACPA,EAAO,SAAS,KAAK,EAI7B,KAAK,SAAS,CAClB,UAII,KAAK,qBAAsB,CAC3B,KAAK,qBAAuB,GAE5B,OAAW,CAACM,EAAGN,CAAM,IAAK,KAAK,WACvBA,EAAO,SACPA,EAAO,SAAS,MAAM,EAI9B,KAAK,UAAU,CACnB,EAER,CAIA,WAAY,CACJ,KAAK,eAAiB,OAE1B,KAAK,aAAe,OAAO,YAAY,IAAM,CACzC,IAAMe,EAAM,KAAK,IAAI,EACrB,OAAW,CAACT,EAAGN,CAAM,IAAK,KAAK,WACvBA,EAAO,SAAWA,EAAO,SAAS,QAClCA,EAAO,SAAS,OAAOe,CAAG,CAGtC,EAAG,KAAK,cAAc,EAC1B,CAIA,UAAW,CACH,KAAK,eAAiB,OACtB,cAAc,KAAK,YAAY,EAC/B,KAAK,aAAe,KAE5B,CAIA,wBAAyB,CACrB,IAAMC,EAAU,CAAC,EACXC,EAAU,CAAC,EACbC,EAAc,EACdC,EAAc,EAClB,OAAW,CAACf,EAAMJ,CAAM,IAAK,KAAK,WAAY,CAC1C,GAAI,CAACA,EAAO,QACR,SACJ,IAAMoB,EAAQpB,EAAO,SAAS,MAAM,EACpCgB,EAAQZ,CAAI,EAAIgB,EAChBH,EAAQb,CAAI,EAAIJ,EAAO,OACIoB,GAAU,OACjCF,GAAelB,EAAO,OACtBmB,GAAeC,EAAQpB,EAAO,OAEtC,CACA,IAAMqB,EAAUH,EAAc,EAAIC,EAAcD,EAAc,GAC9D,MAAO,CACH,QAAS,KAAK,IAAI,EAAG,KAAK,IAAI,EAAGG,CAAO,CAAC,EACzC,QAAAL,EACA,QAAAC,CACJ,CACJ,CACJ,EC1SO,IAAMK,EAAN,KAAmB,CACtB,aAAc,CACV,KAAK,cAAgB,IACzB,CACA,iBAAiBC,EAAU,CACvB,KAAK,cAAgBA,CACzB,CACA,YAAYC,EAAQ,CACZ,KAAK,eACL,KAAK,cAAc,CACf,SAAU,KAAK,KACf,OAAAA,EACA,UAAW,KAAK,IAAI,CACxB,CAAC,CAET,CACJ,EClBO,SAASC,EAAQC,EAAGC,EAAW,EAAGC,EAAY,EAAG,CACpD,MAAO,IAAK,EAAI,KAAK,IAAI,CAACA,GAAaF,EAAIC,EAAS,EACxD,CAIO,SAASE,EAAeH,EAAGC,EAAW,EAAGC,EAAY,EAAG,CAC3D,MAAO,GAAIH,EAAQC,EAAGC,EAAUC,CAAS,CAC7C,CAOO,SAASE,EAASJ,EAAGK,EAAQ,EAAGC,EAAQ,EAAG,CAC9C,IAAMC,EAAW,CAAC,KAAK,IAAIP,EAAIK,EAAO,CAAC,GAAK,EAAIC,EAAQA,GACxD,OAAO,KAAK,IAAIC,CAAQ,CAC5B,CA0BO,SAASC,EAAoBC,EAAQ,CACxC,GAAIA,EAAO,SAAW,EAClB,MAAO,CAAE,KAAM,EAAG,SAAU,EAAG,OAAQ,EAAG,GAAI,CAAE,EAEpD,IAAMC,EAAOD,EAAO,OAAO,CAACE,EAAGC,IAAMD,EAAIC,EAAG,CAAC,EAAIH,EAAO,OAClDI,EAAWJ,EAAO,OAAO,CAACK,EAAKC,IAAMD,GAAOC,EAAIL,IAAS,EAAG,CAAC,EAAID,EAAO,OACxEO,EAAS,KAAK,KAAKH,CAAQ,EAC3BI,EAAKP,EAAO,EAAIM,EAASN,EAAO,EACtC,MAAO,CAAE,KAAAA,EAAM,SAAAG,EAAU,OAAAG,EAAQ,GAAAC,CAAG,CACxC,CAQO,SAASC,EAAiBC,EAAW,CACxC,GAAIA,EAAU,OAAS,EACnB,OAEJ,IAAMC,EAAc,IAAI,IAAID,EAAU,IAAIE,GAAK,KAAK,MAAMA,EAAI,EAAE,CAAC,CAAC,EAAE,KAC9DC,EAAeF,IAAgB,EAGrC,MAAO,CACH,WAFeZ,EAAoBW,CAAS,EAG5C,YAAAC,EACA,aAAAE,CACJ,CACJ,CAMO,SAASC,EAA4BN,EAAI,CAI5C,OAAIA,EAAK,IACE,GACPA,EAAK,EACE,GAEJO,EAASP,EAAI,IAAM,GAAI,CAClC,CC7FO,IAAMQ,EAAN,cAA4BC,CAAa,CAC5C,YAAYC,EAAS,CACjB,MAAM,EACN,KAAK,KAAO,QACZ,KAAK,cAAgB,GACrB,KAAK,eAAiB,CAAC,EACvB,KAAK,YAAc,CAAC,EACpB,KAAK,aAAe,KACpB,KAAK,UAAY,EACjB,KAAK,gBAAkB,EACvB,KAAK,gBAAkB,IACvB,KAAK,SAAW,KAChB,KAAK,cAAgB,KACrB,KAAK,SAAW,GAChB,KAAK,eAAiB,EACiCA,GAAQ,gBAAmB,SAC9E,KAAK,gBAAkBA,EAAQ,cACvC,CACA,OAAQ,CACJ,GAAI,KAAK,SACL,OACJ,KAAK,SAAW,GAEhB,IAAMC,EAAQ,OAAO,WACfC,EAAS,OAAO,YACtB,KAAK,eAAiB,KAAK,KAAKD,EAAQA,EAAQC,EAASA,CAAM,EAC/D,KAAK,SAAYC,GAAM,CACnB,IAAMC,EAAaD,EACbE,EAAM,KAAK,IAAI,EACfC,EAAa,CAAE,EAAGF,EAAW,QAAS,EAAGA,EAAW,OAAQ,EAElE,GAAI,KAAK,aAAc,CACnB,IAAMG,EAAKD,EAAW,EAAI,KAAK,aAAa,EACtCE,EAAKF,EAAW,EAAI,KAAK,aAAa,EAItCG,EAHgB,KAAK,KAAKF,EAAKA,EAAKC,EAAKA,CAAE,EAGN,KAAK,eAEhD,GAAIC,EAAqB,KAAO,CAC5B,IAAMC,EAAW,KAAK,MAAMF,EAAID,CAAE,EAE9BI,EAAYD,EAAW,KAAK,UAEhC,KAAOC,EAAY,KAAK,IACpBA,GAAa,EAAI,KAAK,GAC1B,KAAOA,EAAY,CAAC,KAAK,IACrBA,GAAa,EAAI,KAAK,GAC1B,KAAK,iBAAmBA,EACxB,KAAK,UAAYD,EAEjB,KAAK,eAAe,KAAK,CAAE,MAAOD,EAAoB,UAAWJ,CAAI,CAAC,EACtE,KAAK,YAAY,KAAK,CAAE,MAAO,KAAK,gBAAiB,UAAWA,CAAI,CAAC,EAErE,KAAK,YAAY,KAAK,IAAI,EAAGI,EAAqB,GAAG,CAAC,CAC1D,CAGA,IAAMG,EAASP,EAAM,KAAK,gBAC1B,KAAO,KAAK,eAAe,OAAS,GAAK,KAAK,eAAe,CAAC,EAAE,UAAYO,GACxE,KAAK,eAAe,MAAM,EAC1B,KAAK,YAAY,MAAM,CAE/B,CACA,KAAK,aAAeN,CACxB,EACA,SAAS,iBAAiB,YAAa,KAAK,SAAU,CAAE,QAAS,EAAK,CAAC,EAEvE,KAAK,cAAgB,IAAM,CACvB,KAAK,eAAiB,CAAC,EACvB,KAAK,YAAc,CAAC,EACpB,KAAK,aAAe,KACpB,KAAK,UAAY,EACjB,KAAK,gBAAkB,CAC3B,EACA,SAAS,iBAAiB,aAAc,KAAK,cAAe,CAAE,QAAS,EAAK,CAAC,CACjF,CACA,MAAO,CACE,KAAK,WAEV,KAAK,SAAW,GACZ,KAAK,WACL,SAAS,oBAAoB,YAAa,KAAK,QAAQ,EACvD,KAAK,SAAW,MAEhB,KAAK,gBACL,SAAS,oBAAoB,aAAc,KAAK,aAAa,EAC7D,KAAK,cAAgB,MAE7B,CACA,OAAQ,CACJ,KAAK,eAAiB,CAAC,EACvB,KAAK,YAAc,CAAC,EACpB,KAAK,aAAe,KACpB,KAAK,UAAY,EACjB,KAAK,gBAAkB,CAC3B,CACA,OAAQ,CACJ,GAAI,OAAK,eAAe,OAAS,IAIjC,OAAO,KAAK,oBAAoB,CACpC,CAKA,qBAAsB,CAClB,GAAI,KAAK,eAAe,OAAS,GAC7B,OACJ,IAAIO,EAAQ,EACRC,EAAU,EAERC,EAAY,KAAK,eAAe,IAAIC,GAAKA,EAAE,KAAK,EACtD,GAAID,EAAU,QAAU,EAAG,CACvB,IAAME,EAAQC,EAAoBH,CAAS,EAI3CF,GAASM,EAASF,EAAM,GAAI,GAAK,GAAI,EACrCH,GACJ,CAEA,IAAMM,EAAS,KAAK,YAAY,IAAIJ,GAAKA,EAAE,KAAK,EAChD,GAAII,EAAO,QAAU,EAAG,CACpB,IAAMC,EAAe,CAAC,EACtB,QAASC,EAAI,EAAGA,EAAIF,EAAO,OAAQE,IAC/BD,EAAa,KAAK,KAAK,IAAID,EAAOE,CAAC,EAAIF,EAAOE,EAAI,CAAC,CAAC,CAAC,EAEzD,IAAMC,EAAYF,EAAa,OAAO,CAAC,EAAGG,IAAM,EAAIA,EAAG,CAAC,EAAIH,EAAa,OAGzER,GAASM,EAASI,EAAW,IAAM,GAAI,EACvCT,GACJ,CACA,OAAOA,EAAU,EAAID,EAAQC,EAAU,MAC3C,CACA,cAAe,CACX,MAAO,CACH,WAAY,KAAK,eAAe,OAChC,cAAe,KAAK,gBACpB,SAAU,KAAK,SACf,eAAgB,KAAK,eACrB,YAAa,KAAK,WACtB,CACJ,CACJ,ECnJO,IAAMW,EAAN,cAA6BC,CAAa,CAC7C,YAAYC,EAAS,CACjB,MAAM,EACN,KAAK,KAAO,SACZ,KAAK,cAAgB,IACrB,KAAK,eAAiB,CAAC,EACvB,KAAK,eAAiB,CAAC,EACvB,KAAK,YAAc,KACnB,KAAK,cAAgB,EACrB,KAAK,gBAAkB,IACvB,KAAK,eAAiB,EACtB,KAAK,SAAW,KAChB,KAAK,SAAW,GACuCA,GAAQ,gBAAmB,SAC9E,KAAK,gBAAkBA,EAAQ,cACvC,CACA,OAAQ,CACA,KAAK,WAET,KAAK,SAAW,GAEhB,KAAK,eAAiB,KAAK,IAAI,SAAS,KAAK,aAAc,SAAS,gBAAgB,aAAc,CAAC,EACnG,KAAK,SAAYC,GAAO,CACpB,IAAMC,EAAU,OAAO,QACjBC,EAAM,KAAK,IAAI,EAErB,GAAI,KAAK,cAAgB,KAAM,CAC3B,KAAK,YAAcD,EACnB,KAAK,cAAgBC,EACrB,MACJ,CACA,IAAMC,EAAaF,EAAU,KAAK,YAC5BG,EAAYF,EAAM,KAAK,cAE7B,GAAIC,IAAe,EACf,OAGJ,IAAME,EAAqB,KAAK,IAAIF,CAAU,EAAI,KAAK,eAEvD,GAAIC,EAAY,EAAG,CACf,IAAME,EAAWD,EAAqBD,EAEtC,KAAK,eAAe,KAAK,CAAE,MAAOC,EAAoB,UAAWH,CAAI,CAAC,EACtE,KAAK,eAAe,KAAK,CAAE,MAAOI,EAAU,UAAWJ,CAAI,CAAC,EAE5D,KAAK,YAAY,KAAK,IAAI,EAAGG,EAAqB,EAAE,CAAC,EAErD,IAAME,EAASL,EAAM,KAAK,gBAC1B,KAAO,KAAK,eAAe,OAAS,GAAK,KAAK,eAAe,CAAC,EAAE,UAAYK,GACxE,KAAK,eAAe,MAAM,EAC1B,KAAK,eAAe,MAAM,CAElC,CACA,KAAK,YAAcN,EACnB,KAAK,cAAgBC,CACzB,EAEA,OAAO,iBAAiB,SAAU,KAAK,SAAU,CAAE,QAAS,EAAK,CAAC,EACtE,CACA,MAAO,CACE,KAAK,WAEV,KAAK,SAAW,GACZ,KAAK,WACL,OAAO,oBAAoB,SAAU,KAAK,QAAQ,EAClD,KAAK,SAAW,MAExB,CACA,OAAQ,CACJ,KAAK,eAAiB,CAAC,EACvB,KAAK,eAAiB,CAAC,EACvB,KAAK,YAAc,KACnB,KAAK,cAAgB,CACzB,CACA,OAAQ,CACJ,GAAI,OAAK,eAAe,OAAS,GAGjC,OAAO,KAAK,qBAAqB,CACrC,CAKA,sBAAuB,CACnB,GAAI,KAAK,eAAe,OAAS,EAC7B,OACJ,IAAIM,EAAQ,EACRC,EAAU,EAERC,EAAY,KAAK,eAAe,IAAIC,GAAKA,EAAE,KAAK,EACtD,GAAID,EAAU,QAAU,GAEI,IAAI,IAAIA,EAAU,IAAIE,GAAK,KAAK,MAAMA,EAAI,GAAI,CAAC,CAAC,EAAE,OAClD,EAEpB,MAAO,KAIf,GAAIF,EAAU,QAAU,EAAG,CACvB,IAAMG,EAAQC,EAAoBJ,CAAS,EAI3CF,GAASO,EAASF,EAAM,GAAI,EAAK,EAAG,EACpCJ,GACJ,CAEA,IAAMO,EAAa,KAAK,eAAe,IAAIL,GAAKA,EAAE,KAAK,EACvD,GAAIK,EAAW,QAAU,EAAG,CACxB,IAAMH,EAAQC,EAAoBE,CAAU,EAG5CR,GAASO,EAASF,EAAM,GAAI,IAAK,EAAG,EACpCJ,GACJ,CAEA,IAAMQ,EAAeP,EAAU,OAAOE,GAAKA,EAAI,EAAG,EAAE,OACpD,GAAIF,EAAU,OAAS,EAAG,CACtB,IAAMQ,EAAYD,EAAeP,EAAU,OAE3CF,GAASW,EAAeD,EAAW,GAAK,EAAE,EAC1CT,GACJ,CACA,OAAOA,EAAU,EAAID,EAAQC,EAAU,MAC3C,CACA,cAAe,CACX,MAAO,CACH,WAAY,KAAK,eAAe,OAChC,cAAe,KAAK,gBACpB,SAAU,KAAK,SACf,eAAgB,KAAK,eACrB,eAAgB,KAAK,cACzB,CACJ,CACJ,EC3IO,IAAMW,EAAN,cAA4BC,CAAa,CAC5C,YAAYC,EAAS,CACjB,MAAM,EACN,KAAK,KAAO,QACZ,KAAK,cAAgB,GACrB,KAAK,OAAS,CAAC,EACf,KAAK,gBAAkB,CAAC,SAAU,IAAK,uBAAwB,iBAAiB,EAChF,KAAK,kBAAoB,KACzB,KAAK,cAAgB,KACrB,KAAK,eAAiB,IAAI,IAC1B,KAAK,SAAW,GACsCA,GAAQ,kBAC1D,KAAK,gBAAkBA,EAAQ,gBAEvC,CACA,OAAQ,CACA,KAAK,WAET,KAAK,SAAW,GAEhB,KAAK,cAAiBC,GAAM,CACxB,IAAMC,EAAaD,EACnB,KAAK,kBAAoB,CACrB,EAAGC,EAAW,QACd,EAAGA,EAAW,OAClB,CACJ,EACA,SAAS,iBAAiB,YAAa,KAAK,cAAe,CAAE,QAAS,EAAK,CAAC,EAE5E,KAAK,qBAAqB,EAC9B,CAIA,UAAUC,EAAU,CACX,KAAK,gBAAgB,SAASA,CAAQ,IACvC,KAAK,gBAAgB,KAAKA,CAAQ,EAE9B,KAAK,UACL,KAAK,gCAAgCA,CAAQ,EAGzD,CACA,sBAAuB,CACnB,KAAK,gBAAgB,QAAQA,GAAY,CACrC,KAAK,gCAAgCA,CAAQ,CACjD,CAAC,CACL,CACA,gCAAgCA,EAAU,CACrB,SAAS,iBAAiBA,CAAQ,EAC1C,QAAQC,GAAW,CACxB,GAAI,KAAK,eAAe,IAAIA,CAAO,EAC/B,OACJ,IAAMC,EAAYJ,GAAM,CACpB,IAAIK,EAAIC,EACR,IAAMC,EAAaP,EACbQ,EAAOL,EAAQ,sBAAsB,EAErCM,EAAcD,EAAK,KAAO,GAC5BA,EAAK,MAAQ,GACbA,EAAK,QAAU,OAAO,aACtBA,EAAK,OAAS,OAAO,WAErBE,EACJ,GAAI,CAAC,KAAK,kBACNA,EAAW,oBAEV,CACD,IAAMC,EAAK,KAAK,kBAAkB,EAC5BC,EAAK,KAAK,kBAAkB,EAMlC,GAAI,EAJiBD,GAAMH,EAAK,MAC5BG,GAAMH,EAAK,OACXI,GAAMJ,EAAK,KACXI,GAAMJ,EAAK,QAEXE,EAAW,cAEV,CAED,IAAMG,EAAUL,EAAK,KAAOA,EAAK,MAAQ,EACnCM,EAAUN,EAAK,IAAMA,EAAK,OAAS,EACd,KAAK,MAAMG,EAAKE,IAAY,GAAKD,EAAKE,IAAY,CAAC,EAErD,EACrBJ,EAAW,cAGXA,EAAW,cAEnB,CACJ,CACA,KAAK,OAAO,KAAK,CACb,OAAQH,EAAW,QACnB,OAAQA,EAAW,QACnB,QAASF,EAAK,KAAK,qBAAuB,MAAQA,IAAO,OAAS,OAASA,EAAG,EAC9E,QAASC,EAAK,KAAK,qBAAuB,MAAQA,IAAO,OAAS,OAASA,EAAG,EAC9E,KAAAE,EACA,WAAAC,EACA,SAAAC,EACA,UAAW,KAAK,IAAI,CACxB,CAAC,EAED,KAAK,YAAY,CAAG,CACxB,EACAP,EAAQ,iBAAiB,QAASC,CAAQ,EAC1C,KAAK,eAAe,IAAID,EAASC,CAAQ,CAC7C,CAAC,CACL,CACA,MAAO,CACE,KAAK,WAEV,KAAK,SAAW,GAEZ,KAAK,gBACL,SAAS,oBAAoB,YAAa,KAAK,aAAa,EAC5D,KAAK,cAAgB,MAGzB,KAAK,eAAe,QAAQ,CAACA,EAAUD,IAAY,CAC/CA,EAAQ,oBAAoB,QAASC,CAAQ,CACjD,CAAC,EACD,KAAK,eAAe,MAAM,EAC9B,CACA,OAAQ,CACJ,KAAK,OAAS,CAAC,EACf,KAAK,kBAAoB,IAC7B,CACA,OAAQ,CACJ,GAAI,KAAK,OAAO,SAAW,EACvB,OACJ,IAAIW,EAAa,EACjB,QAAWC,KAAS,KAAK,OACrB,OAAQA,EAAM,SAAU,CACpB,IAAK,gBACDD,GAAc,EACd,MACJ,IAAK,UACDA,GAAc,EACd,MACJ,IAAK,cACDA,GAAc,GACd,MACJ,IAAK,eACDA,GAAc,EACd,KACR,CAEJ,OAAOA,EAAa,KAAK,OAAO,MACpC,CACA,cAAe,CACX,MAAO,CACH,WAAY,KAAK,OAAO,OACxB,UAAW,CACP,YAAa,KAAK,OAAO,OAAOf,GAAKA,EAAE,WAAa,eAAe,EAAE,OACrE,QAAS,KAAK,OAAO,OAAOA,GAAKA,EAAE,WAAa,SAAS,EAAE,OAC3D,WAAY,KAAK,OAAO,OAAOA,GAAKA,EAAE,WAAa,aAAa,EAAE,OAClE,YAAa,KAAK,OAAO,OAAOA,GAAKA,EAAE,WAAa,cAAc,EAAE,MACxE,EACA,WAAY,KAAK,OAAO,OAAOA,GAAKA,EAAE,UAAU,EAAE,OAClD,gBAAiB,KAAK,eAAe,IACzC,CACJ,CACJ,ECjKO,IAAMiB,EAAN,cAA0BC,CAAa,CAC1C,YAAYC,EAAS,CACjB,MAAM,EACN,KAAK,KAAO,MACZ,KAAK,cAAgB,IACrB,KAAK,OAAS,CAAC,EACf,KAAK,gBAAkB,CAAC,SAAU,IAAK,uBAAwB,iBAAiB,EAChF,KAAK,oBAAsB,IAAI,IAC/B,KAAK,kBAAoB,IAAI,IAC7B,KAAK,cAAgB,IAAI,IACzB,KAAK,SAAW,GACsCA,GAAQ,kBAC1D,KAAK,gBAAkBA,EAAQ,gBAEvC,CACA,OAAQ,CACA,KAAK,WAET,KAAK,SAAW,GAChB,KAAK,qBAAqB,EAC9B,CACA,UAAUC,EAAU,CACX,KAAK,gBAAgB,SAASA,CAAQ,IACvC,KAAK,gBAAgB,KAAKA,CAAQ,EAC9B,KAAK,UACL,KAAK,gCAAgCA,CAAQ,EAGzD,CACA,sBAAuB,CACnB,KAAK,gBAAgB,QAAQA,GAAY,CACrC,KAAK,gCAAgCA,CAAQ,CACjD,CAAC,CACL,CACA,gCAAgCA,EAAU,CACrB,SAAS,iBAAiBA,CAAQ,EAC1C,QAAQC,GAAW,CACxB,GAAI,KAAK,oBAAoB,IAAIA,CAAO,EACpC,OACJ,IAAMC,EAAiBC,GAAM,CACzB,IAAMC,EAAaD,EAEnB,GAAIC,EAAW,QAAQ,SAAW,EAC9B,OACJ,IAAMC,EAAQD,EAAW,QAAQ,CAAC,EAClC,KAAK,cAAc,IAAIC,EAAM,WAAY,CACrC,EAAGA,EAAM,QACT,EAAGA,EAAM,QACT,UAAW,KAAK,IAAI,EACpB,QAAAJ,CACJ,CAAC,CACL,EACMK,EAAeH,GAAM,CACvB,IAAMC,EAAaD,EACnB,GAAIC,EAAW,eAAe,SAAW,EACrC,OACJ,IAAMC,EAAQD,EAAW,eAAe,CAAC,EACnCG,EAAY,KAAK,cAAc,IAAIF,EAAM,UAAU,EACzD,GAAI,CAACE,GAAaA,EAAU,UAAYN,EACpC,OACJ,IAAMO,EAAM,KAAK,IAAI,EACfC,EAAWD,EAAMD,EAAU,UAC3BG,EAAKL,EAAM,QAAUE,EAAU,EAC/BI,EAAKN,EAAM,QAAUE,EAAU,EAC/BK,EAAW,KAAK,KAAKF,EAAKA,EAAKC,EAAKA,CAAE,EACtCE,EAAOZ,EAAQ,sBAAsB,EACrCa,EAAcD,EAAK,KAAO,GAC5BA,EAAK,MAAQ,GACbA,EAAK,QAAU,OAAO,aACtBA,EAAK,OAAS,OAAO,WAEnBE,EAAKV,EAAM,QACXW,EAAKX,EAAM,QACXY,EAAeF,GAAMF,EAAK,MAC5BE,GAAMF,EAAK,OACXG,GAAMH,EAAK,KACXG,GAAMH,EAAK,OACXK,EACJ,GAAI,CAACD,EACDC,EAAW,cAEV,CACD,IAAMC,EAAUN,EAAK,KAAOA,EAAK,MAAQ,EACnCO,EAAUP,EAAK,IAAMA,EAAK,OAAS,EAGzCK,EAF2B,KAAK,MAAMH,EAAKI,IAAY,GAAKH,EAAKI,IAAY,CAAC,EAE9C,EAAI,cAAgB,cACxD,CACA,KAAK,OAAO,KAAK,CACb,EAAGL,EACH,EAAGC,EACH,KAAAH,EACA,WAAAC,EACA,SAAAI,EACA,SAAAT,EACA,SAAAG,EACA,UAAWJ,CACf,CAAC,EAED,KAAK,YAAY,CAAG,EACpB,KAAK,cAAc,OAAOH,EAAM,UAAU,CAC9C,EACAJ,EAAQ,iBAAiB,aAAcC,EAAe,CAAE,QAAS,EAAK,CAAC,EACvED,EAAQ,iBAAiB,WAAYK,EAAa,CAAE,QAAS,EAAK,CAAC,EACnE,KAAK,oBAAoB,IAAIL,EAASC,CAAa,EACnD,KAAK,kBAAkB,IAAID,EAASK,CAAW,CACnD,CAAC,CACL,CACA,MAAO,CACE,KAAK,WAEV,KAAK,SAAW,GAChB,KAAK,oBAAoB,QAAQ,CAACe,EAAUpB,IAAY,CACpDA,EAAQ,oBAAoB,aAAcoB,CAAQ,CACtD,CAAC,EACD,KAAK,oBAAoB,MAAM,EAC/B,KAAK,kBAAkB,QAAQ,CAACA,EAAUpB,IAAY,CAClDA,EAAQ,oBAAoB,WAAYoB,CAAQ,CACpD,CAAC,EACD,KAAK,kBAAkB,MAAM,EAC7B,KAAK,cAAc,MAAM,EAC7B,CACA,OAAQ,CACJ,KAAK,OAAS,CAAC,EACf,KAAK,cAAc,MAAM,CAC7B,CACA,OAAQ,CACJ,GAAI,KAAK,OAAO,SAAW,EACvB,OACJ,IAAIC,EAAQ,EACRC,EAAU,EAEVC,EAAgB,EACpB,QAAWC,KAAO,KAAK,OACnB,OAAQA,EAAI,SAAU,CAClB,IAAK,UACDD,GAAiB,EACjB,MACJ,IAAK,cACDA,GAAiB,GACjB,MACJ,IAAK,eACDA,GAAiB,EACjB,KACR,CAEJF,GAASE,EAAgB,KAAK,OAAO,OACrCD,IAEA,IAAMG,EAAY,KAAK,OAAO,IAAIvB,GAAKA,EAAE,QAAQ,EACjD,GAAIuB,EAAU,QAAU,EAAG,CACvB,IAAMC,EAAmBC,EAAiBF,CAAS,EACnD,GAAIC,EAAkB,CAClB,GAAM,CAAE,WAAAE,EAAY,aAAAC,CAAa,EAAIH,EAErC,GAAIG,EACA,MAAO,KAGXR,GAASS,EAA4BF,EAAW,EAAE,EAClDN,IAEAD,GAASU,EAASH,EAAW,KAAM,GAAI,EAAE,EACzCN,GACJ,CACJ,CAEA,IAAMU,EAAY,KAAK,OAAO,IAAI9B,GAAKA,EAAE,QAAQ,EACjD,GAAI8B,EAAU,OAAS,EAAG,CACtB,IAAMC,EAAcD,EAAU,OAAO,CAAC,EAAGE,IAAM,EAAIA,EAAG,CAAC,EAAIF,EAAU,OAErEX,GAASU,EAASE,EAAa,EAAG,CAAC,EACnCX,GACJ,CAEA,GAAI,KAAK,OAAO,QAAU,EAAG,CACzB,IAAMa,EAAY,CAAC,EACnB,QAASC,EAAI,EAAGA,EAAI,KAAK,OAAO,OAAQA,IACpCD,EAAU,KAAK,KAAK,OAAOC,CAAC,EAAE,UAAY,KAAK,OAAOA,EAAI,CAAC,EAAE,SAAS,EAE1E,IAAMC,EAAmBV,EAAiBQ,CAAS,EAC/CE,GAAoB,CAACA,EAAiB,eACtChB,GAASS,EAA4BO,EAAiB,WAAW,EAAE,EACnEf,IAER,CACA,OAAOA,EAAU,EAAID,EAAQC,EAAU,MAC3C,CACA,cAAe,CACX,MAAO,CACH,WAAY,KAAK,OAAO,OACxB,UAAW,CACP,QAAS,KAAK,OAAO,OAAOpB,GAAKA,EAAE,WAAa,SAAS,EAAE,OAC3D,WAAY,KAAK,OAAO,OAAOA,GAAKA,EAAE,WAAa,aAAa,EAAE,OAClE,YAAa,KAAK,OAAO,OAAOA,GAAKA,EAAE,WAAa,cAAc,EAAE,MACxE,EACA,UAAW,KAAK,OAAO,IAAIA,GAAKA,EAAE,QAAQ,EAC1C,UAAW,KAAK,OAAO,IAAIA,GAAKA,EAAE,QAAQ,EAC1C,WAAY,KAAK,OAAO,OAAOA,GAAKA,EAAE,UAAU,EAAE,OAClD,gBAAiB,KAAK,oBAAoB,IAC9C,CACJ,CACJ,EC1MO,IAAMoC,EAAN,cAA+BC,CAAa,CAC/C,YAAYC,EAAS,CACjB,MAAM,EACN,KAAK,KAAO,WACZ,KAAK,cAAgB,GACrB,KAAK,OAAS,CAAC,EACf,KAAK,gBAAkB,CAAC,qBAAsB,sBAAuB,UAAU,EAC/E,KAAK,eAAiB,KACtB,KAAK,uBAAyB,GAC9B,KAAK,mBAAqB,EAC1B,KAAK,sBAAwB,IAC7B,KAAK,aAAe,KACpB,KAAK,WAAa,KAClB,KAAK,eAAiB,IAAI,IAC1B,KAAK,cAAgB,IAAI,IACzB,KAAK,SAAW,GACsCA,GAAQ,kBAC1D,KAAK,gBAAkBA,EAAQ,gBAEvC,CACA,OAAQ,CACA,KAAK,WAET,KAAK,SAAW,GAEhB,KAAK,qBAAqB,EAE1B,KAAK,aAAgBC,GAAM,CACvB,GAAI,CAAC,KAAK,eACN,OACJ,IAAMC,EAAM,KAAK,IAAI,EACfC,EAAWF,EAEb,KAAK,mBAAqB,GAAKC,EAAM,KAAK,mBAAqB,KAAK,wBACpE,KAAK,OAAS,CAAC,GAEnB,KAAK,OAAO,KAAK,CACb,IAAKC,EAAS,IACd,KAAM,OACN,UAAWD,EACX,cAAe,KAAK,sBACxB,CAAC,EAED,KAAK,YAAY,EAAG,EACpB,KAAK,mBAAqBA,CAC9B,EACA,KAAK,WAAcD,GAAM,CACrB,GAAI,CAAC,KAAK,eACN,OACJ,IAAMC,EAAM,KAAK,IAAI,EACfC,EAAWF,EAEb,KAAK,mBAAqB,GAAKC,EAAM,KAAK,mBAAqB,KAAK,wBACpE,KAAK,OAAS,CAAC,GAEnB,KAAK,OAAO,KAAK,CACb,IAAKC,EAAS,IACd,KAAM,KACN,UAAWD,EACX,cAAe,KAAK,sBACxB,CAAC,EACD,KAAK,mBAAqBA,CAC9B,EACA,SAAS,iBAAiB,UAAW,KAAK,YAAY,EACtD,SAAS,iBAAiB,QAAS,KAAK,UAAU,EACtD,CAIA,UAAUE,EAAU,CACX,KAAK,gBAAgB,SAASA,CAAQ,IACvC,KAAK,gBAAgB,KAAKA,CAAQ,EAC9B,KAAK,UACL,KAAK,gCAAgCA,CAAQ,EAGzD,CACA,sBAAuB,CACnB,KAAK,gBAAgB,QAAQA,GAAY,CACrC,KAAK,gCAAgCA,CAAQ,CACjD,CAAC,CACL,CACA,gCAAgCA,EAAU,CACrB,SAAS,iBAAiBA,CAAQ,EAC1C,QAAQC,GAAW,CACxB,GAAI,KAAK,eAAe,IAAIA,CAAO,EAC/B,OACJ,IAAMC,EAAgB,IAAM,CACxB,KAAK,eAAiBD,EACtB,KAAK,uBAAyBD,CAClC,EACMG,EAAe,IAAM,CACvB,KAAK,eAAiB,KACtB,KAAK,uBAAyB,EAClC,EACAF,EAAQ,iBAAiB,QAASC,CAAa,EAC/CD,EAAQ,iBAAiB,OAAQE,CAAY,EAC7C,KAAK,eAAe,IAAIF,EAASC,CAAa,EAC9C,KAAK,cAAc,IAAID,EAASE,CAAY,CAChD,CAAC,CACL,CACA,MAAO,CACE,KAAK,WAEV,KAAK,SAAW,GACZ,KAAK,eACL,SAAS,oBAAoB,UAAW,KAAK,YAAY,EACzD,KAAK,aAAe,MAEpB,KAAK,aACL,SAAS,oBAAoB,QAAS,KAAK,UAAU,EACrD,KAAK,WAAa,MAGtB,KAAK,eAAe,QAAQ,CAACC,EAAUH,IAAY,CAC/CA,EAAQ,oBAAoB,QAASG,CAAQ,CACjD,CAAC,EACD,KAAK,eAAe,MAAM,EAC1B,KAAK,cAAc,QAAQ,CAACA,EAAUH,IAAY,CAC9CA,EAAQ,oBAAoB,OAAQG,CAAQ,CAChD,CAAC,EACD,KAAK,cAAc,MAAM,EACzB,KAAK,eAAiB,KAC1B,CACA,OAAQ,CACJ,KAAK,OAAS,CAAC,EACf,KAAK,eAAiB,KACtB,KAAK,uBAAyB,GAC9B,KAAK,mBAAqB,CAC9B,CACA,OAAQ,CACJ,GAAI,KAAK,OAAO,OAAS,EACrB,OACJ,IAAMC,EAAa,KAAK,OAAO,OAAOR,GAAKA,EAAE,OAAS,MAAM,EAC5D,GAAIQ,EAAW,OAAS,EACpB,OACJ,IAAIC,EAAQ,EACRC,EAAU,EAERC,EAAqB,CAAC,EAC5B,QAASC,EAAI,EAAGA,EAAIJ,EAAW,OAAQI,IACnCD,EAAmB,KAAKH,EAAWI,CAAC,EAAE,UAAYJ,EAAWI,EAAI,CAAC,EAAE,SAAS,EAEjF,IAAMC,EAAoBC,EAAiBH,CAAkB,EAC7D,GAAIE,EAAmB,CACnB,GAAM,CAAE,WAAAE,EAAY,aAAAC,CAAa,EAAIH,EAErC,GAAIG,EACA,MAAO,IAEX,IAAMC,EAAiBC,EAA4BH,EAAW,EAAE,EAIhE,GAHAN,GAASQ,EACTP,IAEIO,GAAkB,GAClB,OAAOA,CACf,CAEA,IAAME,EAAiB,CAAC,EACxB,QAASP,EAAI,EAAGA,EAAI,KAAK,OAAO,OAAS,EAAGA,IACpC,KAAK,OAAOA,CAAC,EAAE,OAAS,QAAU,KAAK,OAAOA,EAAI,CAAC,EAAE,OAAS,MAC9D,KAAK,OAAOA,CAAC,EAAE,MAAQ,KAAK,OAAOA,EAAI,CAAC,EAAE,KAC1CO,EAAe,KAAK,KAAK,OAAOP,EAAI,CAAC,EAAE,UAAY,KAAK,OAAOA,CAAC,EAAE,SAAS,EAGnF,IAAMQ,EAAwBN,EAAiBK,CAAc,EAC7D,GAAIC,EAAuB,CACvB,GAAM,CAAE,WAAAL,EAAY,aAAAC,CAAa,EAAII,EAErC,GAAIJ,EACA,MAAO,IAGX,GAAID,EAAW,KAAO,EAClBN,GAAS,GACTC,QAEC,CACD,IAAMW,EAAqBH,EAA4BH,EAAW,EAAE,EAIpE,GAHAN,GAASY,EACTX,IAEIW,GAAsB,GACtB,OAAOA,CACf,CACJ,CAEA,IAAMC,EAAiB,KAAK,OAAO,OAAOtB,GAAKA,EAAE,MAAQ,WAAW,EAAE,OACtE,GAAIsB,EAAiB,EAAG,CAEpB,IAAMC,EAAiBD,EAAiBd,EAAW,OAC/Ce,EAAiB,KAAQA,EAAiB,IAC1Cd,GAAS,EACTC,KAEKa,EAAiB,IACtBd,GAAS,GACTC,IAER,CACA,OAAOA,EAAU,EAAID,EAAQC,EAAU,MAC3C,CACA,cAAe,CAEX,IAAMS,EAAiB,CAAC,EACxB,QAASP,EAAI,EAAGA,EAAI,KAAK,OAAO,OAAS,EAAGA,IACpC,KAAK,OAAOA,CAAC,EAAE,OAAS,QAAU,KAAK,OAAOA,EAAI,CAAC,EAAE,OAAS,MAC9D,KAAK,OAAOA,CAAC,EAAE,MAAQ,KAAK,OAAOA,EAAI,CAAC,EAAE,KAC1CO,EAAe,KAAK,KAAK,OAAOP,EAAI,CAAC,EAAE,UAAY,KAAK,OAAOA,CAAC,EAAE,SAAS,EAGnF,MAAO,CACH,WAAY,KAAK,OAAO,OACxB,WAAY,KAAK,OAAO,OAAO,GAAK,EAAE,OAAS,MAAM,EAAE,OACvD,SAAU,KAAK,OAAO,OAAO,GAAK,EAAE,OAAS,IAAI,EAAE,OACnD,eAAgB,KAAK,OAAO,OAAO,GAAK,EAAE,MAAQ,WAAW,EAAE,OAC/D,eAAAO,EACA,eAAgB,KAAK,uBACrB,gBAAiB,KAAK,eAAe,IACzC,CACJ,CACJ,EC9NO,IAAMK,EAAN,cAAkCC,CAAa,CAClD,aAAc,CACV,MAAM,GAAG,SAAS,EAClB,KAAK,KAAO,cACZ,KAAK,cAAgB,IACrB,KAAK,KAAO,IAChB,CACA,OAAQ,CACJ,KAAK,mBAAmB,CAC5B,CACA,MAAO,CAEP,CACA,OAAQ,CACJ,KAAK,KAAO,IAChB,CACA,OAAOC,EAAY,CAEf,KAAK,mBAAmB,CAC5B,CACA,OAAQ,CACJ,GAAI,CAAC,KAAK,KACN,OACJ,IAAMC,EAAM,KAAK,KACbC,EAAQ,EACRC,EAAU,EAEdD,GAASD,EAAI,qBAAuB,GAAM,EAC1CC,GAASD,EAAI,gBAAkB,GAAM,EACrCC,GAASD,EAAI,qBAAuB,GAAM,EAC1CE,GAAW,EAEX,IAAMC,EAAe,CACjBH,EAAI,SACJA,EAAI,gBACJA,EAAI,kBACJA,EAAI,YACR,EAAE,OAAO,OAAO,EAAE,OAClB,OAAAC,GAASE,EAAe,EACxBD,IAEAD,GAASG,EAAeJ,EAAI,QAAS,GAAI,GAAI,EAC7CC,GAAUD,EAAI,QAAU,EAAI,EAAM,GAClCE,GAAW,EAEXD,GAASI,EAASL,EAAI,iBAAkB,EAAG,GAAG,EAC9CC,GAAUD,EAAI,aAAe,IAAMA,EAAI,aAAe,GAAM,EAAM,GAClEE,GAAW,EACJA,EAAU,EAAID,EAAQC,EAAU,MAC3C,CACA,gBAAiB,CAEb,IAAMI,EAAiB,UAAU,eAAiB,GAAK,iBAAkB,OACnEC,EAAW,iEAAiE,KAAK,UAAU,SAAS,EACpGC,EAAc,OAAO,WAAa,KAAO,OAAO,YAAc,KACpE,OAAQF,GAAkBE,GAAgBD,CAC9C,CACA,oBAAqB,CACjB,GAAI,CAEA,IAAIE,EAAW,GACf,GAAI,CACA,IAAMC,EAAS,SAAS,cAAc,QAAQ,EAC9CD,EAAW,CAAC,EAAEC,EAAO,WAAW,OAAO,GAAKA,EAAO,WAAW,oBAAoB,EACtF,MACU,CACND,EAAW,EACf,CAEA,IAAME,EAAY,CAAC,EAAE,OAAO,mBACxB,OAAO,sBACP,OAAO,yBAELC,EAAW,KAAK,eAAe,EAC/BC,EAAc,OAAO,WACrBC,EAAe,OAAO,YACtBC,EAAc,OAAO,OAAO,MAC5BC,EAAe,OAAO,OAAO,OAE7BC,EAAwBJ,IAAgB,KAAOC,IAAiB,KACjED,IAAgB,MAAQC,IAAiB,KACzCD,IAAgB,MAAQC,IAAiB,KACzCC,IAAgB,KAAOC,IAAiB,IAEvCE,EAAqBL,EAAcC,GAAiBC,EAAcC,GAClEG,EAAkBD,IAAsB,GAC1CA,EAAoB,IACpBA,EAAoB,EAElBE,EAAa,OAAO,aAAiB,KAAe,OAAO,eAAmB,IAC9EC,EAAwB,UAAU,QAAQ,SAAW,GAAK,UAAU,UAAU,SAAW,GAC3F,CAACZ,GACD,CAACW,EACL,KAAK,KAAO,CACR,YAAAL,EACA,aAAAC,EACA,YAAAH,EACA,aAAAC,EACA,iBAAkB,OAAO,iBACzB,WAAY,OAAO,OAAO,WAC1B,UAAW,UAAU,UACrB,SAAU,UAAU,SACpB,SAAU,UAAU,SACpB,UAAW,UAAU,UAAY,MAAM,KAAK,UAAU,SAAS,EAAI,CAAC,UAAU,QAAQ,EACtF,oBAAqB,UAAU,oBAC/B,eAAgB,UAAU,gBAAkB,EAC5C,OAAQ,UAAU,OAClB,SAAAL,EACA,UAAAE,EACA,gBAAiB,OAAO,aAAiB,IACzC,kBAAmB,OAAO,eAAmB,IAC7C,aAAc,cAAe,OAC7B,QAAS,UAAU,QAAQ,OAC3B,UAAW,UAAU,UAAU,OAC/B,gBAAAQ,EACA,qBAAAF,EACA,qBAAAI,EACA,SAAAT,EACA,UAAW,KAAK,IAAI,CACxB,CACJ,OACOU,EAAO,CACV,QAAQ,KAAK,iCAAkCA,CAAK,CACxD,CACJ,CACA,cAAe,CACX,OAAO,KAAK,IAChB,CAMA,UAAW,CACP,IAAIC,EAAIC,EACR,OAAQA,GAAMD,EAAK,KAAK,QAAU,MAAQA,IAAO,OAAS,OAASA,EAAG,YAAc,MAAQC,IAAO,OAASA,EAAK,IACrH,CACJ,EC1IO,IAAMC,EAAN,cAA6BC,CAAa,CAC7C,aAAc,CACV,MAAM,GAAG,SAAS,EAClB,KAAK,KAAO,SACZ,KAAK,cAAgB,IACrB,KAAK,OAAS,CAAC,EACf,KAAK,SAAW,KAChB,KAAK,SAAW,GAChB,KAAK,kBAAoB,KACzB,KAAK,cAAgB,IACzB,CACA,OAAQ,CACA,KAAK,WAET,KAAK,SAAW,GAEhB,KAAK,cAAiBC,GAAM,CACxB,IAAMC,EAAaD,EACnB,KAAK,kBAAoB,CACrB,EAAGC,EAAW,QACd,EAAGA,EAAW,OAClB,CACJ,EACA,SAAS,iBAAiB,YAAa,KAAK,cAAe,CAAE,QAAS,EAAK,CAAC,EAE5E,KAAK,SAAW,IAAM,CAClB,IAAIC,EAAIC,EACR,IAAMC,GAAUF,EAAK,KAAK,qBAAuB,MAAQA,IAAO,OAAS,OAASA,EAAG,EAC/EG,GAAUF,EAAK,KAAK,qBAAuB,MAAQA,IAAO,OAAS,OAASA,EAAG,EACjFG,EAAgB,GAChBF,IAAW,QAAaC,IAAW,SAEnCC,EAAiBF,EAAS,IACtBA,EAAS,OAAO,WAAa,IAC7BC,EAAS,IACTA,EAAS,OAAO,YAAc,IAEtC,KAAK,OAAO,KAAK,CACb,MAAO,OAAO,WACd,OAAQ,OAAO,YACf,OAAAD,EACA,OAAAC,EACA,cAAAC,EACA,UAAW,KAAK,IAAI,CACxB,CAAC,CACL,EACA,OAAO,iBAAiB,SAAU,KAAK,QAAQ,EACnD,CACA,MAAO,CACE,KAAK,WAEV,KAAK,SAAW,GACZ,KAAK,WACL,OAAO,oBAAoB,SAAU,KAAK,QAAQ,EAClD,KAAK,SAAW,MAEhB,KAAK,gBACL,SAAS,oBAAoB,YAAa,KAAK,aAAa,EAC5D,KAAK,cAAgB,MAE7B,CACA,OAAQ,CACJ,KAAK,OAAS,CAAC,CACnB,CACA,OAAQ,CACJ,GAAI,KAAK,OAAO,SAAW,EACvB,OACJ,IAAIC,EAAQ,EACRC,EAAU,EAEdD,GAASE,EAAe,KAAK,OAAO,OAAQ,EAAG,EAAG,EAClDD,IAEA,IAAME,EAAY,KAAK,OAAO,OAAOV,GAAKA,EAAE,SAAW,MAAS,EAChE,GAAIU,EAAU,OAAS,EAAG,CACtB,IAAMC,EAAWD,EAAU,OAAOV,GAAKA,EAAE,aAAa,EAAE,OACxDO,GAASK,EAAQD,EAAWD,EAAU,OAAQ,GAAK,CAAC,EACpDF,GACJ,CACA,OAAOA,EAAU,EAAID,EAAQC,EAAU,MAC3C,CACA,cAAe,CACX,MAAO,CACH,WAAY,KAAK,OAAO,OACxB,cAAe,KAAK,OAAO,OAAOR,GAAKA,EAAE,SAAW,MAAS,EAAE,MACnE,CACJ,CACJ,EC5FO,IAAMa,EAAmB,CAC5B,YAAa,CACT,UAAW,GACX,OAAQ,EACR,SAAU,CACd,EACA,eAAgB,CACZ,UAAW,IACX,OAAQ,GACZ,EACA,QAAS,CACL,cAAe,GACf,cAAe,GACf,eAAgB,IAChB,eAAgB,GAChB,YAAa,IACb,eAAgB,IAChB,uBAAwB,GAC5B,EACA,cAAe,CAAC,EAChB,wBAAyB,IACzB,aAAc,EAClB",
|
|
6
|
+
"names": ["BehaviorDetector", "tickOptions", "strategy", "weight", "config", "event", "strategyWeight", "contribution", "name", "enabled", "_", "options", "breakdown", "result", "_a", "_b", "counts", "debug", "threshold", "now", "factors", "weights", "totalWeight", "weightedSum", "score", "overall", "BaseStrategy", "callback", "weight", "sigmoid", "x", "midpoint", "steepness", "inverseSigmoid", "gaussian", "ideal", "width", "exponent", "calculateStatistics", "values", "mean", "a", "b", "variance", "sum", "v", "stdDev", "cv", "analyzeIntervals", "intervals", "uniqueCount", "i", "allIdentical", "scoreCoefficientOfVariation", "gaussian", "MouseStrategy", "BaseStrategy", "options", "width", "height", "e", "mouseEvent", "now", "currentPos", "dx", "dy", "normalizedDistance", "rawAngle", "angleDiff", "cutoff", "score", "factors", "distances", "p", "stats", "calculateStatistics", "gaussian", "angles", "angleChanges", "i", "avgChange", "b", "ScrollStrategy", "BaseStrategy", "options", "_e", "scrollY", "now", "pixelDelta", "deltaTime", "normalizedDistance", "velocity", "cutoff", "score", "factors", "distances", "p", "d", "stats", "calculateStatistics", "gaussian", "velocities", "instantJumps", "jumpRatio", "inverseSigmoid", "ClickStrategy", "BaseStrategy", "options", "e", "mouseEvent", "selector", "element", "listener", "_a", "_b", "clickEvent", "rect", "inViewport", "position", "mx", "my", "centerX", "centerY", "totalScore", "click", "TapStrategy", "BaseStrategy", "options", "selector", "element", "startListener", "e", "touchEvent", "touch", "endListener", "startData", "now", "duration", "dx", "dy", "movement", "rect", "inViewport", "tx", "ty", "overElement", "position", "centerX", "centerY", "listener", "score", "factors", "positionScore", "tap", "durations", "durationAnalysis", "analyzeIntervals", "statistics", "allIdentical", "scoreCoefficientOfVariation", "gaussian", "movements", "avgMovement", "b", "intervals", "i", "intervalAnalysis", "KeyboardStrategy", "BaseStrategy", "options", "e", "now", "keyEvent", "selector", "element", "focusListener", "blurListener", "listener", "downEvents", "score", "factors", "keystrokeIntervals", "i", "keystrokeAnalysis", "analyzeIntervals", "statistics", "allIdentical", "keystrokeScore", "scoreCoefficientOfVariation", "pressDurations", "pressDurationAnalysis", "pressDurationScore", "backspaceCount", "backspaceRatio", "EnvironmentStrategy", "BaseStrategy", "_timestamp", "env", "score", "factors", "featureCount", "inverseSigmoid", "gaussian", "hasTouchScreen", "mobileUA", "smallScreen", "hasWebGL", "canvas", "hasWebRTC", "isMobile", "windowWidth", "windowHeight", "screenWidth", "screenHeight", "suspiciousDimensions", "windowScreenRatio", "suspiciousRatio", "hasStorage", "featureInconsistency", "error", "_a", "_b", "ResizeStrategy", "BaseStrategy", "e", "mouseEvent", "_a", "_b", "mouseX", "mouseY", "mouseNearEdge", "score", "factors", "inverseSigmoid", "withMouse", "nearEdge", "sigmoid", "DEFAULT_SETTINGS"]
|
|
7
|
+
}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use strict";(()=>{var V=class{constructor(t){this.strategies=new Map,this.isTracking=!1,this.isPausedByVisibility=!1,this.tickInterval=null,this.tickIntervalMs=1e3,this.pauseOnHidden=!0,this.visibilityChangeHandler=null,this.confidenceScore=0,this.CONFIDENCE_TARGET=1,this.CONFIDENCE_DECAY=.95,t!=null&&t.interval&&(this.tickIntervalMs=t.interval),(t==null?void 0:t.pauseOnHidden)!==void 0&&(this.pauseOnHidden=t.pauseOnHidden)}addStrategy(t,e){let s={strategy:t,weight:e!=null?e:t.defaultWeight,enabled:!0};return this.strategies.set(t.name,s),t.setEventCallback&&t.setEventCallback(n=>{this.onStrategyEvent(n,s.weight)}),this.isTracking&&t.start(),this}onStrategyEvent(t,e){this.confidenceScore*=this.CONFIDENCE_DECAY;let s=t.weight*e;this.confidenceScore=Math.min(this.CONFIDENCE_TARGET,this.confidenceScore+s)}removeStrategy(t){let e=this.strategies.get(t);return e&&(this.isTracking&&e.strategy.stop(),this.strategies.delete(t)),this}setStrategyEnabled(t,e){let s=this.strategies.get(t);return s&&(s.enabled=e,!e&&this.isTracking&&s.strategy.stop(),e&&this.isTracking&&s.strategy.start()),this}getStrategies(){return this.strategies}start(){if(!this.isTracking){if(this.isTracking=!0,this.pauseOnHidden&&typeof document!="undefined"&&(this.visibilityChangeHandler=this.handleVisibilityChange.bind(this),document.addEventListener("visibilitychange",this.visibilityChangeHandler),document.hidden)){this.isPausedByVisibility=!0;return}for(let[t,e]of this.strategies)e.enabled&&e.strategy.start();this.startTick()}}stop(){if(this.isTracking){this.isTracking=!1,this.isPausedByVisibility=!1,this.visibilityChangeHandler&&typeof document!="undefined"&&(document.removeEventListener("visibilitychange",this.visibilityChangeHandler),this.visibilityChangeHandler=null);for(let[t,e]of this.strategies)e.strategy.stop();this.stopTick()}}reset(){this.confidenceScore=0;for(let[t,e]of this.strategies)e.strategy.reset()}async score(t={}){let e=this.calculateStrategyScore(),s={score:e.overall};return t.breakdown&&(s.breakdown=e),s}isActive(){return this.isTracking}isPaused(){return this.isPausedByVisibility}getEventCount(){var t,e;let s={};for(let[n,o]of this.strategies){let i=(e=(t=o.strategy).getDebugInfo)===null||e===void 0?void 0:e.call(t);(i==null?void 0:i.eventCount)!==void 0&&(s[n]=i.eventCount)}return s}getStrategyDebugInfo(){let t={};for(let[e,s]of this.strategies)s.strategy.getDebugInfo&&(t[e]=s.strategy.getDebugInfo());return t}getConfidence(){return Math.min(1,this.confidenceScore)}hasConfidentData(t=.3){return this.getConfidence()>=t}destroy(){this.stop(),this.strategies.clear()}handleVisibilityChange(){if(this.isTracking){if(document.hidden){if(!this.isPausedByVisibility){this.isPausedByVisibility=!0;for(let[t,e]of this.strategies)e.enabled&&e.strategy.stop();this.stopTick()}}else if(this.isPausedByVisibility){this.isPausedByVisibility=!1;for(let[t,e]of this.strategies)e.enabled&&e.strategy.start();this.startTick()}}}startTick(){this.tickInterval===null&&(this.tickInterval=window.setInterval(()=>{let t=Date.now();for(let[e,s]of this.strategies)s.enabled&&s.strategy.onTick&&s.strategy.onTick(t)},this.tickIntervalMs))}stopTick(){this.tickInterval!==null&&(clearInterval(this.tickInterval),this.tickInterval=null)}calculateStrategyScore(){let t={},e={},s=0,n=0;for(let[i,a]of this.strategies){if(!a.enabled)continue;let l=a.strategy.score();t[i]=l,e[i]=a.weight,l!=null&&(s+=a.weight,n+=l*a.weight)}let o=s>0?n/s:.5;return{overall:Math.max(0,Math.min(1,o)),factors:t,weights:e}}};var v=class{constructor(){this.eventCallback=null}setEventCallback(t){this.eventCallback=t}notifyEvent(t){this.eventCallback&&this.eventCallback({strategy:this.name,weight:t,timestamp:Date.now()})}};function X(c,t=0,e=1){return 1/(1+Math.exp(-e*(c-t)))}function x(c,t=0,e=1){return 1-X(c,t,e)}function y(c,t=0,e=1){let s=-Math.pow(c-t,2)/(2*e*e);return Math.exp(s)}function T(c){if(c.length===0)return{mean:0,variance:0,stdDev:0,cv:0};let t=c.reduce((o,i)=>o+i,0)/c.length,e=c.reduce((o,i)=>o+(i-t)**2,0)/c.length,s=Math.sqrt(e),n=t>0?s/t:0;return{mean:t,variance:e,stdDev:s,cv:n}}function C(c){if(c.length<2)return;let t=new Set(c.map(n=>Math.round(n/10))).size,e=t===1;return{statistics:T(c),uniqueCount:t,allIdentical:e}}function A(c){return c<.05?.1:c>2?.3:y(c,.45,.35)}var D=class extends v{constructor(t){super(),this.name="mouse",this.defaultWeight=.3,this.distanceSeries=[],this.angleSeries=[],this.lastPosition=null,this.lastAngle=0,this.cumulativeAngle=0,this.rollingWindowMs=5e3,this.listener=null,this.leaveListener=null,this.isActive=!1,this.screenDiagonal=1,(t==null?void 0:t.rollingWindow)!==void 0&&(this.rollingWindowMs=t.rollingWindow)}start(){if(this.isActive)return;this.isActive=!0;let t=window.innerWidth,e=window.innerHeight;this.screenDiagonal=Math.sqrt(t*t+e*e),this.listener=s=>{let n=s,o=Date.now(),i={x:n.clientX,y:n.clientY};if(this.lastPosition){let a=i.x-this.lastPosition.x,l=i.y-this.lastPosition.y,f=Math.sqrt(a*a+l*l)/this.screenDiagonal;if(f>.001){let g=Math.atan2(l,a),u=g-this.lastAngle;for(;u>Math.PI;)u-=2*Math.PI;for(;u<-Math.PI;)u+=2*Math.PI;this.cumulativeAngle+=u,this.lastAngle=g,this.distanceSeries.push({value:f,timestamp:o}),this.angleSeries.push({value:this.cumulativeAngle,timestamp:o}),this.notifyEvent(Math.min(1,f*100))}let h=o-this.rollingWindowMs;for(;this.distanceSeries.length>0&&this.distanceSeries[0].timestamp<h;)this.distanceSeries.shift(),this.angleSeries.shift()}this.lastPosition=i},document.addEventListener("mousemove",this.listener,{passive:!0}),this.leaveListener=()=>{this.distanceSeries=[],this.angleSeries=[],this.lastPosition=null,this.lastAngle=0,this.cumulativeAngle=0},document.addEventListener("mouseleave",this.leaveListener,{passive:!0})}stop(){this.isActive&&(this.isActive=!1,this.listener&&(document.removeEventListener("mousemove",this.listener),this.listener=null),this.leaveListener&&(document.removeEventListener("mouseleave",this.leaveListener),this.leaveListener=null))}reset(){this.distanceSeries=[],this.angleSeries=[],this.lastPosition=null,this.lastAngle=0,this.cumulativeAngle=0}score(){if(!(this.distanceSeries.length<10))return this.detectMousePatterns()}detectMousePatterns(){if(this.distanceSeries.length<10)return;let t=0,e=0,s=this.distanceSeries.map(o=>o.value);if(s.length>=3){let o=T(s);t+=y(o.cv,.9,.35),e++}let n=this.angleSeries.map(o=>o.value);if(n.length>=3){let o=[];for(let a=1;a<n.length;a++)o.push(Math.abs(n[a]-n[a-1]));let i=o.reduce((a,l)=>a+l,0)/o.length;t+=y(i,.15,.12),e++}return e>0?t/e:void 0}getDebugInfo(){return{eventCount:this.distanceSeries.length,rollingWindow:this.rollingWindowMs,isActive:this.isActive,distanceSeries:this.distanceSeries,angleSeries:this.angleSeries}}};var P=class extends v{constructor(t){super(),this.name="scroll",this.defaultWeight=.15,this.distanceSeries=[],this.velocitySeries=[],this.lastScrollY=null,this.lastTimestamp=0,this.rollingWindowMs=5e3,this.documentHeight=1,this.listener=null,this.isActive=!1,(t==null?void 0:t.rollingWindow)!==void 0&&(this.rollingWindowMs=t.rollingWindow)}start(){this.isActive||(this.isActive=!0,this.documentHeight=Math.max(document.body.scrollHeight,document.documentElement.scrollHeight,1),this.listener=t=>{let e=window.scrollY,s=Date.now();if(this.lastScrollY===null){this.lastScrollY=e,this.lastTimestamp=s;return}let n=e-this.lastScrollY,o=s-this.lastTimestamp;if(n===0)return;let i=Math.abs(n)/this.documentHeight;if(o>0){let a=i/o;this.distanceSeries.push({value:i,timestamp:s}),this.velocitySeries.push({value:a,timestamp:s}),this.notifyEvent(Math.min(1,i*10));let l=s-this.rollingWindowMs;for(;this.distanceSeries.length>0&&this.distanceSeries[0].timestamp<l;)this.distanceSeries.shift(),this.velocitySeries.shift()}this.lastScrollY=e,this.lastTimestamp=s},window.addEventListener("scroll",this.listener,{passive:!0}))}stop(){this.isActive&&(this.isActive=!1,this.listener&&(window.removeEventListener("scroll",this.listener),this.listener=null))}reset(){this.distanceSeries=[],this.velocitySeries=[],this.lastScrollY=null,this.lastTimestamp=0}score(){if(!(this.distanceSeries.length<2))return this.detectScrollPatterns()}detectScrollPatterns(){if(this.distanceSeries.length<2)return;let t=0,e=0,s=this.distanceSeries.map(i=>i.value);if(s.length>=2&&new Set(s.map(a=>Math.round(a*1e3))).size===1)return .05;if(s.length>=2){let i=T(s);t+=y(i.cv,1,.4),e++}let n=this.velocitySeries.map(i=>i.value);if(n.length>=2){let i=T(n);t+=y(i.cv,1.2,.5),e++}let o=s.filter(i=>i>.1).length;if(s.length>0){let i=o/s.length;t+=x(i,.3,15),e++}return e>0?t/e:void 0}getDebugInfo(){return{eventCount:this.distanceSeries.length,rollingWindow:this.rollingWindowMs,isActive:this.isActive,distanceSeries:this.distanceSeries,velocitySeries:this.velocitySeries}}};var I=class extends v{constructor(t){super(),this.name="click",this.defaultWeight=.3,this.events=[],this.targetSelectors=["button","a",'input[type="submit"]','[role="button"]'],this.lastMousePosition=null,this.mouseListener=null,this.clickListeners=new Map,this.isActive=!1,t!=null&&t.targetSelectors&&(this.targetSelectors=t.targetSelectors)}start(){this.isActive||(this.isActive=!0,this.mouseListener=t=>{let e=t;this.lastMousePosition={x:e.clientX,y:e.clientY}},document.addEventListener("mousemove",this.mouseListener,{passive:!0}),this.attachClickListeners())}addTarget(t){this.targetSelectors.includes(t)||(this.targetSelectors.push(t),this.isActive&&this.attachClickListenersForSelector(t))}attachClickListeners(){this.targetSelectors.forEach(t=>{this.attachClickListenersForSelector(t)})}attachClickListenersForSelector(t){document.querySelectorAll(t).forEach(s=>{if(this.clickListeners.has(s))return;let n=o=>{var i,a;let l=o,r=s.getBoundingClientRect(),f=r.top>=0&&r.left>=0&&r.bottom<=window.innerHeight&&r.right<=window.innerWidth,h;if(!this.lastMousePosition)h="no-mouse-data";else{let g=this.lastMousePosition.x,u=this.lastMousePosition.y;if(!(g>=r.left&&g<=r.right&&u>=r.top&&u<=r.bottom))h="outside";else{let d=r.left+r.width/2,b=r.top+r.height/2;Math.sqrt((g-d)**2+(u-b)**2)<2?h="dead-center":h="over-element"}}this.events.push({clickX:l.clientX,clickY:l.clientY,mouseX:(i=this.lastMousePosition)===null||i===void 0?void 0:i.x,mouseY:(a=this.lastMousePosition)===null||a===void 0?void 0:a.y,rect:r,inViewport:f,position:h,timestamp:Date.now()}),this.notifyEvent(1)};s.addEventListener("click",n),this.clickListeners.set(s,n)})}stop(){this.isActive&&(this.isActive=!1,this.mouseListener&&(document.removeEventListener("mousemove",this.mouseListener),this.mouseListener=null),this.clickListeners.forEach((t,e)=>{e.removeEventListener("click",t)}),this.clickListeners.clear())}reset(){this.events=[],this.lastMousePosition=null}score(){if(this.events.length===0)return;let t=0;for(let e of this.events)switch(e.position){case"no-mouse-data":t+=0;break;case"outside":t+=0;break;case"dead-center":t+=.5;break;case"over-element":t+=1;break}return t/this.events.length}getDebugInfo(){return{eventCount:this.events.length,positions:{noMouseData:this.events.filter(t=>t.position==="no-mouse-data").length,outside:this.events.filter(t=>t.position==="outside").length,deadCenter:this.events.filter(t=>t.position==="dead-center").length,overElement:this.events.filter(t=>t.position==="over-element").length},inViewport:this.events.filter(t=>t.inViewport).length,trackedElements:this.clickListeners.size}}};var _=class extends v{constructor(t){super(),this.name="tap",this.defaultWeight=.35,this.events=[],this.targetSelectors=["button","a",'input[type="submit"]','[role="button"]'],this.touchStartListeners=new Map,this.touchEndListeners=new Map,this.activeTouches=new Map,this.isActive=!1,t!=null&&t.targetSelectors&&(this.targetSelectors=t.targetSelectors)}start(){this.isActive||(this.isActive=!0,this.attachTouchListeners())}addTarget(t){this.targetSelectors.includes(t)||(this.targetSelectors.push(t),this.isActive&&this.attachTouchListenersForSelector(t))}attachTouchListeners(){this.targetSelectors.forEach(t=>{this.attachTouchListenersForSelector(t)})}attachTouchListenersForSelector(t){document.querySelectorAll(t).forEach(s=>{if(this.touchStartListeners.has(s))return;let n=i=>{let a=i;if(a.touches.length!==1)return;let l=a.touches[0];this.activeTouches.set(l.identifier,{x:l.clientX,y:l.clientY,timestamp:Date.now(),element:s})},o=i=>{let a=i;if(a.changedTouches.length!==1)return;let l=a.changedTouches[0],r=this.activeTouches.get(l.identifier);if(!r||r.element!==s)return;let f=Date.now(),h=f-r.timestamp,g=l.clientX-r.x,u=l.clientY-r.y,M=Math.sqrt(g*g+u*u),d=s.getBoundingClientRect(),b=d.top>=0&&d.left>=0&&d.bottom<=window.innerHeight&&d.right<=window.innerWidth,S=l.clientX,E=l.clientY,z=S>=d.left&&S<=d.right&&E>=d.top&&E<=d.bottom,k;if(!z)k="outside";else{let F=d.left+d.width/2,Y=d.top+d.height/2;k=Math.sqrt((S-F)**2+(E-Y)**2)<2?"dead-center":"over-element"}this.events.push({x:S,y:E,rect:d,inViewport:b,position:k,duration:h,movement:M,timestamp:f}),this.notifyEvent(1),this.activeTouches.delete(l.identifier)};s.addEventListener("touchstart",n,{passive:!0}),s.addEventListener("touchend",o,{passive:!0}),this.touchStartListeners.set(s,n),this.touchEndListeners.set(s,o)})}stop(){this.isActive&&(this.isActive=!1,this.touchStartListeners.forEach((t,e)=>{e.removeEventListener("touchstart",t)}),this.touchStartListeners.clear(),this.touchEndListeners.forEach((t,e)=>{e.removeEventListener("touchend",t)}),this.touchEndListeners.clear(),this.activeTouches.clear())}reset(){this.events=[],this.activeTouches.clear()}score(){if(this.events.length===0)return;let t=0,e=0,s=0;for(let i of this.events)switch(i.position){case"outside":s+=0;break;case"dead-center":s+=.5;break;case"over-element":s+=1;break}t+=s/this.events.length,e++;let n=this.events.map(i=>i.duration);if(n.length>=2){let i=C(n);if(i){let{statistics:a,allIdentical:l}=i;if(l)return .05;t+=A(a.cv),e++,t+=y(a.mean,95,40),e++}}let o=this.events.map(i=>i.movement);if(o.length>0){let i=o.reduce((a,l)=>a+l,0)/o.length;t+=y(i,2,3),e++}if(this.events.length>=3){let i=[];for(let l=1;l<this.events.length;l++)i.push(this.events[l].timestamp-this.events[l-1].timestamp);let a=C(i);a&&!a.allIdentical&&(t+=A(a.statistics.cv),e++)}return e>0?t/e:void 0}getDebugInfo(){return{eventCount:this.events.length,positions:{outside:this.events.filter(t=>t.position==="outside").length,deadCenter:this.events.filter(t=>t.position==="dead-center").length,overElement:this.events.filter(t=>t.position==="over-element").length},durations:this.events.map(t=>t.duration),movements:this.events.map(t=>t.movement),inViewport:this.events.filter(t=>t.inViewport).length,trackedElements:this.touchStartListeners.size}}};var W=class extends v{constructor(t){super(),this.name="keyboard",this.defaultWeight=.1,this.events=[],this.targetSelectors=['input[type="text"]','input[type="email"]',"textarea"],this.focusedElement=null,this.focusedElementSelector="",this.lastEventTimestamp=0,this.sessionPauseThreshold=1e3,this.downListener=null,this.upListener=null,this.focusListeners=new Map,this.blurListeners=new Map,this.isActive=!1,t!=null&&t.targetSelectors&&(this.targetSelectors=t.targetSelectors)}start(){this.isActive||(this.isActive=!0,this.attachFocusListeners(),this.downListener=t=>{if(!this.focusedElement)return;let e=Date.now(),s=t;this.lastEventTimestamp>0&&e-this.lastEventTimestamp>this.sessionPauseThreshold&&(this.events=[]),this.events.push({key:s.key,type:"down",timestamp:e,targetElement:this.focusedElementSelector}),this.notifyEvent(.8),this.lastEventTimestamp=e},this.upListener=t=>{if(!this.focusedElement)return;let e=Date.now(),s=t;this.lastEventTimestamp>0&&e-this.lastEventTimestamp>this.sessionPauseThreshold&&(this.events=[]),this.events.push({key:s.key,type:"up",timestamp:e,targetElement:this.focusedElementSelector}),this.lastEventTimestamp=e},document.addEventListener("keydown",this.downListener),document.addEventListener("keyup",this.upListener))}addTarget(t){this.targetSelectors.includes(t)||(this.targetSelectors.push(t),this.isActive&&this.attachFocusListenersForSelector(t))}attachFocusListeners(){this.targetSelectors.forEach(t=>{this.attachFocusListenersForSelector(t)})}attachFocusListenersForSelector(t){document.querySelectorAll(t).forEach(s=>{if(this.focusListeners.has(s))return;let n=()=>{this.focusedElement=s,this.focusedElementSelector=t},o=()=>{this.focusedElement=null,this.focusedElementSelector=""};s.addEventListener("focus",n),s.addEventListener("blur",o),this.focusListeners.set(s,n),this.blurListeners.set(s,o)})}stop(){this.isActive&&(this.isActive=!1,this.downListener&&(document.removeEventListener("keydown",this.downListener),this.downListener=null),this.upListener&&(document.removeEventListener("keyup",this.upListener),this.upListener=null),this.focusListeners.forEach((t,e)=>{e.removeEventListener("focus",t)}),this.focusListeners.clear(),this.blurListeners.forEach((t,e)=>{e.removeEventListener("blur",t)}),this.blurListeners.clear(),this.focusedElement=null)}reset(){this.events=[],this.focusedElement=null,this.focusedElementSelector="",this.lastEventTimestamp=0}score(){if(this.events.length<6)return;let t=this.events.filter(r=>r.type==="down");if(t.length<3)return;let e=0,s=0,n=[];for(let r=1;r<t.length;r++)n.push(t[r].timestamp-t[r-1].timestamp);let o=C(n);if(o){let{statistics:r,allIdentical:f}=o;if(f)return .1;let h=A(r.cv);if(e+=h,s++,h<=.1)return h}let i=[];for(let r=0;r<this.events.length-1;r++)this.events[r].type==="down"&&this.events[r+1].type==="up"&&this.events[r].key===this.events[r+1].key&&i.push(this.events[r+1].timestamp-this.events[r].timestamp);let a=C(i);if(a){let{statistics:r,allIdentical:f}=a;if(f)return .1;if(r.mean<5)e+=.1,s++;else{let h=A(r.cv);if(e+=h,s++,h<=.1)return h}}let l=this.events.filter(r=>r.key==="Backspace").length;if(l>0){let r=l/t.length;r>.05&&r<.3?(e+=1,s++):r>0&&(e+=.8,s++)}return s>0?e/s:void 0}getDebugInfo(){let t=[];for(let e=0;e<this.events.length-1;e++)this.events[e].type==="down"&&this.events[e+1].type==="up"&&this.events[e].key===this.events[e+1].key&&t.push(this.events[e+1].timestamp-this.events[e].timestamp);return{eventCount:this.events.length,downEvents:this.events.filter(e=>e.type==="down").length,upEvents:this.events.filter(e=>e.type==="up").length,backspaceCount:this.events.filter(e=>e.key==="Backspace").length,pressDurations:t,focusedElement:this.focusedElementSelector,trackedElements:this.focusListeners.size}}};var H=class extends v{constructor(){super(...arguments),this.name="environment",this.defaultWeight=.08,this.data=null}start(){this.captureEnvironment()}stop(){}reset(){this.data=null}onTick(t){this.captureEnvironment()}score(){if(!this.data)return;let t=this.data,e=0,s=0;e+=t.suspiciousDimensions?.1:1,e+=t.suspiciousRatio?.2:1,e+=t.featureInconsistency?.3:1,s+=3;let n=[t.hasWebGL,t.hasLocalStorage,t.hasSessionStorage,t.hasIndexedDB].filter(Boolean).length;return e+=n/4,s++,e+=x(t.plugins,-2,-.5),e+=t.plugins>0?1:.1,s+=2,e+=y(t.devicePixelRatio,2,1.5),e+=t.colorDepth===24||t.colorDepth===32?1:.4,s+=2,s>0?e/s:void 0}isMobileDevice(){let t=navigator.maxTouchPoints>0||"ontouchstart"in window,e=/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent),s=window.innerWidth<768&&window.innerHeight<1024;return t&&s||e}captureEnvironment(){try{let t=!1;try{let u=document.createElement("canvas");t=!!(u.getContext("webgl")||u.getContext("experimental-webgl"))}catch(u){t=!1}let e=!!(window.RTCPeerConnection||window.mozRTCPeerConnection||window.webkitRTCPeerConnection),s=this.isMobileDevice(),n=window.innerWidth,o=window.innerHeight,i=window.screen.width,a=window.screen.height,l=n===800&&o===600||n===1024&&o===768||n===1280&&o===720||i===800&&a===600,r=n*o/(i*a),f=r===1||r<.1||r>1,h=typeof localStorage!="undefined"&&typeof sessionStorage!="undefined",g=navigator.plugins.length===0&&navigator.mimeTypes.length===0||!t||!h;this.data={screenWidth:i,screenHeight:a,windowWidth:n,windowHeight:o,devicePixelRatio:window.devicePixelRatio,colorDepth:window.screen.colorDepth,userAgent:navigator.userAgent,platform:navigator.platform,language:navigator.language,languages:navigator.languages?Array.from(navigator.languages):[navigator.language],hardwareConcurrency:navigator.hardwareConcurrency,maxTouchPoints:navigator.maxTouchPoints||0,vendor:navigator.vendor,hasWebGL:t,hasWebRTC:e,hasLocalStorage:typeof localStorage!="undefined",hasSessionStorage:typeof sessionStorage!="undefined",hasIndexedDB:"indexedDB"in window,plugins:navigator.plugins.length,mimeTypes:navigator.mimeTypes.length,suspiciousRatio:f,suspiciousDimensions:l,featureInconsistency:g,isMobile:s,timestamp:Date.now()}}catch(t){}}getDebugInfo(){return this.data}isMobile(){var t,e;return(e=(t=this.data)===null||t===void 0?void 0:t.isMobile)!==null&&e!==void 0?e:null}};var B=class extends v{constructor(){super(...arguments),this.name="resize",this.defaultWeight=.02,this.events=[],this.listener=null,this.isActive=!1,this.lastMousePosition=null,this.mouseListener=null}start(){this.isActive||(this.isActive=!0,this.mouseListener=t=>{let e=t;this.lastMousePosition={x:e.clientX,y:e.clientY}},document.addEventListener("mousemove",this.mouseListener,{passive:!0}),this.listener=()=>{var t,e;let s=(t=this.lastMousePosition)===null||t===void 0?void 0:t.x,n=(e=this.lastMousePosition)===null||e===void 0?void 0:e.y,o=!1;s!==void 0&&n!==void 0&&(o=s<50||s>window.innerWidth-50||n<50||n>window.innerHeight-50),this.events.push({width:window.innerWidth,height:window.innerHeight,mouseX:s,mouseY:n,mouseNearEdge:o,timestamp:Date.now()})},window.addEventListener("resize",this.listener))}stop(){this.isActive&&(this.isActive=!1,this.listener&&(window.removeEventListener("resize",this.listener),this.listener=null),this.mouseListener&&(document.removeEventListener("mousemove",this.mouseListener),this.mouseListener=null))}reset(){this.events=[]}score(){if(this.events.length===0)return;let t=0,e=0;t+=x(this.events.length,5,.5),e++;let s=this.events.filter(n=>n.mouseX!==void 0);if(s.length>0){let n=s.filter(o=>o.mouseNearEdge).length;t+=X(n/s.length,.5,8),e++}return e>0?t/e:void 0}getDebugInfo(){return{eventCount:this.events.length,withMouseData:this.events.filter(t=>t.mouseX!==void 0).length}}};function N(){let c=navigator.maxTouchPoints>0||"ontouchstart"in window,t=/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent),e=window.innerWidth<768&&window.innerHeight<1024;return c&&e||t}var q=class{constructor(){this.detector=null,this.checkInterval=null,this.settings=null}init(t){var e,s,n,o,i,a,l,r,f,h,g,u,M,d,b,S,E,z,k,F,Y;this.detector&&this.stop(),this.settings=t,this.detector=new V({pauseOnHidden:t.pauseOnHidden!==void 0?t.pauseOnHidden:!0});let R=N(),m=t.strategies||{},L=R?{mouse:0,scroll:.35,click:0,tap:.35,keyboard:.15,environment:.1,resize:.05}:{mouse:.3,scroll:.15,click:.3,tap:0,keyboard:.1,environment:.08,resize:.02};if(!R&&((e=m.mouse)===null||e===void 0?void 0:e.enabled)!==!1){let p=new D,w=(n=(s=m.mouse)===null||s===void 0?void 0:s.weight)!==null&&n!==void 0?n:L.mouse;this.detector.addStrategy(p,w)}if(((o=m.scroll)===null||o===void 0?void 0:o.enabled)!==!1){let p=new P,w=(a=(i=m.scroll)===null||i===void 0?void 0:i.weight)!==null&&a!==void 0?a:L.scroll;this.detector.addStrategy(p,w)}if(!R&&((l=m.click)===null||l===void 0?void 0:l.enabled)!==!1){let p=new I,w=(f=(r=m.click)===null||r===void 0?void 0:r.weight)!==null&&f!==void 0?f:L.click;this.detector.addStrategy(p,w)}if(R&&((h=m.tap)===null||h===void 0?void 0:h.enabled)!==!1){let p=new _,w=(u=(g=m.tap)===null||g===void 0?void 0:g.weight)!==null&&u!==void 0?u:L.tap;this.detector.addStrategy(p,w)}if(((M=m.keyboard)===null||M===void 0?void 0:M.enabled)!==!1){let p=new W,w=(b=(d=m.keyboard)===null||d===void 0?void 0:d.weight)!==null&&b!==void 0?b:L.keyboard;this.detector.addStrategy(p,w)}if(((S=m.environment)===null||S===void 0?void 0:S.enabled)!==!1){let p=new H,w=(z=(E=m.environment)===null||E===void 0?void 0:E.weight)!==null&&z!==void 0?z:L.environment;this.detector.addStrategy(p,w)}if(((k=m.resize)===null||k===void 0?void 0:k.enabled)!==!1){let p=new B,w=(Y=(F=m.resize)===null||F===void 0?void 0:F.weight)!==null&&Y!==void 0?Y:L.resize;this.detector.addStrategy(p,w)}t.autoStart!==!1&&this.start(),t.checkMs&&t.checkMs>0&&this.startPeriodicCheck(t.checkMs),t.onReady&&t.onReady(this)}start(){this.detector&&this.detector.start()}stop(){this.detector&&this.detector.stop(),this.checkInterval!==null&&(clearInterval(this.checkInterval),this.checkInterval=null)}async score(){return this.detector?this.detector.score({breakdown:!0}):null}startPeriodicCheck(t){this.checkInterval!==null&&clearInterval(this.checkInterval),this.checkInterval=window.setInterval(async()=>{var e,s;let n=await this.score();if(!n||!this.settings)return;this.settings.onScore&&this.settings.onScore(n);let o=(e=this.settings.botThreshold)!==null&&e!==void 0?e:.3,i=(s=this.settings.humanThreshold)!==null&&s!==void 0?s:.7;n.score<o&&this.settings.ifBot?this.settings.ifBot(n):n.score>=i&&this.settings.ifHuman&&this.settings.ifHuman(n)},t)}getDetector(){return this.detector}},O=new q;if(typeof window!="undefined"){window.BehaviorDetector=O;let c=()=>{let t=window.bdSettings;t&&O.init(t)};c(),document.readyState==="loading"&&document.addEventListener("DOMContentLoaded",c)}})();
|
|
2
|
+
//# sourceMappingURL=behavior-detection.min.js.map
|