@botsigged/sdk 1.0.1 → 1.0.2
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/dist/botsigged.js +1 -1
- package/dist/challenge-ng9p6s5y.js +333 -0
- package/dist/hash-gtpm69df.js +300 -0
- package/dist/index.js +2 -2
- package/package.json +1 -1
package/dist/botsigged.js
CHANGED
|
@@ -40,7 +40,7 @@
|
|
|
40
40
|
@keyframes botsigged-spin {
|
|
41
41
|
to { transform: rotate(360deg); }
|
|
42
42
|
}
|
|
43
|
-
`,document.head.appendChild(Q),this.overlay.appendChild(A),this.overlay.appendChild(this.messageEl),this.overlay.appendChild(B),document.body.appendChild(this.overlay)}setProgress(A){if(this.progressEl){let B=Math.min(100,Math.max(0,A*100));this.progressEl.style.width=`${B}%`}}showSuccess(){if(this.messageEl)this.messageEl.textContent=this.config.successMessage;if(this.progressEl)this.progressEl.style.width="100%"}hide(){if(this.overlay)this.overlay.remove(),this.overlay=null,this.messageEl=null,this.progressEl=null}isVisible(){return this.overlay!==null}}var HA={};g(HA,{ChallengeManager:()=>DA});function SA(){let A=new Uint8Array(16);if(typeof crypto<"u"&&crypto.getRandomValues)crypto.getRandomValues(A);else for(let B=0;B<16;B++)A[B]=Math.floor(Math.random()*256);return A}function bA(A){if(A===0)return 32;let B=0;if((A&4294901760)===0)B+=16,A<<=16;if((A&4278190080)===0)B+=8,A<<=8;if((A&4026531840)===0)B+=4,A<<=4;if((A&3221225472)===0)B+=2,A<<=2;if((A&2147483648)===0)B+=1;return B}function TA(A,B,Q,E){let I=U(),C=new Uint8Array(A.length+4);C.set(A);let Y=E,G=0;while(G<Q){C[A.length]=Y&255,C[A.length+1]=Y>>>8&255,C[A.length+2]=Y>>>16&255,C[A.length+3]=Y>>>24&255;let Z=I.xxHash32(C,0);if(G++,bA(Z)>=B)return{nonce:Y,found:!0,iterations:G};Y=Y+1>>>0}return{nonce:Y,found:!1,iterations:G}}class DA{config;overlay;solving=!1;solved=!1;pendingForms=new Map;formHandler=null;formObserver=null;resubmitting=!1;debug;constructor(A,B=!1){this.config=A,this.debug=B,this.overlay=new BA(A.ui)}getDifficultyForLevel(A){let B=this.config.difficulty;switch(A){case"critical":return B.critical;case"high":return B.high;case"medium":return B.medium;default:return 0}}shouldChallenge(A){if(!this.config.enabled||this.solved)return!1;let B=["low","medium","high","critical"],Q=B.indexOf(A),E=B.indexOf(this.config.minLevel);return Q>=E}blockFormsUntilSolved(A){if(this.formHandler)return;this.formHandler=(B)=>{if(this.solved||this.resubmitting)return;B.preventDefault(),B.stopPropagation();let Q=B.target;if(!this.pendingForms.has(Q))this.pendingForms.set(Q,B);if(!this.solving)this.startChallenge(A)},document.querySelectorAll("form").forEach((B)=>{B.addEventListener("submit",this.formHandler,!0)}),this.formObserver=new MutationObserver((B)=>{B.forEach((Q)=>{Q.addedNodes.forEach((E)=>{if(E instanceof HTMLFormElement&&this.formHandler)E.addEventListener("submit",this.formHandler,!0);if(E instanceof HTMLElement&&this.formHandler)E.querySelectorAll("form").forEach((I)=>{I.addEventListener("submit",this.formHandler,!0)})})})}),this.formObserver.observe(document.body,{childList:!0,subtree:!0}),this.log("Forms blocked, challenge required")}async startChallenge(A){if(this.solving||this.solved)return;this.solving=!0;let B=this.getDifficultyForLevel(A),Q=SA(),E=performance.now();this.log(`Starting challenge: difficulty=${B}, level=${A}`),this.config.onChallengeStart?.(A,B),this.overlay.show();let I=1<<B,C=0,Y=0,G;do{await new Promise((N)=>setTimeout(N,0)),G=TA(Q,B,this.config.chunkSize,C),Y+=G.iterations,C=G.nonce+1;let X=Math.min(1,Y/I);this.overlay.setProgress(X),this.config.onChallengeProgress?.(X,Y)}while(!G.found);let Z=performance.now()-E;this.log(`Challenge solved: nonce=${G.nonce}, iterations=${Y}, time=${Z.toFixed(0)}ms`),this.overlay.showSuccess(),await new Promise((X)=>setTimeout(X,500)),this.overlay.hide(),this.solved=!0,this.solving=!1;let K={solveTimeMs:Z,iterations:Y,difficulty:B,level:A,nonce:G.nonce};this.config.onChallengeComplete?.(K),this.unblockForms()}unblockForms(){if(this.formObserver)this.formObserver.disconnect(),this.formObserver=null;if(this.formHandler)document.querySelectorAll("form").forEach((A)=>{A.removeEventListener("submit",this.formHandler,!0)}),this.formHandler=null;this.log("Forms unblocked"),this.resubmitting=!0,this.pendingForms.forEach((A,B)=>{if(this.log("Resubmitting pending form"),B.requestSubmit)B.requestSubmit();else B.submit()}),this.pendingForms.clear(),this.resubmitting=!1}isSolving(){return this.solving}isSolved(){return this.solved}reset(){if(this.formObserver)this.formObserver.disconnect(),this.formObserver=null;if(this.formHandler)document.querySelectorAll("form").forEach((A)=>{A.removeEventListener("submit",this.formHandler,!0)}),this.formHandler=null;this.solved=!1,this.solving=!1,this.resubmitting=!1,this.pendingForms.clear()}log(...A){if(this.debug);}}var $A=u(()=>{b()});var hA={};g(hA,{init:()=>QA,getInstance:()=>EA,destroy:()=>IA,BotSigged:()=>_});function YA(A){return typeof A==="object"&&A!==null&&"code"in A&&A.code==="LIMIT_EXCEEDED"}var R={endpoint:"wss://api.botsigged.com/socket/websocket",debug:!1,sendInterval:2000,maxBufferSize:1000,mouseSampleRate:0.5,autoStart:!0,actionThreshold:70,action:"none",minAlertLevel:"high",botScoreThresholds:{medium:40,high:70,critical:90},hashVerification:{enabled:!1,preferWasm:!0},challenge:{enabled:!1,minLevel:"high",chunkSize:1e4,difficulty:{medium:12,high:16,critical:20},ui:{enabled:!0,message:"Verifying you're human...",successMessage:"Verified!",backgroundColor:"rgba(0, 0, 0, 0.7)",textColor:"#ffffff",spinnerColor:"#3b82f6",zIndex:999999}},formProtection:{mode:"auto",minTimeBeforeSubmit:500,maxHoldTime:3000,showLoadingUI:!0,loadingMessage:"Please wait..."},fallbackMode:"degraded"},GA={action:"challenge",challenge:{difficulty:{suspicious:14,bot:18},timeout_ms:30000},form_protection_mode:"holdUntilReady"};function JA(A){let B=A.action??R.action,Q=B==="challenge"||A.challenge?.enabled;return{apiKey:A.apiKey,accountId:A.accountId,endpoint:A.endpoint??R.endpoint,debug:A.debug??R.debug,sendInterval:A.sendInterval??R.sendInterval,maxBufferSize:A.maxBufferSize??R.maxBufferSize,mouseSampleRate:A.mouseSampleRate??R.mouseSampleRate,autoStart:A.autoStart??R.autoStart,actionThreshold:A.actionThreshold??R.actionThreshold,action:B,minAlertLevel:A.minAlertLevel??R.minAlertLevel,botScoreThresholds:{...R.botScoreThresholds,...A.botScoreThresholds},hashVerification:{...R.hashVerification,...A.hashVerification},challenge:{enabled:Q,minLevel:A.challenge?.minLevel??R.challenge.minLevel,chunkSize:A.challenge?.chunkSize??R.challenge.chunkSize,difficulty:{...R.challenge.difficulty,...A.challenge?.difficulty},ui:{...R.challenge.ui,...A.challenge?.ui},onChallengeStart:A.challenge?.onChallengeStart,onChallengeComplete:A.challenge?.onChallengeComplete,onChallengeProgress:A.challenge?.onChallengeProgress},formProtection:{mode:A.formProtection?.mode??R.formProtection.mode,minTimeBeforeSubmit:A.formProtection?.minTimeBeforeSubmit??R.formProtection.minTimeBeforeSubmit,maxHoldTime:A.formProtection?.maxHoldTime??R.formProtection.maxHoldTime,showLoadingUI:A.formProtection?.showLoadingUI??R.formProtection.showLoadingUI,loadingMessage:A.formProtection?.loadingMessage??R.formProtection.loadingMessage,onHold:A.formProtection?.onHold,onRelease:A.formProtection?.onRelease,onBlock:A.formProtection?.onBlock},fallbackMode:A.fallbackMode??R.fallbackMode,cookie:A.cookie,headers:A.headers,formInject:A.formInject,onScoreUpdate:A.onScoreUpdate,onConnectionChange:A.onConnectionChange,onError:A.onError,onUsageLimitExceeded:A.onUsageLimitExceeded,onHighBotScore:A.onHighBotScore,onServerConfig:A.onServerConfig,onServerAction:A.onServerAction}}class p{events=[];startTime=0;sampleRate;maxBufferSize;isListening=!1;boundHandleMouseMove;boundHandleMouseDown;boundHandleMouseUp;boundHandleClick;constructor(A={}){this.sampleRate=A.sampleRate??0.5,this.maxBufferSize=A.maxBufferSize??500,this.boundHandleMouseMove=this.handleMouseMove.bind(this),this.boundHandleMouseDown=this.handleMouseDown.bind(this),this.boundHandleMouseUp=this.handleMouseUp.bind(this),this.boundHandleClick=this.handleClick.bind(this)}start(){if(this.isListening)return;this.startTime=Date.now(),document.addEventListener("mousemove",this.boundHandleMouseMove,{passive:!0}),document.addEventListener("mousedown",this.boundHandleMouseDown,{passive:!0}),document.addEventListener("mouseup",this.boundHandleMouseUp,{passive:!0}),document.addEventListener("click",this.boundHandleClick,{passive:!0}),this.isListening=!0}stop(){if(!this.isListening)return;document.removeEventListener("mousemove",this.boundHandleMouseMove),document.removeEventListener("mousedown",this.boundHandleMouseDown),document.removeEventListener("mouseup",this.boundHandleMouseUp),document.removeEventListener("click",this.boundHandleClick),this.isListening=!1}addEvent(A){if(this.events.push(A),this.events.length>this.maxBufferSize)this.events.shift()}handleMouseMove(A){if(Math.random()>this.sampleRate)return;this.addEvent({type:"move",x:A.clientX,y:A.clientY,t:Date.now()})}handleMouseDown(A){this.addEvent({type:"down",x:A.clientX,y:A.clientY,t:Date.now(),button:A.button})}handleMouseUp(A){this.addEvent({type:"up",x:A.clientX,y:A.clientY,t:Date.now(),button:A.button})}handleClick(A){let B=A.target,Q,E;if(B&&B.getBoundingClientRect){let I=B.getBoundingClientRect();Q={top:I.top,left:I.left,width:I.width,height:I.height},E=B.tagName?.toLowerCase()}this.addEvent({type:"click",x:A.clientX,y:A.clientY,t:Date.now(),button:A.button,targetRect:Q,targetTag:E})}getSignal(){return{events:[...this.events],start_time:this.startTime}}flush(){this.events=[]}getBufferSize(){return this.events.length}reset(){this.events=[],this.startTime=Date.now()}}class m{events=[];startTime=0;maxBufferSize;isListening=!1;boundHandleScroll;constructor(A={}){this.maxBufferSize=A.maxBufferSize??200,this.boundHandleScroll=this.handleScroll.bind(this)}start(){if(this.isListening)return;this.startTime=Date.now(),window.addEventListener("scroll",this.boundHandleScroll,{passive:!0}),this.isListening=!0}stop(){if(!this.isListening)return;window.removeEventListener("scroll",this.boundHandleScroll),this.isListening=!1}handleScroll(){if(this.events.push({y:window.scrollY,t:Date.now()}),this.events.length>this.maxBufferSize)this.events.shift()}getSignal(){return{events:[...this.events],start_time:this.startTime}}flush(){this.events=[]}getBufferSize(){return this.events.length}reset(){this.events=[],this.startTime=Date.now()}}class w{static instance=null;timings={signalRoundtrips:[]};pendingSignals=new Map;constructor(){this.timings.scriptStart=performance.now()}static getInstance(){if(!w.instance)w.instance=new w;return w.instance}static reset(){w.instance=null}markScriptStart(){this.timings.scriptStart=performance.now()}markConstructorStart(){this.timings.constructorStart=performance.now()}markConstructorEnd(){this.timings.constructorEnd=performance.now()}markStartCalled(){this.timings.startCalled=performance.now()}markSdkReady(){this.timings.sdkReady=performance.now()}markFingerprintStart(){this.timings.fingerprintStart=performance.now()}markFingerprintEnd(){this.timings.fingerprintEnd=performance.now()}markWsConnectStart(){this.timings.wsConnectStart=performance.now()}markWsConnectEnd(){this.timings.wsConnectEnd=performance.now()}markChannelJoinStart(){this.timings.channelJoinStart=performance.now()}markChannelJoinEnd(){this.timings.channelJoinEnd=performance.now()}markInitialScoreReceived(){this.timings.initialScoreReceived=performance.now()}markFormCollectorStart(){this.timings.formCollectorStart=performance.now()}markFormCollectorReady(){this.timings.formCollectorReady=performance.now()}markFirstFormInteraction(){if(!this.timings.firstFormInteraction){if(this.timings.firstFormInteraction=performance.now(),this.timings.sdkReady)this.timings.timeToFirstInteraction=this.timings.firstFormInteraction-this.timings.sdkReady}}markFirstSubmitAttempt(A){if(!this.timings.firstSubmitAttempt)this.timings.firstSubmitAttempt=performance.now(),this.timings.hadScoreBeforeSubmit=A}markSignalSent(A){this.pendingSignals.set(A,performance.now())}markSignalResponseReceived(A){let B=this.pendingSignals.get(A);if(B!==void 0){let Q=performance.now(),E={sentAt:B,receivedAt:Q,roundtripMs:Q-B,seq:A};this.timings.signalRoundtrips?.push(E),this.pendingSignals.delete(A)}}getTimings(){return{...this.timings}}getSummary(){let A=this.timings,B=A.signalRoundtrips||[],Q=0,E=1/0,I=0;if(B.length>0)Q=B.reduce((V,z)=>V+z.roundtripMs,0)/B.length,E=Math.min(...B.map((V)=>V.roundtripMs)),I=Math.max(...B.map((V)=>V.roundtripMs));let C=(A.sdkReady??0)-(A.scriptStart??0),Y=(A.fingerprintEnd??0)-(A.fingerprintStart??0),G=(A.wsConnectEnd??0)-(A.wsConnectStart??0),Z=(A.channelJoinEnd??0)-(A.channelJoinStart??0),K=(A.initialScoreReceived??0)-(A.startCalled??0),X=(A.initialScoreReceived??0)-(A.scriptStart??0);return{totalStartupMs:Math.round(C),fingerprintMs:Math.round(Y),wsConnectionMs:Math.round(G),channelJoinMs:Math.round(Z),timeToFirstScoreMs:Math.round(K),avgSignalRoundtripMs:Math.round(Q),minSignalRoundtripMs:E===1/0?0:Math.round(E),maxSignalRoundtripMs:Math.round(I),vulnerabilityWindowMs:Math.round(X),protectedBeforeSubmit:A.hadScoreBeforeSubmit??!1}}logSummary(){let A=this.getSummary(),B=this.timings;if(B.firstFormInteraction);if(B.firstSubmitAttempt);if(A.vulnerabilityWindowMs>0);}getReport(){return{timings:this.timings,summary:this.getSummary(),userAgent:navigator.userAgent,timestamp:Date.now()}}}var J=w.getInstance();function O(){return w.getInstance()}var P="__bs_ghost_value";class d{keyEvents=[];focusEvents=[];pasteEvents=[];inputEvents=[];submitCount=0;startTime=0;maxKeyEvents;maxFocusEvents;maxInputEvents;isListening=!1;valueSetterHooked=!1;onSubmit;originalInputDescriptor;originalTextareaDescriptor;lastKeyWasTab=!1;currentField=null;emailDomains=new Set;boundHandleFocusIn;boundHandleFocusOut;boundHandleKeyDown;boundHandleKeyUp;boundHandlePaste;boundHandleSubmit;boundHandleClick;boundHandleInput;boundHandleGhostValue;constructor(A={}){this.maxKeyEvents=A.maxKeyEvents??500,this.maxFocusEvents=A.maxFocusEvents??100,this.maxInputEvents=A.maxInputEvents??200,this.onSubmit=A.onSubmit,this.boundHandleFocusIn=this.handleFocusIn.bind(this),this.boundHandleFocusOut=this.handleFocusOut.bind(this),this.boundHandleKeyDown=this.handleKeyDown.bind(this),this.boundHandleKeyUp=this.handleKeyUp.bind(this),this.boundHandlePaste=this.handlePaste.bind(this),this.boundHandleSubmit=this.handleSubmit.bind(this),this.boundHandleClick=this.handleClick.bind(this),this.boundHandleInput=this.handleInput.bind(this),this.boundHandleGhostValue=this.handleGhostValue.bind(this)}start(){if(this.isListening)return;this.startTime=Date.now(),document.addEventListener("focusin",this.boundHandleFocusIn,{passive:!0,capture:!0}),document.addEventListener("focusout",this.boundHandleFocusOut,{passive:!0,capture:!0}),document.addEventListener("keydown",this.boundHandleKeyDown,{passive:!0}),document.addEventListener("keyup",this.boundHandleKeyUp,{passive:!0}),document.addEventListener("paste",this.boundHandlePaste,{passive:!0}),document.addEventListener("submit",this.boundHandleSubmit,{passive:!0}),document.addEventListener("click",this.boundHandleClick,{passive:!0}),document.addEventListener("input",this.boundHandleInput,{passive:!0}),document.addEventListener(P,this.boundHandleGhostValue,{passive:!0}),this.hookValueSetters(),this.isListening=!0}stop(){if(!this.isListening)return;document.removeEventListener("focusin",this.boundHandleFocusIn,{capture:!0}),document.removeEventListener("focusout",this.boundHandleFocusOut,{capture:!0}),document.removeEventListener("keydown",this.boundHandleKeyDown),document.removeEventListener("keyup",this.boundHandleKeyUp),document.removeEventListener("paste",this.boundHandlePaste),document.removeEventListener("submit",this.boundHandleSubmit),document.removeEventListener("click",this.boundHandleClick),document.removeEventListener("input",this.boundHandleInput),document.removeEventListener(P,this.boundHandleGhostValue),this.unhookValueSetters(),this.isListening=!1}isFormInput(A){if(!A||!(A instanceof HTMLElement))return!1;let B=A.tagName.toLowerCase();if(B==="textarea"||B==="select")return!0;if(B==="input"){let Q=A.type.toLowerCase();return!["submit","button","reset","hidden","image"].includes(Q)}return!1}isEmailField(A){let B=A.type?.toLowerCase()||"",Q=(A.name||"").toLowerCase(),E=(A.id||"").toLowerCase();return B==="email"||Q.includes("email")||Q.includes("e-mail")||E.includes("email")||E.includes("e-mail")}extractEmailDomain(A){if(!A||typeof A!=="string")return null;let B=A.trim();if(!B)return null;let Q=B.match(/@([a-zA-Z0-9.-]+\.[a-zA-Z]{2,})$/);return Q?Q[1].toLowerCase():null}getFieldId(A){return A.id||A.getAttribute("name")||`field-${A.tagName.toLowerCase()}`}handleFocusIn(A){if(!this.isFormInput(A.target))return;O().markFirstFormInteraction();let B=this.getFieldId(A.target),Q="direct";if(this.lastKeyWasTab)Q="tab";if(this.focusEvents.push({type:"focus",field:B,t:Date.now(),method:Q}),this.focusEvents.length>this.maxFocusEvents)this.focusEvents.shift();this.currentField=B,this.lastKeyWasTab=!1}handleFocusOut(A){if(!this.isFormInput(A.target))return;let B=A.target,Q=this.getFieldId(B);if(this.focusEvents.push({type:"blur",field:Q,t:Date.now()}),this.focusEvents.length>this.maxFocusEvents)this.focusEvents.shift();if(B instanceof HTMLInputElement&&this.isEmailField(B)){let E=this.extractEmailDomain(B.value);if(E)this.emailDomains.add(E)}this.currentField=null}handleClick(A){if(!this.isFormInput(A.target))return;let B=this.focusEvents[this.focusEvents.length-1];if(B&&B.type==="focus"&&Date.now()-B.t<50)B.method="click"}handleKeyDown(A){if(A.key==="Tab"){this.lastKeyWasTab=!0;return}if(!this.isFormInput(A.target))return;let B="key";if(A.key==="Backspace")B="backspace";else if(A.key==="Delete")B="delete";else if(A.key==="Enter")B="enter";else if(A.key==="Tab")B="tab";else if(A.key.length===1)B="char";else if(A.key.startsWith("Arrow"))B="arrow";if(this.keyEvents.push({type:"down",code:B,t:Date.now(),field:this.currentField||void 0}),this.keyEvents.length>this.maxKeyEvents)this.keyEvents.shift()}handleKeyUp(A){if(!this.isFormInput(A.target))return;let B="key";if(A.key==="Backspace")B="backspace";else if(A.key==="Delete")B="delete";else if(A.key.length===1)B="char";if(this.keyEvents.push({type:"up",code:B,t:Date.now(),field:this.currentField||void 0}),this.keyEvents.length>this.maxKeyEvents)this.keyEvents.shift()}handleInput(A){if(!this.isFormInput(A.target))return;let B=A.target,E=A.inputType||"unknown",I=B.value?.length??0;if(this.inputEvents.push({field:this.getFieldId(B),t:Date.now(),inputType:E,valueLength:I}),this.inputEvents.length>this.maxInputEvents)this.inputEvents.shift()}handlePaste(A){if(!this.isFormInput(A.target))return;let B=A.clipboardData?.getData("text")||"";this.pasteEvents.push({field:this.getFieldId(A.target),t:Date.now(),length:B.length})}handleSubmit(A){this.submitCount++;let B=A.target;if(B&&B.elements)for(let Q=0;Q<B.elements.length;Q++){let E=B.elements[Q];if(E instanceof HTMLInputElement&&this.isEmailField(E)){let I=this.extractEmailDomain(E.value);if(I)this.emailDomains.add(I)}}this.onSubmit?.()}getSignal(){return{keys:[...this.keyEvents],focus:[...this.focusEvents],pastes:[...this.pasteEvents],inputs:[...this.inputEvents],submits:this.submitCount,start_time:this.startTime,email_domains:this.emailDomains.size>0?Array.from(this.emailDomains):void 0}}flush(){this.keyEvents=[],this.focusEvents=[],this.pasteEvents=[],this.inputEvents=[]}getBufferSize(){return this.keyEvents.length+this.focusEvents.length+this.pasteEvents.length+this.inputEvents.length}reset(){this.keyEvents=[],this.focusEvents=[],this.pasteEvents=[],this.inputEvents=[],this.submitCount=0,this.startTime=Date.now(),this.lastKeyWasTab=!1,this.currentField=null,this.emailDomains.clear()}hookValueSetters(){if(this.valueSetterHooked)return;if(this.originalInputDescriptor=Object.getOwnPropertyDescriptor(HTMLInputElement.prototype,"value"),this.originalInputDescriptor){let A=this.originalInputDescriptor.set,B=this.originalInputDescriptor.get;Object.defineProperty(HTMLInputElement.prototype,"value",{configurable:!0,enumerable:!0,get(){return B?.call(this)},set(Q){let E=B?.call(this)??"";A?.call(this,Q);let I=Q??"";if(I!==E)this.dispatchEvent(new CustomEvent(P,{bubbles:!0,detail:{valueLength:I.length,wasEmpty:E.length===0}}))}})}if(this.originalTextareaDescriptor=Object.getOwnPropertyDescriptor(HTMLTextAreaElement.prototype,"value"),this.originalTextareaDescriptor){let A=this.originalTextareaDescriptor.set,B=this.originalTextareaDescriptor.get;Object.defineProperty(HTMLTextAreaElement.prototype,"value",{configurable:!0,enumerable:!0,get(){return B?.call(this)},set(Q){let E=B?.call(this)??"";A?.call(this,Q);let I=Q??"";if(I!==E)this.dispatchEvent(new CustomEvent(P,{bubbles:!0,detail:{valueLength:I.length,wasEmpty:E.length===0}}))}})}this.valueSetterHooked=!0}unhookValueSetters(){if(!this.valueSetterHooked)return;if(this.originalInputDescriptor)Object.defineProperty(HTMLInputElement.prototype,"value",this.originalInputDescriptor);if(this.originalTextareaDescriptor)Object.defineProperty(HTMLTextAreaElement.prototype,"value",this.originalTextareaDescriptor);this.valueSetterHooked=!1}handleGhostValue(A){let B=A.target;if(!this.isFormInput(B))return;let E=A.detail?.valueLength??0;if(this.inputEvents.push({field:this.getFieldId(B),t:Date.now(),inputType:"programmatic",valueLength:E}),this.inputEvents.length>this.maxInputEvents)this.inputEvents.shift()}}class f{cachedSignal=null;collect(){if(this.cachedSignal)return this.cachedSignal;let A=navigator,B=window;return this.cachedSignal={user_agent:navigator.userAgent,platform:navigator.platform,language:navigator.language,languages:[...navigator.languages||[]],hardware_concurrency:navigator.hardwareConcurrency??null,device_memory:A.deviceMemory??null,max_touch_points:navigator.maxTouchPoints??0,screen_width:screen.width,screen_height:screen.height,screen_avail_width:screen.availWidth,screen_avail_height:screen.availHeight,color_depth:screen.colorDepth,pixel_ratio:window.devicePixelRatio??1,...this.getWebGLInfo(),plugins_count:navigator.plugins?.length??0,mime_types_count:navigator.mimeTypes?.length??0,timezone:this.getTimezone(),timezone_offset:new Date().getTimezoneOffset(),has_webdriver:A.webdriver===!0,has_chrome_runtime:!!B.chrome?.runtime,has_chrome_app:!!B.chrome?.app,has_notification_api:"Notification"in window,has_permissions_api:"permissions"in navigator,outer_dimensions:{width:window.outerWidth,height:window.outerHeight},inner_dimensions:{width:window.innerWidth,height:window.innerHeight},notification_permission:this.getNotificationPermission()},this.cachedSignal}getWebGLInfo(){try{let A=document.createElement("canvas"),B=A.getContext("webgl")||A.getContext("experimental-webgl");if(!B||!(B instanceof WebGLRenderingContext))return{webgl_vendor:null,webgl_renderer:null};let Q=B.getExtension("WEBGL_debug_renderer_info");if(!Q)return{webgl_vendor:null,webgl_renderer:null};return{webgl_vendor:B.getParameter(Q.UNMASKED_VENDOR_WEBGL),webgl_renderer:B.getParameter(Q.UNMASKED_RENDERER_WEBGL)}}catch{return{webgl_vendor:null,webgl_renderer:null}}}getTimezone(){try{return Intl.DateTimeFormat().resolvedOptions().timeZone}catch{return null}}getNotificationPermission(){if("Notification"in window)return Notification.permission;return null}getSignal(){return this.collect()}reset(){this.cachedSignal=null}}b();class n{cachedFingerprint=null;async generate(){if(this.cachedFingerprint)return this.cachedFingerprint;let[A,B,Q,E,I]=await Promise.all([this.getCanvasHash(),this.getWebGLData(),this.getAudioHash(),this.getFontData(),this.getScreenHash()]),C={hash:"",canvas_hash:A,webgl_hash:B.hash,audio_hash:Q,font_hash:E.hash,screen_hash:I,webgl_vendor:B.vendor,webgl_renderer:B.renderer,timezone:this.getTimezone(),language:this.getLanguage(),platform:this.getPlatform(),font_count:E.count};return C.hash=await this.generateMainHash(C),this.cachedFingerprint=C,C}getFingerprint(){return this.cachedFingerprint}reset(){this.cachedFingerprint=null}async getCanvasHash(){try{let A=document.createElement("canvas");A.width=200,A.height=50;let B=A.getContext("2d");if(!B)return null;B.textBaseline="top",B.font="14px 'Arial'",B.fillStyle="#f60",B.fillRect(125,1,62,20),B.fillStyle="#069",B.fillText("BotSigged,\uD83C\uDFA8",2,15),B.fillStyle="rgba(102, 204, 0, 0.7)",B.fillText("BotSigged,\uD83C\uDFA8",4,17);let Q=A.toDataURL();return this.hashString(Q)}catch{return null}}async getWebGLData(){try{let A=document.createElement("canvas"),B=A.getContext("webgl")||A.getContext("experimental-webgl");if(!B||!(B instanceof WebGLRenderingContext))return{hash:null,vendor:null,renderer:null};let Q=[],E=[B.ALIASED_LINE_WIDTH_RANGE,B.ALIASED_POINT_SIZE_RANGE,B.ALPHA_BITS,B.BLUE_BITS,B.DEPTH_BITS,B.GREEN_BITS,B.MAX_COMBINED_TEXTURE_IMAGE_UNITS,B.MAX_CUBE_MAP_TEXTURE_SIZE,B.MAX_FRAGMENT_UNIFORM_VECTORS,B.MAX_RENDERBUFFER_SIZE,B.MAX_TEXTURE_IMAGE_UNITS,B.MAX_TEXTURE_SIZE,B.MAX_VARYING_VECTORS,B.MAX_VERTEX_ATTRIBS,B.MAX_VERTEX_TEXTURE_IMAGE_UNITS,B.MAX_VERTEX_UNIFORM_VECTORS,B.MAX_VIEWPORT_DIMS,B.RED_BITS,B.RENDERER,B.SHADING_LANGUAGE_VERSION,B.STENCIL_BITS,B.VENDOR,B.VERSION];for(let K of E)try{let X=B.getParameter(K);Q.push(String(X))}catch{Q.push("")}let I=B.getSupportedExtensions();if(I)Q.push(I.sort().join(","));let C=null,Y=null,G=B.getExtension("WEBGL_debug_renderer_info");if(G)C=B.getParameter(G.UNMASKED_VENDOR_WEBGL),Y=B.getParameter(G.UNMASKED_RENDERER_WEBGL);return{hash:this.hashString(Q.join("|")),vendor:C,renderer:Y}}catch{return{hash:null,vendor:null,renderer:null}}}async getAudioHash(){try{let A=window.OfflineAudioContext||window.webkitOfflineAudioContext;if(!A)return null;let B=new A(1,4500,44100),Q=B.createOscillator(),E=B.createDynamicsCompressor();Q.type="triangle",Q.frequency.setValueAtTime(1e4,B.currentTime),E.threshold.setValueAtTime(-50,B.currentTime),E.knee.setValueAtTime(40,B.currentTime),E.ratio.setValueAtTime(12,B.currentTime),E.attack.setValueAtTime(0,B.currentTime),E.release.setValueAtTime(0.25,B.currentTime),Q.connect(E),E.connect(B.destination),Q.start(0);let C=(await B.startRendering()).getChannelData(0),Y=[];for(let G=0;G<C.length;G+=100)Y.push(C[G]);return this.hashString(Y.join(","))}catch{return null}}async getFontData(){let A=["Arial","Arial Black","Arial Narrow","Calibri","Cambria","Cambria Math","Comic Sans MS","Consolas","Courier","Courier New","Georgia","Helvetica","Impact","Lucida Console","Lucida Sans Unicode","Microsoft Sans Serif","MS Gothic","MS PGothic","MS Sans Serif","MS Serif","Palatino Linotype","Segoe Print","Segoe Script","Segoe UI","Symbol","Tahoma","Times","Times New Roman","Trebuchet MS","Verdana","Wingdings"],B=["monospace","sans-serif","serif"],Q="mmmmmmmmmmlli",E="72px",I=document.createElement("span");I.style.position="absolute",I.style.left="-9999px",I.style.fontSize="72px",I.style.lineHeight="normal",I.innerHTML="mmmmmmmmmmlli",document.body.appendChild(I);let C={};for(let Z of B)I.style.fontFamily=Z,C[Z]=I.offsetWidth;let Y=[];for(let Z of A){let K=!1;for(let X of B)if(I.style.fontFamily=`'${Z}', ${X}`,I.offsetWidth!==C[X]){K=!0;break}if(K)Y.push(Z)}return document.body.removeChild(I),{hash:this.hashString(Y.join(",")),count:Y.length}}async getScreenHash(){let A=[String(screen.width),String(screen.height),String(screen.availWidth),String(screen.availHeight),String(screen.colorDepth),String(screen.pixelDepth),String(window.devicePixelRatio||1)];return this.hashString(A.join("|"))}getTimezone(){try{return Intl.DateTimeFormat().resolvedOptions().timeZone}catch{return null}}getLanguage(){return navigator.language||null}getPlatform(){return navigator.platform||null}generateMainHash(A){let B=[A.canvas_hash||"",A.webgl_hash||"",A.audio_hash||"",A.font_hash||"",A.screen_hash||"",A.timezone||"",A.language||"",A.platform||""];return this.hashString(B.join("|"))}hashString(A){return s(A)}}class t{ws=null;endpoint;apiKey;heartbeatInterval;reconnectAttempts;reconnectDelay;debug;state="disconnected";channelState="closed";refCounter=0;joinRef=null;heartbeatTimer=null;reconnectTimer=null;reconnectCount=0;pendingReplies=new Map;onConnectionChange;onError;channelCallbacks={};topic=null;constructor(A){this.endpoint=A.endpoint,this.apiKey=A.apiKey,this.heartbeatInterval=A.heartbeatInterval??30000,this.reconnectAttempts=A.reconnectAttempts??10,this.reconnectDelay=A.reconnectDelay??((B)=>Math.min(1000*Math.pow(2,B),30000)),this.debug=A.debug??!1,this.onConnectionChange=A.onConnectionChange,this.onError=A.onError}connect(){return new Promise((A,B)=>{if(this.ws&&this.state==="connected"){A();return}this.setState("connecting");let Q=this.buildUrl();this.log("Connecting to",Q);try{this.ws=new WebSocket(Q),this.ws.onopen=()=>{this.log("WebSocket connected"),this.setState("connected"),this.reconnectCount=0,this.startHeartbeat(),A()},this.ws.onclose=(E)=>{this.log("WebSocket closed",E.code,E.reason),this.handleClose()},this.ws.onerror=(E)=>{this.log("WebSocket error",E);let I=Error("WebSocket connection error");this.handleError(I),B(I)},this.ws.onmessage=(E)=>{this.handleMessage(E.data)}}catch(E){let I=E instanceof Error?E:Error(String(E));this.handleError(I),B(I)}})}disconnect(){if(this.stopHeartbeat(),this.stopReconnect(),this.ws)this.ws.close(1000,"Client disconnect"),this.ws=null;this.setState("disconnected"),this.setChannelState("closed")}joinChannel(A,B,Q,E,I={},C){return this.channelCallbacks=I,this.topic=`detection:${A}`,new Promise((Y,G)=>{if(this.state!=="connected"){G(Error("WebSocket not connected"));return}this.setChannelState("joining"),this.joinRef=this.makeRef();let Z={session_id:A,api_key:this.apiKey,fingerprint:B,session:Q,browser:E};if(C)Z.account_id=C;this.push("phx_join",Z,this.joinRef).then((K)=>{this.log("Channel joined",K),this.setChannelState("joined"),this.channelCallbacks.onJoin?.(),Y(K)}).catch((K)=>{this.log("Channel join failed",K),this.setChannelState("error"),this.channelCallbacks.onError?.(K),G(K)})})}leaveChannel(){return new Promise((A,B)=>{if(this.channelState!=="joined"){A();return}this.setChannelState("leaving"),this.push("phx_leave",{}).then(()=>{this.log("Channel left"),this.setChannelState("closed"),this.joinRef=null,this.topic=null,this.channelCallbacks.onLeave?.(),A()}).catch((Q)=>{this.setChannelState("error"),B(Q)})})}sendSignal(A){if(this.channelState!=="joined")return Promise.reject(Error("Channel not joined"));return this.push("signal",A)}sendFormStatus(A){if(this.channelState!=="joined")return Promise.reject(Error("Channel not joined"));return this.push("form_status",{status:A})}sendEvent(A,B){if(this.channelState!=="joined")return Promise.reject(Error("Channel not joined"));return this.push(A,B)}getState(){return this.state}getChannelState(){return this.channelState}isReady(){return this.state==="connected"&&this.channelState==="joined"}buildUrl(){let A=new URL(this.endpoint);return A.searchParams.set("vsn","2.0.0"),A.searchParams.set("api_key",this.apiKey),A.toString()}makeRef(){return this.refCounter++,String(this.refCounter)}push(A,B,Q){return new Promise((E,I)=>{if(!this.ws||this.ws.readyState!==WebSocket.OPEN){I(Error("WebSocket not open"));return}if(!this.topic){I(Error("Channel topic not set"));return}let C=Q??this.makeRef(),Y=[this.joinRef,C,this.topic,A,B],G=setTimeout(()=>{this.pendingReplies.delete(C),I(Error(`Timeout waiting for reply to ${A}`))},1e4);this.pendingReplies.set(C,{resolve:E,reject:I,timeout:G}),this.log("Sending",A,B),this.ws.send(JSON.stringify(Y))})}handleMessage(A){try{let[B,Q,E,I,C]=JSON.parse(A);if(this.log("Received",I,C),I==="phx_reply"&&Q){let Y=this.pendingReplies.get(Q);if(Y){clearTimeout(Y.timeout),this.pendingReplies.delete(Q);let G=C;if(G.status==="ok")Y.resolve(G.response??{});else if(G.response&&typeof G.response==="object"&&"code"in G.response)Y.reject(G.response);else{let Z=this.buildErrorMessage(G.status,G.response);Y.reject(Error(Z))}}return}if(I==="phx_error"){let Y=Error("Channel error");this.setChannelState("error"),this.channelCallbacks.onError?.(Y);return}if(I==="phx_close"){this.setChannelState("closed"),this.channelCallbacks.onLeave?.();return}if(I==="score_update"){this.channelCallbacks.onScoreUpdate?.(C);return}if(I==="action"){this.channelCallbacks.onAction?.(C);return}this.channelCallbacks.onMessage?.(I,C)}catch(B){this.log("Error parsing message",B)}}handleClose(){this.stopHeartbeat(),this.setState("disconnected"),this.setChannelState("closed");for(let[A,B]of this.pendingReplies)clearTimeout(B.timeout),B.reject(Error("Connection closed"));this.pendingReplies.clear(),this.scheduleReconnect()}handleError(A){this.setState("error"),this.onError?.(A)}startHeartbeat(){this.stopHeartbeat(),this.heartbeatTimer=setInterval(()=>{if(this.ws&&this.ws.readyState===WebSocket.OPEN){let A=[null,this.makeRef(),"phoenix","heartbeat",{}];if(this.ws.send(JSON.stringify(A)),this.channelState==="joined")this.push("heartbeat",{}).then((B)=>{if(B.bot_score!==void 0)this.channelCallbacks.onScoreUpdate?.({bot_score:B.bot_score,classification:B.classification,triggered_rules:[],event_count:0})}).catch(()=>{})}},this.heartbeatInterval)}stopHeartbeat(){if(this.heartbeatTimer)clearInterval(this.heartbeatTimer),this.heartbeatTimer=null}scheduleReconnect(){if(this.reconnectCount>=this.reconnectAttempts){this.log("Max reconnect attempts reached");return}let A=this.reconnectDelay(this.reconnectCount);this.reconnectCount++,this.log(`Scheduling reconnect attempt ${this.reconnectCount} in ${A}ms`),this.reconnectTimer=setTimeout(()=>{this.connect().catch((B)=>{this.log("Reconnect failed",B)})},A)}stopReconnect(){if(this.reconnectTimer)clearTimeout(this.reconnectTimer),this.reconnectTimer=null;this.reconnectCount=0}setState(A){if(this.state!==A)this.state=A,this.onConnectionChange?.(A)}setChannelState(A){this.channelState=A}buildErrorMessage(A,B){if(B){if(typeof B.reason==="string")return`Channel error: ${B.reason}`;if(Object.keys(B).length>0)return`Channel error (${A??"error"}): ${JSON.stringify(B)}`}return A??"Unknown error"}log(...A){if(this.debug);}}class o{config;isReady=!1;hasScore=!1;hasFormScore=!1;currentScore=null;pendingSubmissions=[];pendingRequests=[];protectedForms=new Set;releasingForms=new Set;loadingOverlay=null;formObserver=null;startTime;originalFetch=null;originalXHROpen=null;originalXHRSend=null;constructor(A={}){if(this.startTime=performance.now(),this.config={mode:A.mode??"none",minTimeBeforeSubmit:A.minTimeBeforeSubmit??500,maxHoldTime:A.maxHoldTime??5000,showLoadingUI:A.showLoadingUI??!0,loadingMessage:A.loadingMessage??"Please wait...",onHold:A.onHold,onRelease:A.onRelease,onBlock:A.onBlock,flushAndWaitForScore:A.flushAndWaitForScore},this.config.mode!=="none")this.setup()}setup(){if(this.config.mode==="auto")this.interceptFetch(),this.interceptXHR();let A=()=>{document.querySelectorAll("form").forEach((B)=>{this.protectForm(B)}),this.formObserver=new MutationObserver((B)=>{B.forEach((Q)=>{Q.addedNodes.forEach((E)=>{if(E instanceof HTMLFormElement)this.protectForm(E);if(E instanceof HTMLElement)E.querySelectorAll("form").forEach((I)=>{this.protectForm(I)})})})}),this.formObserver.observe(document.body,{childList:!0,subtree:!0})};if(document.body)A();else document.addEventListener("DOMContentLoaded",A,{once:!0})}isFormLikeRequest(A,B){if((B?.method?.toUpperCase()||"GET")!=="POST")return!1;try{if((typeof A==="string"?new URL(A,window.location.origin):A instanceof URL?A:new URL(A.url)).origin!==window.location.origin)return!1}catch{return!1}let E=B?.headers instanceof Headers?B.headers.get("content-type"):typeof B?.headers==="object"&&B.headers!==null?B.headers["content-type"]||B.headers["Content-Type"]:null;if(E){let I=E.toLowerCase();if(I.includes("application/x-www-form-urlencoded")||I.includes("multipart/form-data")||I.includes("application/json"))return!0;return!1}if(B?.body)return!0;return!1}interceptFetch(){this.originalFetch=window.fetch.bind(window);let A=this;window.fetch=async function(B,Q){if(!A.isFormLikeRequest(B,Q))return A.originalFetch(B,Q);if(A.hasScore)return A.originalFetch(B,Q);return new Promise((E,I)=>{let C={resolve:E,reject:I,execute:()=>A.originalFetch(B,Q),timestamp:performance.now()};if(A.pendingRequests.push(C),A.config.showLoadingUI&&A.pendingRequests.length===1)A.showLoading(document.createElement("form"));if(setTimeout(()=>{if(A.pendingRequests.includes(C))A.releaseRequest(C)},A.config.maxHoldTime),A.hasScore)A.releaseRequest(C)})}}interceptXHR(){this.originalXHROpen=XMLHttpRequest.prototype.open,this.originalXHRSend=XMLHttpRequest.prototype.send;let A=this;XMLHttpRequest.prototype.open=function(B,Q,E=!0,I,C){let Y=this;return Y._bsMethod=B.toUpperCase(),Y._bsUrl=Q.toString(),A.originalXHROpen.call(this,B,Q,E,I,C)},XMLHttpRequest.prototype.send=function(B){let Q=this,E=Q._bsMethod||"GET",I=Q._bsUrl||"";if(E!=="POST")return A.originalXHRSend.call(this,B);try{if(new URL(I,window.location.origin).origin!==window.location.origin)return A.originalXHRSend.call(this,B)}catch{return A.originalXHRSend.call(this,B)}if(A.hasScore)return A.originalXHRSend.call(this,B);let C=performance.now(),Y=()=>{if(A.hasScore){if(A.config.showLoadingUI)A.hideLoading();A.originalXHRSend.call(Q,B)}else if(performance.now()-C>=A.config.maxHoldTime){if(A.config.showLoadingUI)A.hideLoading();A.originalXHRSend.call(Q,B)}else setTimeout(Y,50)};if(A.config.showLoadingUI)A.showLoading(document.createElement("form"));Y()}}releaseRequest(A){let B=this.pendingRequests.indexOf(A);if(B===-1)return;if(this.pendingRequests.splice(B,1),this.pendingRequests.length===0&&this.config.showLoadingUI)this.hideLoading();A.execute().then(A.resolve).catch(A.reject)}protectForm(A){if(this.protectedForms.has(A))return;this.protectedForms.add(A),A.addEventListener("submit",(B)=>this.handleSubmit(B,A),{capture:!0})}handleSubmit(A,B){if(this.releasingForms.has(B)){this.releasingForms.delete(B);return}let E=performance.now()-this.startTime;switch(O().markFirstSubmitAttempt(this.hasScore),this.config.mode){case"holdUntilReady":if(!this.hasScore)A.preventDefault(),A.stopPropagation(),this.holdSubmission(B,A);break;case"holdUntilFormScored":A.preventDefault(),A.stopPropagation(),this.holdAndScoreSubmission(B,A);break;case"blockInstant":if(E<this.config.minTimeBeforeSubmit)A.preventDefault(),A.stopPropagation(),this.config.onBlock?.(B,"instant_submission");break;case"challengeFirst":if(!this.hasScore)A.preventDefault(),A.stopPropagation(),this.holdSubmission(B,A);break;case"none":default:break}}holdSubmission(A,B){if(this.config.onHold?.(A),this.config.showLoadingUI)this.showLoading(A);let Q={form:A,event:B,timestamp:performance.now(),resolver:()=>{},rejecter:()=>{}},E=new Promise((I,C)=>{Q.resolver=I,Q.rejecter=C});if(this.pendingSubmissions.push(Q),setTimeout(()=>{if(this.pendingSubmissions.includes(Q))this.releaseSubmission(Q,!1)},this.config.maxHoldTime),this.hasScore)this.releaseSubmission(Q,!1);E.catch(()=>{})}async holdAndScoreSubmission(A,B){if(this.config.onHold?.(A),this.config.showLoadingUI)this.showLoading(A);let Q=performance.now();try{if(!this.config.flushAndWaitForScore){this.submitForm(A);return}let E=this.config.flushAndWaitForScore(),I=new Promise((G)=>{setTimeout(()=>G(null),this.config.maxHoldTime)}),C=await Promise.race([E,I]),Y=performance.now()-Q;if(C===null);else this.currentScore=C,this.hasFormScore=!0;if(this.config.showLoadingUI)this.hideLoading();this.config.onRelease?.(A,!1),this.submitForm(A)}catch(E){if(this.config.showLoadingUI)this.hideLoading();this.config.onRelease?.(A,!1),this.submitForm(A)}}submitForm(A){if(this.releasingForms.add(A),A.requestSubmit)A.requestSubmit();else A.submit()}releaseSubmission(A,B){let Q=this.pendingSubmissions.indexOf(A);if(Q===-1)return;if(this.pendingSubmissions.splice(Q,1),this.config.showLoadingUI)this.hideLoading();if(this.config.onRelease?.(A.form,B),!B)if(A.resolver(),A.form.requestSubmit)A.form.requestSubmit();else A.form.submit();else A.rejecter("blocked")}showLoading(A){if(this.loadingOverlay)return;this.loadingOverlay=document.createElement("div"),this.loadingOverlay.innerHTML=`
|
|
43
|
+
`,document.head.appendChild(Q),this.overlay.appendChild(A),this.overlay.appendChild(this.messageEl),this.overlay.appendChild(B),document.body.appendChild(this.overlay)}setProgress(A){if(this.progressEl){let B=Math.min(100,Math.max(0,A*100));this.progressEl.style.width=`${B}%`}}showSuccess(){if(this.messageEl)this.messageEl.textContent=this.config.successMessage;if(this.progressEl)this.progressEl.style.width="100%"}hide(){if(this.overlay)this.overlay.remove(),this.overlay=null,this.messageEl=null,this.progressEl=null}isVisible(){return this.overlay!==null}}var HA={};g(HA,{ChallengeManager:()=>DA});function SA(){let A=new Uint8Array(16);if(typeof crypto<"u"&&crypto.getRandomValues)crypto.getRandomValues(A);else for(let B=0;B<16;B++)A[B]=Math.floor(Math.random()*256);return A}function bA(A){if(A===0)return 32;let B=0;if((A&4294901760)===0)B+=16,A<<=16;if((A&4278190080)===0)B+=8,A<<=8;if((A&4026531840)===0)B+=4,A<<=4;if((A&3221225472)===0)B+=2,A<<=2;if((A&2147483648)===0)B+=1;return B}function TA(A,B,Q,E){let I=U(),C=new Uint8Array(A.length+4);C.set(A);let Y=E,G=0;while(G<Q){C[A.length]=Y&255,C[A.length+1]=Y>>>8&255,C[A.length+2]=Y>>>16&255,C[A.length+3]=Y>>>24&255;let Z=I.xxHash32(C,0);if(G++,bA(Z)>=B)return{nonce:Y,found:!0,iterations:G};Y=Y+1>>>0}return{nonce:Y,found:!1,iterations:G}}class DA{config;overlay;solving=!1;solved=!1;pendingForms=new Map;formHandler=null;formObserver=null;resubmitting=!1;debug;constructor(A,B=!1){this.config=A,this.debug=B,this.overlay=new BA(A.ui)}getDifficultyForLevel(A){let B=this.config.difficulty;switch(A){case"critical":return B.critical;case"high":return B.high;case"medium":return B.medium;default:return 0}}shouldChallenge(A){if(!this.config.enabled||this.solved)return!1;let B=["low","medium","high","critical"],Q=B.indexOf(A),E=B.indexOf(this.config.minLevel);return Q>=E}blockFormsUntilSolved(A){if(this.formHandler)return;this.formHandler=(B)=>{if(this.solved||this.resubmitting)return;B.preventDefault(),B.stopPropagation();let Q=B.target;if(!this.pendingForms.has(Q))this.pendingForms.set(Q,B);if(!this.solving)this.startChallenge(A)},document.querySelectorAll("form").forEach((B)=>{B.addEventListener("submit",this.formHandler,!0)}),this.formObserver=new MutationObserver((B)=>{B.forEach((Q)=>{Q.addedNodes.forEach((E)=>{if(E instanceof HTMLFormElement&&this.formHandler)E.addEventListener("submit",this.formHandler,!0);if(E instanceof HTMLElement&&this.formHandler)E.querySelectorAll("form").forEach((I)=>{I.addEventListener("submit",this.formHandler,!0)})})})}),this.formObserver.observe(document.body,{childList:!0,subtree:!0}),this.log("Forms blocked, challenge required")}async startChallenge(A){if(this.solving||this.solved)return;this.solving=!0;let B=this.getDifficultyForLevel(A),Q=SA(),E=performance.now();this.log(`Starting challenge: difficulty=${B}, level=${A}`),this.config.onChallengeStart?.(A,B),this.overlay.show();let I=1<<B,C=0,Y=0,G;do{await new Promise((N)=>setTimeout(N,0)),G=TA(Q,B,this.config.chunkSize,C),Y+=G.iterations,C=G.nonce+1;let X=Math.min(1,Y/I);this.overlay.setProgress(X),this.config.onChallengeProgress?.(X,Y)}while(!G.found);let Z=performance.now()-E;this.log(`Challenge solved: nonce=${G.nonce}, iterations=${Y}, time=${Z.toFixed(0)}ms`),this.overlay.showSuccess(),await new Promise((X)=>setTimeout(X,500)),this.overlay.hide(),this.solved=!0,this.solving=!1;let K={solveTimeMs:Z,iterations:Y,difficulty:B,level:A,nonce:G.nonce};this.config.onChallengeComplete?.(K),this.unblockForms()}unblockForms(){if(this.formObserver)this.formObserver.disconnect(),this.formObserver=null;if(this.formHandler)document.querySelectorAll("form").forEach((A)=>{A.removeEventListener("submit",this.formHandler,!0)}),this.formHandler=null;this.log("Forms unblocked"),this.resubmitting=!0,this.pendingForms.forEach((A,B)=>{if(this.log("Resubmitting pending form"),B.requestSubmit)B.requestSubmit();else B.submit()}),this.pendingForms.clear(),this.resubmitting=!1}isSolving(){return this.solving}isSolved(){return this.solved}reset(){if(this.formObserver)this.formObserver.disconnect(),this.formObserver=null;if(this.formHandler)document.querySelectorAll("form").forEach((A)=>{A.removeEventListener("submit",this.formHandler,!0)}),this.formHandler=null;this.solved=!1,this.solving=!1,this.resubmitting=!1,this.pendingForms.clear()}log(...A){if(this.debug);}}var $A=u(()=>{b()});var hA={};g(hA,{init:()=>QA,getInstance:()=>EA,destroy:()=>IA,BotSigged:()=>_});function YA(A){return typeof A==="object"&&A!==null&&"code"in A&&A.code==="LIMIT_EXCEEDED"}var R={endpoint:"wss://botsigged.com/sdk/websocket",debug:!1,sendInterval:2000,maxBufferSize:1000,mouseSampleRate:0.5,autoStart:!0,actionThreshold:70,action:"none",minAlertLevel:"high",botScoreThresholds:{medium:40,high:70,critical:90},hashVerification:{enabled:!1,preferWasm:!0},challenge:{enabled:!1,minLevel:"high",chunkSize:1e4,difficulty:{medium:12,high:16,critical:20},ui:{enabled:!0,message:"Verifying you're human...",successMessage:"Verified!",backgroundColor:"rgba(0, 0, 0, 0.7)",textColor:"#ffffff",spinnerColor:"#3b82f6",zIndex:999999}},formProtection:{mode:"auto",minTimeBeforeSubmit:500,maxHoldTime:3000,showLoadingUI:!0,loadingMessage:"Please wait..."},fallbackMode:"degraded"},GA={action:"challenge",challenge:{difficulty:{suspicious:14,bot:18},timeout_ms:30000},form_protection_mode:"holdUntilReady"};function JA(A){let B=A.action??R.action,Q=B==="challenge"||A.challenge?.enabled;return{apiKey:A.apiKey,accountId:A.accountId,endpoint:A.endpoint??R.endpoint,debug:A.debug??R.debug,sendInterval:A.sendInterval??R.sendInterval,maxBufferSize:A.maxBufferSize??R.maxBufferSize,mouseSampleRate:A.mouseSampleRate??R.mouseSampleRate,autoStart:A.autoStart??R.autoStart,actionThreshold:A.actionThreshold??R.actionThreshold,action:B,minAlertLevel:A.minAlertLevel??R.minAlertLevel,botScoreThresholds:{...R.botScoreThresholds,...A.botScoreThresholds},hashVerification:{...R.hashVerification,...A.hashVerification},challenge:{enabled:Q,minLevel:A.challenge?.minLevel??R.challenge.minLevel,chunkSize:A.challenge?.chunkSize??R.challenge.chunkSize,difficulty:{...R.challenge.difficulty,...A.challenge?.difficulty},ui:{...R.challenge.ui,...A.challenge?.ui},onChallengeStart:A.challenge?.onChallengeStart,onChallengeComplete:A.challenge?.onChallengeComplete,onChallengeProgress:A.challenge?.onChallengeProgress},formProtection:{mode:A.formProtection?.mode??R.formProtection.mode,minTimeBeforeSubmit:A.formProtection?.minTimeBeforeSubmit??R.formProtection.minTimeBeforeSubmit,maxHoldTime:A.formProtection?.maxHoldTime??R.formProtection.maxHoldTime,showLoadingUI:A.formProtection?.showLoadingUI??R.formProtection.showLoadingUI,loadingMessage:A.formProtection?.loadingMessage??R.formProtection.loadingMessage,onHold:A.formProtection?.onHold,onRelease:A.formProtection?.onRelease,onBlock:A.formProtection?.onBlock},fallbackMode:A.fallbackMode??R.fallbackMode,cookie:A.cookie,headers:A.headers,formInject:A.formInject,onScoreUpdate:A.onScoreUpdate,onConnectionChange:A.onConnectionChange,onError:A.onError,onUsageLimitExceeded:A.onUsageLimitExceeded,onHighBotScore:A.onHighBotScore,onServerConfig:A.onServerConfig,onServerAction:A.onServerAction}}class p{events=[];startTime=0;sampleRate;maxBufferSize;isListening=!1;boundHandleMouseMove;boundHandleMouseDown;boundHandleMouseUp;boundHandleClick;constructor(A={}){this.sampleRate=A.sampleRate??0.5,this.maxBufferSize=A.maxBufferSize??500,this.boundHandleMouseMove=this.handleMouseMove.bind(this),this.boundHandleMouseDown=this.handleMouseDown.bind(this),this.boundHandleMouseUp=this.handleMouseUp.bind(this),this.boundHandleClick=this.handleClick.bind(this)}start(){if(this.isListening)return;this.startTime=Date.now(),document.addEventListener("mousemove",this.boundHandleMouseMove,{passive:!0}),document.addEventListener("mousedown",this.boundHandleMouseDown,{passive:!0}),document.addEventListener("mouseup",this.boundHandleMouseUp,{passive:!0}),document.addEventListener("click",this.boundHandleClick,{passive:!0}),this.isListening=!0}stop(){if(!this.isListening)return;document.removeEventListener("mousemove",this.boundHandleMouseMove),document.removeEventListener("mousedown",this.boundHandleMouseDown),document.removeEventListener("mouseup",this.boundHandleMouseUp),document.removeEventListener("click",this.boundHandleClick),this.isListening=!1}addEvent(A){if(this.events.push(A),this.events.length>this.maxBufferSize)this.events.shift()}handleMouseMove(A){if(Math.random()>this.sampleRate)return;this.addEvent({type:"move",x:A.clientX,y:A.clientY,t:Date.now()})}handleMouseDown(A){this.addEvent({type:"down",x:A.clientX,y:A.clientY,t:Date.now(),button:A.button})}handleMouseUp(A){this.addEvent({type:"up",x:A.clientX,y:A.clientY,t:Date.now(),button:A.button})}handleClick(A){let B=A.target,Q,E;if(B&&B.getBoundingClientRect){let I=B.getBoundingClientRect();Q={top:I.top,left:I.left,width:I.width,height:I.height},E=B.tagName?.toLowerCase()}this.addEvent({type:"click",x:A.clientX,y:A.clientY,t:Date.now(),button:A.button,targetRect:Q,targetTag:E})}getSignal(){return{events:[...this.events],start_time:this.startTime}}flush(){this.events=[]}getBufferSize(){return this.events.length}reset(){this.events=[],this.startTime=Date.now()}}class m{events=[];startTime=0;maxBufferSize;isListening=!1;boundHandleScroll;constructor(A={}){this.maxBufferSize=A.maxBufferSize??200,this.boundHandleScroll=this.handleScroll.bind(this)}start(){if(this.isListening)return;this.startTime=Date.now(),window.addEventListener("scroll",this.boundHandleScroll,{passive:!0}),this.isListening=!0}stop(){if(!this.isListening)return;window.removeEventListener("scroll",this.boundHandleScroll),this.isListening=!1}handleScroll(){if(this.events.push({y:window.scrollY,t:Date.now()}),this.events.length>this.maxBufferSize)this.events.shift()}getSignal(){return{events:[...this.events],start_time:this.startTime}}flush(){this.events=[]}getBufferSize(){return this.events.length}reset(){this.events=[],this.startTime=Date.now()}}class w{static instance=null;timings={signalRoundtrips:[]};pendingSignals=new Map;constructor(){this.timings.scriptStart=performance.now()}static getInstance(){if(!w.instance)w.instance=new w;return w.instance}static reset(){w.instance=null}markScriptStart(){this.timings.scriptStart=performance.now()}markConstructorStart(){this.timings.constructorStart=performance.now()}markConstructorEnd(){this.timings.constructorEnd=performance.now()}markStartCalled(){this.timings.startCalled=performance.now()}markSdkReady(){this.timings.sdkReady=performance.now()}markFingerprintStart(){this.timings.fingerprintStart=performance.now()}markFingerprintEnd(){this.timings.fingerprintEnd=performance.now()}markWsConnectStart(){this.timings.wsConnectStart=performance.now()}markWsConnectEnd(){this.timings.wsConnectEnd=performance.now()}markChannelJoinStart(){this.timings.channelJoinStart=performance.now()}markChannelJoinEnd(){this.timings.channelJoinEnd=performance.now()}markInitialScoreReceived(){this.timings.initialScoreReceived=performance.now()}markFormCollectorStart(){this.timings.formCollectorStart=performance.now()}markFormCollectorReady(){this.timings.formCollectorReady=performance.now()}markFirstFormInteraction(){if(!this.timings.firstFormInteraction){if(this.timings.firstFormInteraction=performance.now(),this.timings.sdkReady)this.timings.timeToFirstInteraction=this.timings.firstFormInteraction-this.timings.sdkReady}}markFirstSubmitAttempt(A){if(!this.timings.firstSubmitAttempt)this.timings.firstSubmitAttempt=performance.now(),this.timings.hadScoreBeforeSubmit=A}markSignalSent(A){this.pendingSignals.set(A,performance.now())}markSignalResponseReceived(A){let B=this.pendingSignals.get(A);if(B!==void 0){let Q=performance.now(),E={sentAt:B,receivedAt:Q,roundtripMs:Q-B,seq:A};this.timings.signalRoundtrips?.push(E),this.pendingSignals.delete(A)}}getTimings(){return{...this.timings}}getSummary(){let A=this.timings,B=A.signalRoundtrips||[],Q=0,E=1/0,I=0;if(B.length>0)Q=B.reduce((V,z)=>V+z.roundtripMs,0)/B.length,E=Math.min(...B.map((V)=>V.roundtripMs)),I=Math.max(...B.map((V)=>V.roundtripMs));let C=(A.sdkReady??0)-(A.scriptStart??0),Y=(A.fingerprintEnd??0)-(A.fingerprintStart??0),G=(A.wsConnectEnd??0)-(A.wsConnectStart??0),Z=(A.channelJoinEnd??0)-(A.channelJoinStart??0),K=(A.initialScoreReceived??0)-(A.startCalled??0),X=(A.initialScoreReceived??0)-(A.scriptStart??0);return{totalStartupMs:Math.round(C),fingerprintMs:Math.round(Y),wsConnectionMs:Math.round(G),channelJoinMs:Math.round(Z),timeToFirstScoreMs:Math.round(K),avgSignalRoundtripMs:Math.round(Q),minSignalRoundtripMs:E===1/0?0:Math.round(E),maxSignalRoundtripMs:Math.round(I),vulnerabilityWindowMs:Math.round(X),protectedBeforeSubmit:A.hadScoreBeforeSubmit??!1}}logSummary(){let A=this.getSummary(),B=this.timings;if(B.firstFormInteraction);if(B.firstSubmitAttempt);if(A.vulnerabilityWindowMs>0);}getReport(){return{timings:this.timings,summary:this.getSummary(),userAgent:navigator.userAgent,timestamp:Date.now()}}}var J=w.getInstance();function O(){return w.getInstance()}var P="__bs_ghost_value";class d{keyEvents=[];focusEvents=[];pasteEvents=[];inputEvents=[];submitCount=0;startTime=0;maxKeyEvents;maxFocusEvents;maxInputEvents;isListening=!1;valueSetterHooked=!1;onSubmit;originalInputDescriptor;originalTextareaDescriptor;lastKeyWasTab=!1;currentField=null;emailDomains=new Set;boundHandleFocusIn;boundHandleFocusOut;boundHandleKeyDown;boundHandleKeyUp;boundHandlePaste;boundHandleSubmit;boundHandleClick;boundHandleInput;boundHandleGhostValue;constructor(A={}){this.maxKeyEvents=A.maxKeyEvents??500,this.maxFocusEvents=A.maxFocusEvents??100,this.maxInputEvents=A.maxInputEvents??200,this.onSubmit=A.onSubmit,this.boundHandleFocusIn=this.handleFocusIn.bind(this),this.boundHandleFocusOut=this.handleFocusOut.bind(this),this.boundHandleKeyDown=this.handleKeyDown.bind(this),this.boundHandleKeyUp=this.handleKeyUp.bind(this),this.boundHandlePaste=this.handlePaste.bind(this),this.boundHandleSubmit=this.handleSubmit.bind(this),this.boundHandleClick=this.handleClick.bind(this),this.boundHandleInput=this.handleInput.bind(this),this.boundHandleGhostValue=this.handleGhostValue.bind(this)}start(){if(this.isListening)return;this.startTime=Date.now(),document.addEventListener("focusin",this.boundHandleFocusIn,{passive:!0,capture:!0}),document.addEventListener("focusout",this.boundHandleFocusOut,{passive:!0,capture:!0}),document.addEventListener("keydown",this.boundHandleKeyDown,{passive:!0}),document.addEventListener("keyup",this.boundHandleKeyUp,{passive:!0}),document.addEventListener("paste",this.boundHandlePaste,{passive:!0}),document.addEventListener("submit",this.boundHandleSubmit,{passive:!0}),document.addEventListener("click",this.boundHandleClick,{passive:!0}),document.addEventListener("input",this.boundHandleInput,{passive:!0}),document.addEventListener(P,this.boundHandleGhostValue,{passive:!0}),this.hookValueSetters(),this.isListening=!0}stop(){if(!this.isListening)return;document.removeEventListener("focusin",this.boundHandleFocusIn,{capture:!0}),document.removeEventListener("focusout",this.boundHandleFocusOut,{capture:!0}),document.removeEventListener("keydown",this.boundHandleKeyDown),document.removeEventListener("keyup",this.boundHandleKeyUp),document.removeEventListener("paste",this.boundHandlePaste),document.removeEventListener("submit",this.boundHandleSubmit),document.removeEventListener("click",this.boundHandleClick),document.removeEventListener("input",this.boundHandleInput),document.removeEventListener(P,this.boundHandleGhostValue),this.unhookValueSetters(),this.isListening=!1}isFormInput(A){if(!A||!(A instanceof HTMLElement))return!1;let B=A.tagName.toLowerCase();if(B==="textarea"||B==="select")return!0;if(B==="input"){let Q=A.type.toLowerCase();return!["submit","button","reset","hidden","image"].includes(Q)}return!1}isEmailField(A){let B=A.type?.toLowerCase()||"",Q=(A.name||"").toLowerCase(),E=(A.id||"").toLowerCase();return B==="email"||Q.includes("email")||Q.includes("e-mail")||E.includes("email")||E.includes("e-mail")}extractEmailDomain(A){if(!A||typeof A!=="string")return null;let B=A.trim();if(!B)return null;let Q=B.match(/@([a-zA-Z0-9.-]+\.[a-zA-Z]{2,})$/);return Q?Q[1].toLowerCase():null}getFieldId(A){return A.id||A.getAttribute("name")||`field-${A.tagName.toLowerCase()}`}handleFocusIn(A){if(!this.isFormInput(A.target))return;O().markFirstFormInteraction();let B=this.getFieldId(A.target),Q="direct";if(this.lastKeyWasTab)Q="tab";if(this.focusEvents.push({type:"focus",field:B,t:Date.now(),method:Q}),this.focusEvents.length>this.maxFocusEvents)this.focusEvents.shift();this.currentField=B,this.lastKeyWasTab=!1}handleFocusOut(A){if(!this.isFormInput(A.target))return;let B=A.target,Q=this.getFieldId(B);if(this.focusEvents.push({type:"blur",field:Q,t:Date.now()}),this.focusEvents.length>this.maxFocusEvents)this.focusEvents.shift();if(B instanceof HTMLInputElement&&this.isEmailField(B)){let E=this.extractEmailDomain(B.value);if(E)this.emailDomains.add(E)}this.currentField=null}handleClick(A){if(!this.isFormInput(A.target))return;let B=this.focusEvents[this.focusEvents.length-1];if(B&&B.type==="focus"&&Date.now()-B.t<50)B.method="click"}handleKeyDown(A){if(A.key==="Tab"){this.lastKeyWasTab=!0;return}if(!this.isFormInput(A.target))return;let B="key";if(A.key==="Backspace")B="backspace";else if(A.key==="Delete")B="delete";else if(A.key==="Enter")B="enter";else if(A.key==="Tab")B="tab";else if(A.key.length===1)B="char";else if(A.key.startsWith("Arrow"))B="arrow";if(this.keyEvents.push({type:"down",code:B,t:Date.now(),field:this.currentField||void 0}),this.keyEvents.length>this.maxKeyEvents)this.keyEvents.shift()}handleKeyUp(A){if(!this.isFormInput(A.target))return;let B="key";if(A.key==="Backspace")B="backspace";else if(A.key==="Delete")B="delete";else if(A.key.length===1)B="char";if(this.keyEvents.push({type:"up",code:B,t:Date.now(),field:this.currentField||void 0}),this.keyEvents.length>this.maxKeyEvents)this.keyEvents.shift()}handleInput(A){if(!this.isFormInput(A.target))return;let B=A.target,E=A.inputType||"unknown",I=B.value?.length??0;if(this.inputEvents.push({field:this.getFieldId(B),t:Date.now(),inputType:E,valueLength:I}),this.inputEvents.length>this.maxInputEvents)this.inputEvents.shift()}handlePaste(A){if(!this.isFormInput(A.target))return;let B=A.clipboardData?.getData("text")||"";this.pasteEvents.push({field:this.getFieldId(A.target),t:Date.now(),length:B.length})}handleSubmit(A){this.submitCount++;let B=A.target;if(B&&B.elements)for(let Q=0;Q<B.elements.length;Q++){let E=B.elements[Q];if(E instanceof HTMLInputElement&&this.isEmailField(E)){let I=this.extractEmailDomain(E.value);if(I)this.emailDomains.add(I)}}this.onSubmit?.()}getSignal(){return{keys:[...this.keyEvents],focus:[...this.focusEvents],pastes:[...this.pasteEvents],inputs:[...this.inputEvents],submits:this.submitCount,start_time:this.startTime,email_domains:this.emailDomains.size>0?Array.from(this.emailDomains):void 0}}flush(){this.keyEvents=[],this.focusEvents=[],this.pasteEvents=[],this.inputEvents=[]}getBufferSize(){return this.keyEvents.length+this.focusEvents.length+this.pasteEvents.length+this.inputEvents.length}reset(){this.keyEvents=[],this.focusEvents=[],this.pasteEvents=[],this.inputEvents=[],this.submitCount=0,this.startTime=Date.now(),this.lastKeyWasTab=!1,this.currentField=null,this.emailDomains.clear()}hookValueSetters(){if(this.valueSetterHooked)return;if(this.originalInputDescriptor=Object.getOwnPropertyDescriptor(HTMLInputElement.prototype,"value"),this.originalInputDescriptor){let A=this.originalInputDescriptor.set,B=this.originalInputDescriptor.get;Object.defineProperty(HTMLInputElement.prototype,"value",{configurable:!0,enumerable:!0,get(){return B?.call(this)},set(Q){let E=B?.call(this)??"";A?.call(this,Q);let I=Q??"";if(I!==E)this.dispatchEvent(new CustomEvent(P,{bubbles:!0,detail:{valueLength:I.length,wasEmpty:E.length===0}}))}})}if(this.originalTextareaDescriptor=Object.getOwnPropertyDescriptor(HTMLTextAreaElement.prototype,"value"),this.originalTextareaDescriptor){let A=this.originalTextareaDescriptor.set,B=this.originalTextareaDescriptor.get;Object.defineProperty(HTMLTextAreaElement.prototype,"value",{configurable:!0,enumerable:!0,get(){return B?.call(this)},set(Q){let E=B?.call(this)??"";A?.call(this,Q);let I=Q??"";if(I!==E)this.dispatchEvent(new CustomEvent(P,{bubbles:!0,detail:{valueLength:I.length,wasEmpty:E.length===0}}))}})}this.valueSetterHooked=!0}unhookValueSetters(){if(!this.valueSetterHooked)return;if(this.originalInputDescriptor)Object.defineProperty(HTMLInputElement.prototype,"value",this.originalInputDescriptor);if(this.originalTextareaDescriptor)Object.defineProperty(HTMLTextAreaElement.prototype,"value",this.originalTextareaDescriptor);this.valueSetterHooked=!1}handleGhostValue(A){let B=A.target;if(!this.isFormInput(B))return;let E=A.detail?.valueLength??0;if(this.inputEvents.push({field:this.getFieldId(B),t:Date.now(),inputType:"programmatic",valueLength:E}),this.inputEvents.length>this.maxInputEvents)this.inputEvents.shift()}}class f{cachedSignal=null;collect(){if(this.cachedSignal)return this.cachedSignal;let A=navigator,B=window;return this.cachedSignal={user_agent:navigator.userAgent,platform:navigator.platform,language:navigator.language,languages:[...navigator.languages||[]],hardware_concurrency:navigator.hardwareConcurrency??null,device_memory:A.deviceMemory??null,max_touch_points:navigator.maxTouchPoints??0,screen_width:screen.width,screen_height:screen.height,screen_avail_width:screen.availWidth,screen_avail_height:screen.availHeight,color_depth:screen.colorDepth,pixel_ratio:window.devicePixelRatio??1,...this.getWebGLInfo(),plugins_count:navigator.plugins?.length??0,mime_types_count:navigator.mimeTypes?.length??0,timezone:this.getTimezone(),timezone_offset:new Date().getTimezoneOffset(),has_webdriver:A.webdriver===!0,has_chrome_runtime:!!B.chrome?.runtime,has_chrome_app:!!B.chrome?.app,has_notification_api:"Notification"in window,has_permissions_api:"permissions"in navigator,outer_dimensions:{width:window.outerWidth,height:window.outerHeight},inner_dimensions:{width:window.innerWidth,height:window.innerHeight},notification_permission:this.getNotificationPermission()},this.cachedSignal}getWebGLInfo(){try{let A=document.createElement("canvas"),B=A.getContext("webgl")||A.getContext("experimental-webgl");if(!B||!(B instanceof WebGLRenderingContext))return{webgl_vendor:null,webgl_renderer:null};let Q=B.getExtension("WEBGL_debug_renderer_info");if(!Q)return{webgl_vendor:null,webgl_renderer:null};return{webgl_vendor:B.getParameter(Q.UNMASKED_VENDOR_WEBGL),webgl_renderer:B.getParameter(Q.UNMASKED_RENDERER_WEBGL)}}catch{return{webgl_vendor:null,webgl_renderer:null}}}getTimezone(){try{return Intl.DateTimeFormat().resolvedOptions().timeZone}catch{return null}}getNotificationPermission(){if("Notification"in window)return Notification.permission;return null}getSignal(){return this.collect()}reset(){this.cachedSignal=null}}b();class n{cachedFingerprint=null;async generate(){if(this.cachedFingerprint)return this.cachedFingerprint;let[A,B,Q,E,I]=await Promise.all([this.getCanvasHash(),this.getWebGLData(),this.getAudioHash(),this.getFontData(),this.getScreenHash()]),C={hash:"",canvas_hash:A,webgl_hash:B.hash,audio_hash:Q,font_hash:E.hash,screen_hash:I,webgl_vendor:B.vendor,webgl_renderer:B.renderer,timezone:this.getTimezone(),language:this.getLanguage(),platform:this.getPlatform(),font_count:E.count};return C.hash=await this.generateMainHash(C),this.cachedFingerprint=C,C}getFingerprint(){return this.cachedFingerprint}reset(){this.cachedFingerprint=null}async getCanvasHash(){try{let A=document.createElement("canvas");A.width=200,A.height=50;let B=A.getContext("2d");if(!B)return null;B.textBaseline="top",B.font="14px 'Arial'",B.fillStyle="#f60",B.fillRect(125,1,62,20),B.fillStyle="#069",B.fillText("BotSigged,\uD83C\uDFA8",2,15),B.fillStyle="rgba(102, 204, 0, 0.7)",B.fillText("BotSigged,\uD83C\uDFA8",4,17);let Q=A.toDataURL();return this.hashString(Q)}catch{return null}}async getWebGLData(){try{let A=document.createElement("canvas"),B=A.getContext("webgl")||A.getContext("experimental-webgl");if(!B||!(B instanceof WebGLRenderingContext))return{hash:null,vendor:null,renderer:null};let Q=[],E=[B.ALIASED_LINE_WIDTH_RANGE,B.ALIASED_POINT_SIZE_RANGE,B.ALPHA_BITS,B.BLUE_BITS,B.DEPTH_BITS,B.GREEN_BITS,B.MAX_COMBINED_TEXTURE_IMAGE_UNITS,B.MAX_CUBE_MAP_TEXTURE_SIZE,B.MAX_FRAGMENT_UNIFORM_VECTORS,B.MAX_RENDERBUFFER_SIZE,B.MAX_TEXTURE_IMAGE_UNITS,B.MAX_TEXTURE_SIZE,B.MAX_VARYING_VECTORS,B.MAX_VERTEX_ATTRIBS,B.MAX_VERTEX_TEXTURE_IMAGE_UNITS,B.MAX_VERTEX_UNIFORM_VECTORS,B.MAX_VIEWPORT_DIMS,B.RED_BITS,B.RENDERER,B.SHADING_LANGUAGE_VERSION,B.STENCIL_BITS,B.VENDOR,B.VERSION];for(let K of E)try{let X=B.getParameter(K);Q.push(String(X))}catch{Q.push("")}let I=B.getSupportedExtensions();if(I)Q.push(I.sort().join(","));let C=null,Y=null,G=B.getExtension("WEBGL_debug_renderer_info");if(G)C=B.getParameter(G.UNMASKED_VENDOR_WEBGL),Y=B.getParameter(G.UNMASKED_RENDERER_WEBGL);return{hash:this.hashString(Q.join("|")),vendor:C,renderer:Y}}catch{return{hash:null,vendor:null,renderer:null}}}async getAudioHash(){try{let A=window.OfflineAudioContext||window.webkitOfflineAudioContext;if(!A)return null;let B=new A(1,4500,44100),Q=B.createOscillator(),E=B.createDynamicsCompressor();Q.type="triangle",Q.frequency.setValueAtTime(1e4,B.currentTime),E.threshold.setValueAtTime(-50,B.currentTime),E.knee.setValueAtTime(40,B.currentTime),E.ratio.setValueAtTime(12,B.currentTime),E.attack.setValueAtTime(0,B.currentTime),E.release.setValueAtTime(0.25,B.currentTime),Q.connect(E),E.connect(B.destination),Q.start(0);let C=(await B.startRendering()).getChannelData(0),Y=[];for(let G=0;G<C.length;G+=100)Y.push(C[G]);return this.hashString(Y.join(","))}catch{return null}}async getFontData(){let A=["Arial","Arial Black","Arial Narrow","Calibri","Cambria","Cambria Math","Comic Sans MS","Consolas","Courier","Courier New","Georgia","Helvetica","Impact","Lucida Console","Lucida Sans Unicode","Microsoft Sans Serif","MS Gothic","MS PGothic","MS Sans Serif","MS Serif","Palatino Linotype","Segoe Print","Segoe Script","Segoe UI","Symbol","Tahoma","Times","Times New Roman","Trebuchet MS","Verdana","Wingdings"],B=["monospace","sans-serif","serif"],Q="mmmmmmmmmmlli",E="72px",I=document.createElement("span");I.style.position="absolute",I.style.left="-9999px",I.style.fontSize="72px",I.style.lineHeight="normal",I.innerHTML="mmmmmmmmmmlli",document.body.appendChild(I);let C={};for(let Z of B)I.style.fontFamily=Z,C[Z]=I.offsetWidth;let Y=[];for(let Z of A){let K=!1;for(let X of B)if(I.style.fontFamily=`'${Z}', ${X}`,I.offsetWidth!==C[X]){K=!0;break}if(K)Y.push(Z)}return document.body.removeChild(I),{hash:this.hashString(Y.join(",")),count:Y.length}}async getScreenHash(){let A=[String(screen.width),String(screen.height),String(screen.availWidth),String(screen.availHeight),String(screen.colorDepth),String(screen.pixelDepth),String(window.devicePixelRatio||1)];return this.hashString(A.join("|"))}getTimezone(){try{return Intl.DateTimeFormat().resolvedOptions().timeZone}catch{return null}}getLanguage(){return navigator.language||null}getPlatform(){return navigator.platform||null}generateMainHash(A){let B=[A.canvas_hash||"",A.webgl_hash||"",A.audio_hash||"",A.font_hash||"",A.screen_hash||"",A.timezone||"",A.language||"",A.platform||""];return this.hashString(B.join("|"))}hashString(A){return s(A)}}class t{ws=null;endpoint;apiKey;heartbeatInterval;reconnectAttempts;reconnectDelay;debug;state="disconnected";channelState="closed";refCounter=0;joinRef=null;heartbeatTimer=null;reconnectTimer=null;reconnectCount=0;pendingReplies=new Map;onConnectionChange;onError;channelCallbacks={};topic=null;constructor(A){this.endpoint=A.endpoint,this.apiKey=A.apiKey,this.heartbeatInterval=A.heartbeatInterval??30000,this.reconnectAttempts=A.reconnectAttempts??10,this.reconnectDelay=A.reconnectDelay??((B)=>Math.min(1000*Math.pow(2,B),30000)),this.debug=A.debug??!1,this.onConnectionChange=A.onConnectionChange,this.onError=A.onError}connect(){return new Promise((A,B)=>{if(this.ws&&this.state==="connected"){A();return}this.setState("connecting");let Q=this.buildUrl();this.log("Connecting to",Q);try{this.ws=new WebSocket(Q),this.ws.onopen=()=>{this.log("WebSocket connected"),this.setState("connected"),this.reconnectCount=0,this.startHeartbeat(),A()},this.ws.onclose=(E)=>{this.log("WebSocket closed",E.code,E.reason),this.handleClose()},this.ws.onerror=(E)=>{this.log("WebSocket error",E);let I=Error("WebSocket connection error");this.handleError(I),B(I)},this.ws.onmessage=(E)=>{this.handleMessage(E.data)}}catch(E){let I=E instanceof Error?E:Error(String(E));this.handleError(I),B(I)}})}disconnect(){if(this.stopHeartbeat(),this.stopReconnect(),this.ws)this.ws.close(1000,"Client disconnect"),this.ws=null;this.setState("disconnected"),this.setChannelState("closed")}joinChannel(A,B,Q,E,I={},C){return this.channelCallbacks=I,this.topic=`detection:${A}`,new Promise((Y,G)=>{if(this.state!=="connected"){G(Error("WebSocket not connected"));return}this.setChannelState("joining"),this.joinRef=this.makeRef();let Z={session_id:A,api_key:this.apiKey,fingerprint:B,session:Q,browser:E};if(C)Z.account_id=C;this.push("phx_join",Z,this.joinRef).then((K)=>{this.log("Channel joined",K),this.setChannelState("joined"),this.channelCallbacks.onJoin?.(),Y(K)}).catch((K)=>{this.log("Channel join failed",K),this.setChannelState("error"),this.channelCallbacks.onError?.(K),G(K)})})}leaveChannel(){return new Promise((A,B)=>{if(this.channelState!=="joined"){A();return}this.setChannelState("leaving"),this.push("phx_leave",{}).then(()=>{this.log("Channel left"),this.setChannelState("closed"),this.joinRef=null,this.topic=null,this.channelCallbacks.onLeave?.(),A()}).catch((Q)=>{this.setChannelState("error"),B(Q)})})}sendSignal(A){if(this.channelState!=="joined")return Promise.reject(Error("Channel not joined"));return this.push("signal",A)}sendFormStatus(A){if(this.channelState!=="joined")return Promise.reject(Error("Channel not joined"));return this.push("form_status",{status:A})}sendEvent(A,B){if(this.channelState!=="joined")return Promise.reject(Error("Channel not joined"));return this.push(A,B)}getState(){return this.state}getChannelState(){return this.channelState}isReady(){return this.state==="connected"&&this.channelState==="joined"}buildUrl(){let A=new URL(this.endpoint);return A.searchParams.set("vsn","2.0.0"),A.searchParams.set("api_key",this.apiKey),A.toString()}makeRef(){return this.refCounter++,String(this.refCounter)}push(A,B,Q){return new Promise((E,I)=>{if(!this.ws||this.ws.readyState!==WebSocket.OPEN){I(Error("WebSocket not open"));return}if(!this.topic){I(Error("Channel topic not set"));return}let C=Q??this.makeRef(),Y=[this.joinRef,C,this.topic,A,B],G=setTimeout(()=>{this.pendingReplies.delete(C),I(Error(`Timeout waiting for reply to ${A}`))},1e4);this.pendingReplies.set(C,{resolve:E,reject:I,timeout:G}),this.log("Sending",A,B),this.ws.send(JSON.stringify(Y))})}handleMessage(A){try{let[B,Q,E,I,C]=JSON.parse(A);if(this.log("Received",I,C),I==="phx_reply"&&Q){let Y=this.pendingReplies.get(Q);if(Y){clearTimeout(Y.timeout),this.pendingReplies.delete(Q);let G=C;if(G.status==="ok")Y.resolve(G.response??{});else if(G.response&&typeof G.response==="object"&&"code"in G.response)Y.reject(G.response);else{let Z=this.buildErrorMessage(G.status,G.response);Y.reject(Error(Z))}}return}if(I==="phx_error"){let Y=Error("Channel error");this.setChannelState("error"),this.channelCallbacks.onError?.(Y);return}if(I==="phx_close"){this.setChannelState("closed"),this.channelCallbacks.onLeave?.();return}if(I==="score_update"){this.channelCallbacks.onScoreUpdate?.(C);return}if(I==="action"){this.channelCallbacks.onAction?.(C);return}this.channelCallbacks.onMessage?.(I,C)}catch(B){this.log("Error parsing message",B)}}handleClose(){this.stopHeartbeat(),this.setState("disconnected"),this.setChannelState("closed");for(let[A,B]of this.pendingReplies)clearTimeout(B.timeout),B.reject(Error("Connection closed"));this.pendingReplies.clear(),this.scheduleReconnect()}handleError(A){this.setState("error"),this.onError?.(A)}startHeartbeat(){this.stopHeartbeat(),this.heartbeatTimer=setInterval(()=>{if(this.ws&&this.ws.readyState===WebSocket.OPEN){let A=[null,this.makeRef(),"phoenix","heartbeat",{}];if(this.ws.send(JSON.stringify(A)),this.channelState==="joined")this.push("heartbeat",{}).then((B)=>{if(B.bot_score!==void 0)this.channelCallbacks.onScoreUpdate?.({bot_score:B.bot_score,classification:B.classification,triggered_rules:[],event_count:0})}).catch(()=>{})}},this.heartbeatInterval)}stopHeartbeat(){if(this.heartbeatTimer)clearInterval(this.heartbeatTimer),this.heartbeatTimer=null}scheduleReconnect(){if(this.reconnectCount>=this.reconnectAttempts){this.log("Max reconnect attempts reached");return}let A=this.reconnectDelay(this.reconnectCount);this.reconnectCount++,this.log(`Scheduling reconnect attempt ${this.reconnectCount} in ${A}ms`),this.reconnectTimer=setTimeout(()=>{this.connect().catch((B)=>{this.log("Reconnect failed",B)})},A)}stopReconnect(){if(this.reconnectTimer)clearTimeout(this.reconnectTimer),this.reconnectTimer=null;this.reconnectCount=0}setState(A){if(this.state!==A)this.state=A,this.onConnectionChange?.(A)}setChannelState(A){this.channelState=A}buildErrorMessage(A,B){if(B){if(typeof B.reason==="string")return`Channel error: ${B.reason}`;if(Object.keys(B).length>0)return`Channel error (${A??"error"}): ${JSON.stringify(B)}`}return A??"Unknown error"}log(...A){if(this.debug);}}class o{config;isReady=!1;hasScore=!1;hasFormScore=!1;currentScore=null;pendingSubmissions=[];pendingRequests=[];protectedForms=new Set;releasingForms=new Set;loadingOverlay=null;formObserver=null;startTime;originalFetch=null;originalXHROpen=null;originalXHRSend=null;constructor(A={}){if(this.startTime=performance.now(),this.config={mode:A.mode??"none",minTimeBeforeSubmit:A.minTimeBeforeSubmit??500,maxHoldTime:A.maxHoldTime??5000,showLoadingUI:A.showLoadingUI??!0,loadingMessage:A.loadingMessage??"Please wait...",onHold:A.onHold,onRelease:A.onRelease,onBlock:A.onBlock,flushAndWaitForScore:A.flushAndWaitForScore},this.config.mode!=="none")this.setup()}setup(){if(this.config.mode==="auto")this.interceptFetch(),this.interceptXHR();let A=()=>{document.querySelectorAll("form").forEach((B)=>{this.protectForm(B)}),this.formObserver=new MutationObserver((B)=>{B.forEach((Q)=>{Q.addedNodes.forEach((E)=>{if(E instanceof HTMLFormElement)this.protectForm(E);if(E instanceof HTMLElement)E.querySelectorAll("form").forEach((I)=>{this.protectForm(I)})})})}),this.formObserver.observe(document.body,{childList:!0,subtree:!0})};if(document.body)A();else document.addEventListener("DOMContentLoaded",A,{once:!0})}isFormLikeRequest(A,B){if((B?.method?.toUpperCase()||"GET")!=="POST")return!1;try{if((typeof A==="string"?new URL(A,window.location.origin):A instanceof URL?A:new URL(A.url)).origin!==window.location.origin)return!1}catch{return!1}let E=B?.headers instanceof Headers?B.headers.get("content-type"):typeof B?.headers==="object"&&B.headers!==null?B.headers["content-type"]||B.headers["Content-Type"]:null;if(E){let I=E.toLowerCase();if(I.includes("application/x-www-form-urlencoded")||I.includes("multipart/form-data")||I.includes("application/json"))return!0;return!1}if(B?.body)return!0;return!1}interceptFetch(){this.originalFetch=window.fetch.bind(window);let A=this;window.fetch=async function(B,Q){if(!A.isFormLikeRequest(B,Q))return A.originalFetch(B,Q);if(A.hasScore)return A.originalFetch(B,Q);return new Promise((E,I)=>{let C={resolve:E,reject:I,execute:()=>A.originalFetch(B,Q),timestamp:performance.now()};if(A.pendingRequests.push(C),A.config.showLoadingUI&&A.pendingRequests.length===1)A.showLoading(document.createElement("form"));if(setTimeout(()=>{if(A.pendingRequests.includes(C))A.releaseRequest(C)},A.config.maxHoldTime),A.hasScore)A.releaseRequest(C)})}}interceptXHR(){this.originalXHROpen=XMLHttpRequest.prototype.open,this.originalXHRSend=XMLHttpRequest.prototype.send;let A=this;XMLHttpRequest.prototype.open=function(B,Q,E=!0,I,C){let Y=this;return Y._bsMethod=B.toUpperCase(),Y._bsUrl=Q.toString(),A.originalXHROpen.call(this,B,Q,E,I,C)},XMLHttpRequest.prototype.send=function(B){let Q=this,E=Q._bsMethod||"GET",I=Q._bsUrl||"";if(E!=="POST")return A.originalXHRSend.call(this,B);try{if(new URL(I,window.location.origin).origin!==window.location.origin)return A.originalXHRSend.call(this,B)}catch{return A.originalXHRSend.call(this,B)}if(A.hasScore)return A.originalXHRSend.call(this,B);let C=performance.now(),Y=()=>{if(A.hasScore){if(A.config.showLoadingUI)A.hideLoading();A.originalXHRSend.call(Q,B)}else if(performance.now()-C>=A.config.maxHoldTime){if(A.config.showLoadingUI)A.hideLoading();A.originalXHRSend.call(Q,B)}else setTimeout(Y,50)};if(A.config.showLoadingUI)A.showLoading(document.createElement("form"));Y()}}releaseRequest(A){let B=this.pendingRequests.indexOf(A);if(B===-1)return;if(this.pendingRequests.splice(B,1),this.pendingRequests.length===0&&this.config.showLoadingUI)this.hideLoading();A.execute().then(A.resolve).catch(A.reject)}protectForm(A){if(this.protectedForms.has(A))return;this.protectedForms.add(A),A.addEventListener("submit",(B)=>this.handleSubmit(B,A),{capture:!0})}handleSubmit(A,B){if(this.releasingForms.has(B)){this.releasingForms.delete(B);return}let E=performance.now()-this.startTime;switch(O().markFirstSubmitAttempt(this.hasScore),this.config.mode){case"holdUntilReady":if(!this.hasScore)A.preventDefault(),A.stopPropagation(),this.holdSubmission(B,A);break;case"holdUntilFormScored":A.preventDefault(),A.stopPropagation(),this.holdAndScoreSubmission(B,A);break;case"blockInstant":if(E<this.config.minTimeBeforeSubmit)A.preventDefault(),A.stopPropagation(),this.config.onBlock?.(B,"instant_submission");break;case"challengeFirst":if(!this.hasScore)A.preventDefault(),A.stopPropagation(),this.holdSubmission(B,A);break;case"none":default:break}}holdSubmission(A,B){if(this.config.onHold?.(A),this.config.showLoadingUI)this.showLoading(A);let Q={form:A,event:B,timestamp:performance.now(),resolver:()=>{},rejecter:()=>{}},E=new Promise((I,C)=>{Q.resolver=I,Q.rejecter=C});if(this.pendingSubmissions.push(Q),setTimeout(()=>{if(this.pendingSubmissions.includes(Q))this.releaseSubmission(Q,!1)},this.config.maxHoldTime),this.hasScore)this.releaseSubmission(Q,!1);E.catch(()=>{})}async holdAndScoreSubmission(A,B){if(this.config.onHold?.(A),this.config.showLoadingUI)this.showLoading(A);let Q=performance.now();try{if(!this.config.flushAndWaitForScore){this.submitForm(A);return}let E=this.config.flushAndWaitForScore(),I=new Promise((G)=>{setTimeout(()=>G(null),this.config.maxHoldTime)}),C=await Promise.race([E,I]),Y=performance.now()-Q;if(C===null);else this.currentScore=C,this.hasFormScore=!0;if(this.config.showLoadingUI)this.hideLoading();this.config.onRelease?.(A,!1),this.submitForm(A)}catch(E){if(this.config.showLoadingUI)this.hideLoading();this.config.onRelease?.(A,!1),this.submitForm(A)}}submitForm(A){if(this.releasingForms.add(A),A.requestSubmit)A.requestSubmit();else A.submit()}releaseSubmission(A,B){let Q=this.pendingSubmissions.indexOf(A);if(Q===-1)return;if(this.pendingSubmissions.splice(Q,1),this.config.showLoadingUI)this.hideLoading();if(this.config.onRelease?.(A.form,B),!B)if(A.resolver(),A.form.requestSubmit)A.form.requestSubmit();else A.form.submit();else A.rejecter("blocked")}showLoading(A){if(this.loadingOverlay)return;this.loadingOverlay=document.createElement("div"),this.loadingOverlay.innerHTML=`
|
|
44
44
|
<div style="
|
|
45
45
|
position: fixed;
|
|
46
46
|
top: 0;
|
|
@@ -0,0 +1,333 @@
|
|
|
1
|
+
import {
|
|
2
|
+
getHash
|
|
3
|
+
} from "./hash-gtpm69df.js";
|
|
4
|
+
|
|
5
|
+
// src/challenge-ui.ts
|
|
6
|
+
class ChallengeOverlay {
|
|
7
|
+
overlay = null;
|
|
8
|
+
messageEl = null;
|
|
9
|
+
progressEl = null;
|
|
10
|
+
config;
|
|
11
|
+
constructor(config) {
|
|
12
|
+
this.config = config;
|
|
13
|
+
}
|
|
14
|
+
show() {
|
|
15
|
+
if (!this.config.enabled || this.overlay)
|
|
16
|
+
return;
|
|
17
|
+
this.overlay = document.createElement("div");
|
|
18
|
+
this.overlay.id = "botsigged-challenge-overlay";
|
|
19
|
+
this.overlay.style.cssText = `
|
|
20
|
+
position: fixed;
|
|
21
|
+
top: 0;
|
|
22
|
+
left: 0;
|
|
23
|
+
width: 100%;
|
|
24
|
+
height: 100%;
|
|
25
|
+
background: ${this.config.backgroundColor};
|
|
26
|
+
display: flex;
|
|
27
|
+
flex-direction: column;
|
|
28
|
+
align-items: center;
|
|
29
|
+
justify-content: center;
|
|
30
|
+
z-index: ${this.config.zIndex};
|
|
31
|
+
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
|
|
32
|
+
`;
|
|
33
|
+
const spinner = document.createElement("div");
|
|
34
|
+
spinner.style.cssText = `
|
|
35
|
+
width: 48px;
|
|
36
|
+
height: 48px;
|
|
37
|
+
border: 4px solid ${this.config.textColor}33;
|
|
38
|
+
border-top-color: ${this.config.spinnerColor};
|
|
39
|
+
border-radius: 50%;
|
|
40
|
+
animation: botsigged-spin 1s linear infinite;
|
|
41
|
+
margin-bottom: 20px;
|
|
42
|
+
`;
|
|
43
|
+
this.messageEl = document.createElement("span");
|
|
44
|
+
this.messageEl.textContent = this.config.message;
|
|
45
|
+
this.messageEl.style.cssText = `
|
|
46
|
+
color: ${this.config.textColor};
|
|
47
|
+
font-size: 18px;
|
|
48
|
+
font-weight: 500;
|
|
49
|
+
margin-bottom: 12px;
|
|
50
|
+
`;
|
|
51
|
+
const progressContainer = document.createElement("div");
|
|
52
|
+
progressContainer.style.cssText = `
|
|
53
|
+
width: 200px;
|
|
54
|
+
height: 4px;
|
|
55
|
+
background: ${this.config.textColor}33;
|
|
56
|
+
border-radius: 2px;
|
|
57
|
+
overflow: hidden;
|
|
58
|
+
`;
|
|
59
|
+
this.progressEl = document.createElement("div");
|
|
60
|
+
this.progressEl.style.cssText = `
|
|
61
|
+
width: 0%;
|
|
62
|
+
height: 100%;
|
|
63
|
+
background: ${this.config.spinnerColor};
|
|
64
|
+
border-radius: 2px;
|
|
65
|
+
transition: width 0.1s ease-out;
|
|
66
|
+
`;
|
|
67
|
+
progressContainer.appendChild(this.progressEl);
|
|
68
|
+
const style = document.createElement("style");
|
|
69
|
+
style.textContent = `
|
|
70
|
+
@keyframes botsigged-spin {
|
|
71
|
+
to { transform: rotate(360deg); }
|
|
72
|
+
}
|
|
73
|
+
`;
|
|
74
|
+
document.head.appendChild(style);
|
|
75
|
+
this.overlay.appendChild(spinner);
|
|
76
|
+
this.overlay.appendChild(this.messageEl);
|
|
77
|
+
this.overlay.appendChild(progressContainer);
|
|
78
|
+
document.body.appendChild(this.overlay);
|
|
79
|
+
}
|
|
80
|
+
setProgress(progress) {
|
|
81
|
+
if (this.progressEl) {
|
|
82
|
+
const percent = Math.min(100, Math.max(0, progress * 100));
|
|
83
|
+
this.progressEl.style.width = `${percent}%`;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
showSuccess() {
|
|
87
|
+
if (this.messageEl) {
|
|
88
|
+
this.messageEl.textContent = this.config.successMessage;
|
|
89
|
+
}
|
|
90
|
+
if (this.progressEl) {
|
|
91
|
+
this.progressEl.style.width = "100%";
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
hide() {
|
|
95
|
+
if (this.overlay) {
|
|
96
|
+
this.overlay.remove();
|
|
97
|
+
this.overlay = null;
|
|
98
|
+
this.messageEl = null;
|
|
99
|
+
this.progressEl = null;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
isVisible() {
|
|
103
|
+
return this.overlay !== null;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
// src/challenge.ts
|
|
108
|
+
function generateChallengePrefix() {
|
|
109
|
+
const prefix = new Uint8Array(16);
|
|
110
|
+
if (typeof crypto !== "undefined" && crypto.getRandomValues) {
|
|
111
|
+
crypto.getRandomValues(prefix);
|
|
112
|
+
} else {
|
|
113
|
+
for (let i = 0;i < 16; i++) {
|
|
114
|
+
prefix[i] = Math.floor(Math.random() * 256);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
return prefix;
|
|
118
|
+
}
|
|
119
|
+
function countLeadingZeroBits(value) {
|
|
120
|
+
if (value === 0)
|
|
121
|
+
return 32;
|
|
122
|
+
let count = 0;
|
|
123
|
+
if ((value & 4294901760) === 0) {
|
|
124
|
+
count += 16;
|
|
125
|
+
value <<= 16;
|
|
126
|
+
}
|
|
127
|
+
if ((value & 4278190080) === 0) {
|
|
128
|
+
count += 8;
|
|
129
|
+
value <<= 8;
|
|
130
|
+
}
|
|
131
|
+
if ((value & 4026531840) === 0) {
|
|
132
|
+
count += 4;
|
|
133
|
+
value <<= 4;
|
|
134
|
+
}
|
|
135
|
+
if ((value & 3221225472) === 0) {
|
|
136
|
+
count += 2;
|
|
137
|
+
value <<= 2;
|
|
138
|
+
}
|
|
139
|
+
if ((value & 2147483648) === 0) {
|
|
140
|
+
count += 1;
|
|
141
|
+
}
|
|
142
|
+
return count;
|
|
143
|
+
}
|
|
144
|
+
function solvePoWChunkJS(prefix, difficulty, chunkSize, startNonce) {
|
|
145
|
+
const hashModule = getHash();
|
|
146
|
+
const buffer = new Uint8Array(prefix.length + 4);
|
|
147
|
+
buffer.set(prefix);
|
|
148
|
+
let nonce = startNonce;
|
|
149
|
+
let iterations = 0;
|
|
150
|
+
while (iterations < chunkSize) {
|
|
151
|
+
buffer[prefix.length] = nonce & 255;
|
|
152
|
+
buffer[prefix.length + 1] = nonce >>> 8 & 255;
|
|
153
|
+
buffer[prefix.length + 2] = nonce >>> 16 & 255;
|
|
154
|
+
buffer[prefix.length + 3] = nonce >>> 24 & 255;
|
|
155
|
+
const hash = hashModule.xxHash32(buffer, 0);
|
|
156
|
+
iterations++;
|
|
157
|
+
if (countLeadingZeroBits(hash) >= difficulty) {
|
|
158
|
+
return { nonce, found: true, iterations };
|
|
159
|
+
}
|
|
160
|
+
nonce = nonce + 1 >>> 0;
|
|
161
|
+
}
|
|
162
|
+
return { nonce, found: false, iterations };
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
class ChallengeManager {
|
|
166
|
+
config;
|
|
167
|
+
overlay;
|
|
168
|
+
solving = false;
|
|
169
|
+
solved = false;
|
|
170
|
+
pendingForms = new Map;
|
|
171
|
+
formHandler = null;
|
|
172
|
+
formObserver = null;
|
|
173
|
+
resubmitting = false;
|
|
174
|
+
debug;
|
|
175
|
+
constructor(config, debug = false) {
|
|
176
|
+
this.config = config;
|
|
177
|
+
this.debug = debug;
|
|
178
|
+
this.overlay = new ChallengeOverlay(config.ui);
|
|
179
|
+
}
|
|
180
|
+
getDifficultyForLevel(level) {
|
|
181
|
+
const difficulty = this.config.difficulty;
|
|
182
|
+
switch (level) {
|
|
183
|
+
case "critical":
|
|
184
|
+
return difficulty.critical;
|
|
185
|
+
case "high":
|
|
186
|
+
return difficulty.high;
|
|
187
|
+
case "medium":
|
|
188
|
+
return difficulty.medium;
|
|
189
|
+
default:
|
|
190
|
+
return 0;
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
shouldChallenge(level) {
|
|
194
|
+
if (!this.config.enabled || this.solved)
|
|
195
|
+
return false;
|
|
196
|
+
const levelOrder = ["low", "medium", "high", "critical"];
|
|
197
|
+
const levelIndex = levelOrder.indexOf(level);
|
|
198
|
+
const minIndex = levelOrder.indexOf(this.config.minLevel);
|
|
199
|
+
return levelIndex >= minIndex;
|
|
200
|
+
}
|
|
201
|
+
blockFormsUntilSolved(level) {
|
|
202
|
+
if (this.formHandler)
|
|
203
|
+
return;
|
|
204
|
+
this.formHandler = (e) => {
|
|
205
|
+
if (this.solved || this.resubmitting)
|
|
206
|
+
return;
|
|
207
|
+
e.preventDefault();
|
|
208
|
+
e.stopPropagation();
|
|
209
|
+
const form = e.target;
|
|
210
|
+
if (!this.pendingForms.has(form)) {
|
|
211
|
+
this.pendingForms.set(form, e);
|
|
212
|
+
}
|
|
213
|
+
if (!this.solving) {
|
|
214
|
+
this.startChallenge(level);
|
|
215
|
+
}
|
|
216
|
+
};
|
|
217
|
+
document.querySelectorAll("form").forEach((form) => {
|
|
218
|
+
form.addEventListener("submit", this.formHandler, true);
|
|
219
|
+
});
|
|
220
|
+
this.formObserver = new MutationObserver((mutations) => {
|
|
221
|
+
mutations.forEach((mutation) => {
|
|
222
|
+
mutation.addedNodes.forEach((node) => {
|
|
223
|
+
if (node instanceof HTMLFormElement && this.formHandler) {
|
|
224
|
+
node.addEventListener("submit", this.formHandler, true);
|
|
225
|
+
}
|
|
226
|
+
if (node instanceof HTMLElement && this.formHandler) {
|
|
227
|
+
node.querySelectorAll("form").forEach((form) => {
|
|
228
|
+
form.addEventListener("submit", this.formHandler, true);
|
|
229
|
+
});
|
|
230
|
+
}
|
|
231
|
+
});
|
|
232
|
+
});
|
|
233
|
+
});
|
|
234
|
+
this.formObserver.observe(document.body, { childList: true, subtree: true });
|
|
235
|
+
this.log("Forms blocked, challenge required");
|
|
236
|
+
}
|
|
237
|
+
async startChallenge(level) {
|
|
238
|
+
if (this.solving || this.solved)
|
|
239
|
+
return;
|
|
240
|
+
this.solving = true;
|
|
241
|
+
const difficulty = this.getDifficultyForLevel(level);
|
|
242
|
+
const prefix = generateChallengePrefix();
|
|
243
|
+
const startTime = performance.now();
|
|
244
|
+
this.log(`Starting challenge: difficulty=${difficulty}, level=${level}`);
|
|
245
|
+
this.config.onChallengeStart?.(level, difficulty);
|
|
246
|
+
this.overlay.show();
|
|
247
|
+
const estimatedIterations = 1 << difficulty;
|
|
248
|
+
let nonce = 0;
|
|
249
|
+
let totalIterations = 0;
|
|
250
|
+
let result;
|
|
251
|
+
do {
|
|
252
|
+
await new Promise((resolve) => setTimeout(resolve, 0));
|
|
253
|
+
result = solvePoWChunkJS(prefix, difficulty, this.config.chunkSize, nonce);
|
|
254
|
+
totalIterations += result.iterations;
|
|
255
|
+
nonce = result.nonce + 1;
|
|
256
|
+
const progress = Math.min(1, totalIterations / estimatedIterations);
|
|
257
|
+
this.overlay.setProgress(progress);
|
|
258
|
+
this.config.onChallengeProgress?.(progress, totalIterations);
|
|
259
|
+
} while (!result.found);
|
|
260
|
+
const solveTime = performance.now() - startTime;
|
|
261
|
+
this.log(`Challenge solved: nonce=${result.nonce}, iterations=${totalIterations}, time=${solveTime.toFixed(0)}ms`);
|
|
262
|
+
this.overlay.showSuccess();
|
|
263
|
+
await new Promise((resolve) => setTimeout(resolve, 500));
|
|
264
|
+
this.overlay.hide();
|
|
265
|
+
this.solved = true;
|
|
266
|
+
this.solving = false;
|
|
267
|
+
const event = {
|
|
268
|
+
solveTimeMs: solveTime,
|
|
269
|
+
iterations: totalIterations,
|
|
270
|
+
difficulty,
|
|
271
|
+
level,
|
|
272
|
+
nonce: result.nonce
|
|
273
|
+
};
|
|
274
|
+
this.config.onChallengeComplete?.(event);
|
|
275
|
+
this.unblockForms();
|
|
276
|
+
}
|
|
277
|
+
unblockForms() {
|
|
278
|
+
if (this.formObserver) {
|
|
279
|
+
this.formObserver.disconnect();
|
|
280
|
+
this.formObserver = null;
|
|
281
|
+
}
|
|
282
|
+
if (this.formHandler) {
|
|
283
|
+
document.querySelectorAll("form").forEach((form) => {
|
|
284
|
+
form.removeEventListener("submit", this.formHandler, true);
|
|
285
|
+
});
|
|
286
|
+
this.formHandler = null;
|
|
287
|
+
}
|
|
288
|
+
this.log("Forms unblocked");
|
|
289
|
+
this.resubmitting = true;
|
|
290
|
+
this.pendingForms.forEach((_, form) => {
|
|
291
|
+
this.log("Resubmitting pending form");
|
|
292
|
+
if (form.requestSubmit) {
|
|
293
|
+
form.requestSubmit();
|
|
294
|
+
} else {
|
|
295
|
+
form.submit();
|
|
296
|
+
}
|
|
297
|
+
});
|
|
298
|
+
this.pendingForms.clear();
|
|
299
|
+
this.resubmitting = false;
|
|
300
|
+
}
|
|
301
|
+
isSolving() {
|
|
302
|
+
return this.solving;
|
|
303
|
+
}
|
|
304
|
+
isSolved() {
|
|
305
|
+
return this.solved;
|
|
306
|
+
}
|
|
307
|
+
reset() {
|
|
308
|
+
if (this.formObserver) {
|
|
309
|
+
this.formObserver.disconnect();
|
|
310
|
+
this.formObserver = null;
|
|
311
|
+
}
|
|
312
|
+
if (this.formHandler) {
|
|
313
|
+
document.querySelectorAll("form").forEach((form) => {
|
|
314
|
+
form.removeEventListener("submit", this.formHandler, true);
|
|
315
|
+
});
|
|
316
|
+
this.formHandler = null;
|
|
317
|
+
}
|
|
318
|
+
this.solved = false;
|
|
319
|
+
this.solving = false;
|
|
320
|
+
this.resubmitting = false;
|
|
321
|
+
this.pendingForms.clear();
|
|
322
|
+
}
|
|
323
|
+
log(...args) {
|
|
324
|
+
if (this.debug) {
|
|
325
|
+
console.log("[BotSigged:Challenge]", ...args);
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
export {
|
|
330
|
+
ChallengeManager
|
|
331
|
+
};
|
|
332
|
+
|
|
333
|
+
//# debugId=B0255CA1E0DDDD3364756E2164756E21
|
|
@@ -0,0 +1,300 @@
|
|
|
1
|
+
var __create = Object.create;
|
|
2
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __toESM = (mod, isNodeMode, target) => {
|
|
7
|
+
target = mod != null ? __create(__getProtoOf(mod)) : {};
|
|
8
|
+
const to = isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target;
|
|
9
|
+
for (let key of __getOwnPropNames(mod))
|
|
10
|
+
if (!__hasOwnProp.call(to, key))
|
|
11
|
+
__defProp(to, key, {
|
|
12
|
+
get: () => mod[key],
|
|
13
|
+
enumerable: true
|
|
14
|
+
});
|
|
15
|
+
return to;
|
|
16
|
+
};
|
|
17
|
+
var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
|
|
18
|
+
get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
|
|
19
|
+
}) : x)(function(x) {
|
|
20
|
+
if (typeof require !== "undefined")
|
|
21
|
+
return require.apply(this, arguments);
|
|
22
|
+
throw Error('Dynamic require of "' + x + '" is not supported');
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
// src/wasm/hash.wasm.base64.ts
|
|
26
|
+
var wasmBinaryBase64 = "AGFzbQEAAAABOgpgAn9/AX9gAX8Bf2ACf38AYAN/f38Bf2ADf39/AGAEf39/fwF/YAF/AGAAAGAEf39/fwBgAn9/AX4CDQEDZW52BWFib3J0AAgDIyIAAQAAAAAACQIBAgIAAQQAAAADAwIBBAAFBQMBAQYBBwYHBQMBAAEGEQN/AUEAC38BQQALfwBB0AwLB5ACFAdmbnYxYTMyAAIIeHhIYXNoMzIABwxjb21iaW5lZEhhc2gACApoYXNoU3RyaW5nABEPaGFzaFN0cmluZ1RvSGV4ABIKdmVyaWZ5SGFzaAATEHZlcmlmeVN0cmluZ0hhc2gAFAhzb2x2ZVBvVwAZDXNvbHZlUG9XQ2h1bmsAGgl2ZXJpZnlQb1cAGxJlc3RpbWF0ZUl0ZXJhdGlvbnMAHA1hbGxvY2F0ZUJ5dGVzAB0JZnJlZUJ5dGVzAB4FX19uZXcADQVfX3BpbgAfB19fdW5waW4AHglfX2NvbGxlY3QAIAtfX3J0dGlfYmFzZQMCBm1lbW9yeQIAFF9fc2V0QXJndW1lbnRzTGVuZ3RoACEIASIMARUKyRIiJgAgASAAKAIITwRAQaAIQeAIQacBQS0QAAALIAAoAgQgAWotAAALNgECf0HFu/KIeCEBA0AgAiAAKAIISARAIAAgAhABIAFzQZODgAhsIQEgAkEBaiECDAELCyABCy8AIAAgARABIAAgAUEBahABQQh0ciAAIAFBAmoQAUEQdHIgACABQQNqEAFBGHRyCxAAIAAgAXQgAEEgIAFrdnILGQAgACABQfeUr694bGpBDRAEQbHz3fF5bAvBAgEGfyAAKAIIIgNBEE4EfyADQRBrIQcgAUGoiI2hAmohBCABQYnr0NAHayEFIAFBz4yijgZqIQYDQCACIAdMBEAgBCAAIAIQAxAFIQQgBSAAIAJBBGoiAhADEAUhBSABIAAgAkEEaiICEAMQBSEBIAYgACACQQRqIgIQAxAFIQYgAkEEaiECDAELCyAEQQEQBCAFQQcQBGogAUEMEARqIAZBEhAEagUgAUGxz9myAWoLIANqIQEDQCACIANBBGtMBEAgASAAIAIQA0G93MqVfGxqQREQBEGv1tO+AmwhASACQQRqIQIMAQsLA0AgAiADSARAIAEgACACEAFBsc/ZsgFsakELEARBsfPd8XlsIQEgAkEBaiECDAELCyABIAFBD3ZzQfeUr694bCIAIABBDXZzQb3cypV8bCIAIABBEHZzCyAAAkACQAJAIwBBAWsOAgECAAsAC0EAIQELIAAgARAGCyoAAkACQAJAIwBBAWsOAgECAAsAC0EAIQELIAAQAq1CIIYgACABEAathAsJACAAIAE2AgALggEBBX8gAEH8////A0sEQEGgCUHgCUEhQR0QAAALIwEjAUEEaiICIABBE2pBcHFBBGsiAGoiAz8AIgRBEHRBD2pBcHEiBUsEQCAEIAMgBWtB//8DakGAgHxxQRB2IgUgBCAFShtAAEEASARAIAVAAEEASARAAAsLCyADJAEgABAJIAILCQAgACABNgIECwkAIAAgATYCCAtJAQJ/IABB7P///wNLBEBBoAlB4AlB1gBBHhAAAAsgAEEQahAKIgNBBGsiAkEAEAsgAkEAEAwgAiABNgIMIAIgADYCECADQRBqCw0AIABBFGsoAhBBAXYLsgIBAn8gACABQQF0aiEDIAIhAQNAIAAgA0kEQCAALwEAIgJBgAFJBH8gASACOgAAIAFBAWoFIAJBgBBJBH8gASACQQZ2QcABciACQT9xQYABckEIdHI7AQAgAUECagUgAkGAuANJIABBAmogA0lxIAJBgPADcUGAsANGcQRAIAAvAQIiBEGA+ANxQYC4A0YEQCABIAJB/wdxQQp0QYCABGogBEH/B3FyIgJBP3FBgAFyQRh0IAJBBnZBP3FBgAFyQRB0ciACQQx2QT9xQYABckEIdHIgAkESdkHwAXJyNgIAIAFBBGohASAAQQRqIQAMBQsLIAEgAkEMdkHgAXIgAkEGdkE/cUGAAXJBCHRyOwEAIAEgAkE/cUGAAXI6AAIgAUEDagsLIQEgAEECaiEADAELCwvQAQEEf0EBJAAgACICQRRrKAIQIAJqIQQDQCACIARJBEAgAi8BACIFQYABSQR/IANBAWoFIAVBgBBJBH8gA0ECagUgBUGA+ANxQYCwA0YgAkECaiAESXEEQCACLwECQYD4A3FBgLgDRgRAIANBBGohAyACQQRqIQIMBQsLIANBA2oLCyEDIAJBAmohAgwBCwsgA0EBEA0hAiAAIAAQDiACEA9BASQAIAJBFGsoAhAhAEEMQQQQDSIDIAI2AgAgAyAANgIIIAMgAjYCBCADIAEQBgsgAAJAAkACQCMAQQFrDgIBAgALAAtBACEBCyAAIAEQEAuzAQEGfwJAAkACQCMAQQFrDgIBAgALAAtBACEBCyAAIAEQECEFQYAMIQBBByECA0AgAkEATgRAQYAMIQNBwAsQDiAFIAJBAnR2QQ9xIgFLBEBBAkECEA0iAyABQQF0QcALai8BADsBAAsgACEBQYAMIQAgARAOQQF0IgQgAxAOQQF0IgZqIgcEQCAHQQIQDSIAIAEgBPwKAAAgACAEaiADIAb8CgAACyACQQFrIQIMAQsLIAALIwACQAJAAkAjAEECaw4CAQIACwALQQAhAgsgACACEAYgAUYLIwACQAJAAkAjAEECaw4CAQIACwALQQAhAgsgACACEBAgAUYLCQAgACABOgAEC2YBAn9BDEEEEA0iAUUEQEEMQQMQDSEBCyABQQAQCSABQQAQCyABQQAQDCAAQfz///8DSwRAQZALQaAMQRNBORAAAAsgAEEBEA0iAkEAIAD8CwAgASACEAkgASACEAsgASAAEAwgAQsoACABIAAoAghPBEBBoAhB4AhBsgFBLRAAAAsgACgCBCABaiACOgAAC4cBAQF/IAAEfyAAQYCAfHFFBEBBECECIABBEHQhAAsgAEGAgIB4cUUEQCACQQhqIQIgAEEIdCEACyAAQYCAgIB/cUUEQCACQQRqIQIgAEEEdCEACyAAQYCAgIB8cQR/IAAFIAJBAmohAiAAQQJ0C0GAgICAeHEEfyACBSACQQFqCwVBIAsgAU8LgQIBBX9BDBAKIgRBABAJIARBABAVIARBABAMIARBABAJIARBABAVIARBABAMQSAgASABQSBLGyEHIAAoAggiAUEEahAWIQgDQCABIAVKBEAgCCAFIAAgBRABEBcgBUEBaiEFDAELCyADIQAgAkUhBQNAIAIgBksgBXIEQAJAIAggASAAQf8BcRAXIAggAUEBaiAAQQh2Qf8BcRAXIAggAUECaiAAQRB2Qf8BcRAXIAggAUEDaiAAQRh2EBcgBkEBaiEGIAhBABAGIAcQGARAIAQgABAJIARBARAVIAQgBhAMIAQPCyAAQQFqIgBFIANBAEdxDQAMAgsLCyAEIAYQDCAECwwAIAAgASACIAMQGQt6AQN/IAAoAggiBEEEahAWIQMDQCAEIAVKBEAgAyAFIAAgBRABEBcgBUEBaiEFDAELCyADIAQgAUH/AXEQFyADIARBAWogAUEIdkH/AXEQFyADIARBAmogAUEQdkH/AXEQFyADIARBA2ogAUEYdhAXIANBABAGIAIQGAsSACAAQSBPBEBBfw8LQQEgAHQLBgAgABAWCwIACwQAIAALAgALBgAgACQACwcAQewMJAELC44EFQBBjAgLATwAQZgICysCAAAAJAAAAEkAbgBkAGUAeAAgAG8AdQB0ACAAbwBmACAAcgBhAG4AZwBlAEHMCAsBPABB2AgLKwIAAAAkAAAAfgBsAGkAYgAvAHQAeQBwAGUAZABhAHIAcgBhAHkALgB0AHMAQYwJCwE8AEGYCQsvAgAAACgAAABBAGwAbABvAGMAYQB0AGkAbwBuACAAdABvAG8AIABsAGEAcgBnAGUAQcwJCwE8AEHYCQslAgAAAB4AAAB+AGwAaQBiAC8AcgB0AC8AcwB0AHUAYgAuAHQAcwBBjAoLATwAQZgKCysCAAAAJAAAAFUAbgBwAGEAaQByAGUAZAAgAHMAdQByAHIAbwBnAGEAdABlAEHMCgsBLABB2AoLIwIAAAAcAAAAfgBsAGkAYgAvAHMAdAByAGkAbgBnAC4AdABzAEH8CgsBLABBiAsLIwIAAAAcAAAASQBuAHYAYQBsAGkAZAAgAGwAZQBuAGcAdABoAEGsCwsBPABBuAsLJwIAAAAgAAAAMAAxADIAMwA0ADUANgA3ADgAOQBhAGIAYwBkAGUAZgBB7AsLARwAQfgLCwECAEGMDAsBPABBmAwLLQIAAAAmAAAAfgBsAGkAYgAvAGEAcgByAGEAeQBiAHUAZgBmAGUAcgAuAHQAcwBB0AwLFQUAAAAgAAAAIAAAACAAAAAAAAAAQQ==";
|
|
27
|
+
var hash_wasm_base64_default = wasmBinaryBase64;
|
|
28
|
+
|
|
29
|
+
// src/wasm/hash-wasm.ts
|
|
30
|
+
var wasmInstance = null;
|
|
31
|
+
var loadPromise = null;
|
|
32
|
+
function base64ToBytes(base64) {
|
|
33
|
+
const binaryString = atob(base64);
|
|
34
|
+
const bytes = new Uint8Array(binaryString.length);
|
|
35
|
+
for (let i = 0;i < binaryString.length; i++) {
|
|
36
|
+
bytes[i] = binaryString.charCodeAt(i);
|
|
37
|
+
}
|
|
38
|
+
return bytes;
|
|
39
|
+
}
|
|
40
|
+
async function loadHashModule() {
|
|
41
|
+
if (loadPromise) {
|
|
42
|
+
return loadPromise;
|
|
43
|
+
}
|
|
44
|
+
loadPromise = (async () => {
|
|
45
|
+
try {
|
|
46
|
+
const wasmBytes = base64ToBytes(hash_wasm_base64_default);
|
|
47
|
+
const wasmModule = await WebAssembly.compile(wasmBytes);
|
|
48
|
+
const instance = await WebAssembly.instantiate(wasmModule, {
|
|
49
|
+
env: {
|
|
50
|
+
abort: (_msg, _file, line, col) => {
|
|
51
|
+
console.error(`WASM abort at ${line}:${col}`);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
});
|
|
55
|
+
wasmInstance = instance.exports;
|
|
56
|
+
return createHashModule(wasmInstance);
|
|
57
|
+
} catch (error) {
|
|
58
|
+
loadPromise = null;
|
|
59
|
+
throw error;
|
|
60
|
+
}
|
|
61
|
+
})();
|
|
62
|
+
return loadPromise;
|
|
63
|
+
}
|
|
64
|
+
function isHashModuleLoaded() {
|
|
65
|
+
return wasmInstance !== null;
|
|
66
|
+
}
|
|
67
|
+
function createHashModule(wasm) {
|
|
68
|
+
function writeBytes(data) {
|
|
69
|
+
const ptr = wasm.__new(data.length, 1);
|
|
70
|
+
const view = new Uint8Array(wasm.memory.buffer, ptr, data.length);
|
|
71
|
+
view.set(data);
|
|
72
|
+
return ptr;
|
|
73
|
+
}
|
|
74
|
+
function writeString(str) {
|
|
75
|
+
const buf = new Uint16Array(str.length);
|
|
76
|
+
for (let i = 0;i < str.length; i++) {
|
|
77
|
+
buf[i] = str.charCodeAt(i);
|
|
78
|
+
}
|
|
79
|
+
const ptr = wasm.__new(buf.length * 2, 2);
|
|
80
|
+
const mem = new Uint16Array(wasm.memory.buffer, ptr, buf.length);
|
|
81
|
+
mem.set(buf);
|
|
82
|
+
return ptr;
|
|
83
|
+
}
|
|
84
|
+
function readString(ptr, maxLength = 1024) {
|
|
85
|
+
const memory = new Uint8Array(wasm.memory.buffer);
|
|
86
|
+
const memoryLength = memory.length;
|
|
87
|
+
if (ptr < 0 || ptr >= memoryLength) {
|
|
88
|
+
return "";
|
|
89
|
+
}
|
|
90
|
+
let end = ptr;
|
|
91
|
+
const limit = Math.min(ptr + maxLength, memoryLength);
|
|
92
|
+
while (end < limit && memory[end] !== 0) {
|
|
93
|
+
end++;
|
|
94
|
+
}
|
|
95
|
+
const bytes = memory.slice(ptr, end);
|
|
96
|
+
return new TextDecoder().decode(bytes);
|
|
97
|
+
}
|
|
98
|
+
return {
|
|
99
|
+
xxHash32(data, seed = 0) {
|
|
100
|
+
const ptr = writeBytes(data);
|
|
101
|
+
try {
|
|
102
|
+
return wasm.xxHash32(ptr, seed);
|
|
103
|
+
} finally {
|
|
104
|
+
wasm.__unpin(ptr);
|
|
105
|
+
}
|
|
106
|
+
},
|
|
107
|
+
hashString(str, seed = 0) {
|
|
108
|
+
const ptr = writeString(str);
|
|
109
|
+
try {
|
|
110
|
+
return wasm.hashString(ptr, seed);
|
|
111
|
+
} finally {
|
|
112
|
+
wasm.__unpin(ptr);
|
|
113
|
+
}
|
|
114
|
+
},
|
|
115
|
+
hashStringToHex(str, seed = 0) {
|
|
116
|
+
const ptr = writeString(str);
|
|
117
|
+
try {
|
|
118
|
+
const resultPtr = wasm.hashStringToHex(ptr, seed);
|
|
119
|
+
return readString(resultPtr);
|
|
120
|
+
} finally {
|
|
121
|
+
wasm.__unpin(ptr);
|
|
122
|
+
}
|
|
123
|
+
},
|
|
124
|
+
verifyHash(data, expectedHash, seed = 0) {
|
|
125
|
+
const ptr = writeBytes(data);
|
|
126
|
+
try {
|
|
127
|
+
return wasm.verifyHash(ptr, expectedHash, seed);
|
|
128
|
+
} finally {
|
|
129
|
+
wasm.__unpin(ptr);
|
|
130
|
+
}
|
|
131
|
+
},
|
|
132
|
+
verifyStringHash(str, expectedHash, seed = 0) {
|
|
133
|
+
const ptr = writeString(str);
|
|
134
|
+
try {
|
|
135
|
+
return wasm.verifyStringHash(ptr, expectedHash, seed);
|
|
136
|
+
} finally {
|
|
137
|
+
wasm.__unpin(ptr);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
function createFallbackHashModule() {
|
|
143
|
+
const textEncoder = new TextEncoder;
|
|
144
|
+
function xxHash32Impl(data, seed = 0) {
|
|
145
|
+
const PRIME32_1 = 2654435761;
|
|
146
|
+
const PRIME32_2 = 2246822519;
|
|
147
|
+
const PRIME32_3 = 3266489917;
|
|
148
|
+
const PRIME32_4 = 668265263;
|
|
149
|
+
const PRIME32_5 = 374761393;
|
|
150
|
+
const rotl32 = (x, r) => (x << r | x >>> 32 - r) >>> 0;
|
|
151
|
+
const readU32 = (arr, offset) => (arr[offset] | arr[offset + 1] << 8 | arr[offset + 2] << 16 | arr[offset + 3] << 24) >>> 0;
|
|
152
|
+
const len = data.length;
|
|
153
|
+
let h32;
|
|
154
|
+
let index = 0;
|
|
155
|
+
if (len >= 16) {
|
|
156
|
+
const limit = len - 16;
|
|
157
|
+
let v1 = seed + PRIME32_1 + PRIME32_2 >>> 0;
|
|
158
|
+
let v2 = seed + PRIME32_2 >>> 0;
|
|
159
|
+
let v3 = seed >>> 0;
|
|
160
|
+
let v4 = seed - PRIME32_1 >>> 0;
|
|
161
|
+
while (index <= limit) {
|
|
162
|
+
v1 = Math.imul(rotl32(v1 + Math.imul(readU32(data, index), PRIME32_2) >>> 0, 13), PRIME32_1) >>> 0;
|
|
163
|
+
index += 4;
|
|
164
|
+
v2 = Math.imul(rotl32(v2 + Math.imul(readU32(data, index), PRIME32_2) >>> 0, 13), PRIME32_1) >>> 0;
|
|
165
|
+
index += 4;
|
|
166
|
+
v3 = Math.imul(rotl32(v3 + Math.imul(readU32(data, index), PRIME32_2) >>> 0, 13), PRIME32_1) >>> 0;
|
|
167
|
+
index += 4;
|
|
168
|
+
v4 = Math.imul(rotl32(v4 + Math.imul(readU32(data, index), PRIME32_2) >>> 0, 13), PRIME32_1) >>> 0;
|
|
169
|
+
index += 4;
|
|
170
|
+
}
|
|
171
|
+
h32 = rotl32(v1, 1) + rotl32(v2, 7) + rotl32(v3, 12) + rotl32(v4, 18) >>> 0;
|
|
172
|
+
} else {
|
|
173
|
+
h32 = seed + PRIME32_5 >>> 0;
|
|
174
|
+
}
|
|
175
|
+
h32 = h32 + len >>> 0;
|
|
176
|
+
while (index <= len - 4) {
|
|
177
|
+
h32 = Math.imul(rotl32(h32 + Math.imul(readU32(data, index), PRIME32_3) >>> 0, 17), PRIME32_4) >>> 0;
|
|
178
|
+
index += 4;
|
|
179
|
+
}
|
|
180
|
+
while (index < len) {
|
|
181
|
+
h32 = Math.imul(rotl32(h32 + Math.imul(data[index], PRIME32_5) >>> 0, 11), PRIME32_1) >>> 0;
|
|
182
|
+
index++;
|
|
183
|
+
}
|
|
184
|
+
h32 ^= h32 >>> 15;
|
|
185
|
+
h32 = Math.imul(h32, PRIME32_2) >>> 0;
|
|
186
|
+
h32 ^= h32 >>> 13;
|
|
187
|
+
h32 = Math.imul(h32, PRIME32_3) >>> 0;
|
|
188
|
+
h32 ^= h32 >>> 16;
|
|
189
|
+
return h32 >>> 0;
|
|
190
|
+
}
|
|
191
|
+
function toHex(value) {
|
|
192
|
+
return (value >>> 0).toString(16).padStart(8, "0");
|
|
193
|
+
}
|
|
194
|
+
return {
|
|
195
|
+
xxHash32: xxHash32Impl,
|
|
196
|
+
hashString(str, seed = 0) {
|
|
197
|
+
return xxHash32Impl(textEncoder.encode(str), seed);
|
|
198
|
+
},
|
|
199
|
+
hashStringToHex(str, seed = 0) {
|
|
200
|
+
return toHex(xxHash32Impl(textEncoder.encode(str), seed));
|
|
201
|
+
},
|
|
202
|
+
verifyHash(data, expectedHash, seed = 0) {
|
|
203
|
+
return xxHash32Impl(data, seed) === expectedHash;
|
|
204
|
+
},
|
|
205
|
+
verifyStringHash(str, expectedHash, seed = 0) {
|
|
206
|
+
return xxHash32Impl(textEncoder.encode(str), seed) === expectedHash;
|
|
207
|
+
}
|
|
208
|
+
};
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
// src/hash.ts
|
|
212
|
+
var hashModule = null;
|
|
213
|
+
var initPromise = null;
|
|
214
|
+
var useWasm = true;
|
|
215
|
+
async function initHashModule(config = {}) {
|
|
216
|
+
const { preferWasm = true, onWasmLoaded, onFallback } = config;
|
|
217
|
+
if (hashModule) {
|
|
218
|
+
return hashModule;
|
|
219
|
+
}
|
|
220
|
+
if (initPromise) {
|
|
221
|
+
return initPromise;
|
|
222
|
+
}
|
|
223
|
+
initPromise = (async () => {
|
|
224
|
+
if (preferWasm) {
|
|
225
|
+
try {
|
|
226
|
+
hashModule = await loadHashModule();
|
|
227
|
+
useWasm = true;
|
|
228
|
+
onWasmLoaded?.();
|
|
229
|
+
return hashModule;
|
|
230
|
+
} catch (error) {
|
|
231
|
+
const reason = error instanceof Error ? error.message : "Unknown error";
|
|
232
|
+
onFallback?.(reason);
|
|
233
|
+
}
|
|
234
|
+
} else {
|
|
235
|
+
onFallback?.("WASM disabled by configuration");
|
|
236
|
+
}
|
|
237
|
+
hashModule = createFallbackHashModule();
|
|
238
|
+
useWasm = false;
|
|
239
|
+
return hashModule;
|
|
240
|
+
})();
|
|
241
|
+
return initPromise;
|
|
242
|
+
}
|
|
243
|
+
function getHash() {
|
|
244
|
+
if (hashModule) {
|
|
245
|
+
return hashModule;
|
|
246
|
+
}
|
|
247
|
+
hashModule = createFallbackHashModule();
|
|
248
|
+
useWasm = false;
|
|
249
|
+
return hashModule;
|
|
250
|
+
}
|
|
251
|
+
function isUsingWasm() {
|
|
252
|
+
return useWasm && isHashModuleLoaded();
|
|
253
|
+
}
|
|
254
|
+
function hash(data, seed = 0) {
|
|
255
|
+
const module = getHash();
|
|
256
|
+
if (typeof data === "string") {
|
|
257
|
+
return module.hashString(data, seed);
|
|
258
|
+
}
|
|
259
|
+
return module.xxHash32(data, seed);
|
|
260
|
+
}
|
|
261
|
+
function hashToHex(data, seed = 0) {
|
|
262
|
+
const module = getHash();
|
|
263
|
+
if (typeof data === "string") {
|
|
264
|
+
return module.hashStringToHex(data, seed);
|
|
265
|
+
}
|
|
266
|
+
return module.xxHash32(data, seed).toString(16).padStart(8, "0");
|
|
267
|
+
}
|
|
268
|
+
function verify(data, expectedHash, seed = 0) {
|
|
269
|
+
const module = getHash();
|
|
270
|
+
const expected = typeof expectedHash === "string" ? parseInt(expectedHash, 16) : expectedHash;
|
|
271
|
+
if (typeof data === "string") {
|
|
272
|
+
return module.verifyStringHash(data, expected, seed);
|
|
273
|
+
}
|
|
274
|
+
return module.verifyHash(data, expected, seed);
|
|
275
|
+
}
|
|
276
|
+
function createSignature(data, secret) {
|
|
277
|
+
const module = getHash();
|
|
278
|
+
const secretHash = module.hashString(secret, 0);
|
|
279
|
+
const dataHash = module.hashString(data, secretHash);
|
|
280
|
+
return dataHash.toString(16).padStart(8, "0");
|
|
281
|
+
}
|
|
282
|
+
function verifySignature(data, signature, secret) {
|
|
283
|
+
return createSignature(data, secret) === signature;
|
|
284
|
+
}
|
|
285
|
+
export {
|
|
286
|
+
verifySignature,
|
|
287
|
+
verify,
|
|
288
|
+
loadHashModule,
|
|
289
|
+
isUsingWasm,
|
|
290
|
+
isHashModuleLoaded,
|
|
291
|
+
initHashModule,
|
|
292
|
+
hashToHex,
|
|
293
|
+
hash,
|
|
294
|
+
getHash,
|
|
295
|
+
createSignature,
|
|
296
|
+
createFallbackHashModule
|
|
297
|
+
};
|
|
298
|
+
export { __toESM, __require, getHash, hashToHex };
|
|
299
|
+
|
|
300
|
+
//# debugId=18EFA41CA1DEC13A64756E2164756E21
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{a as y,b as U,d as v}from"./hash-q46pgar4.js";function T(Q){return typeof Q==="object"&&Q!==null&&"code"in Q&&Q.code==="LIMIT_EXCEEDED"}var q={endpoint:"wss://api.botsigged.com/socket/websocket",debug:!1,sendInterval:2000,maxBufferSize:1000,mouseSampleRate:0.5,autoStart:!0,actionThreshold:70,action:"none",minAlertLevel:"high",botScoreThresholds:{medium:40,high:70,critical:90},hashVerification:{enabled:!1,preferWasm:!0},challenge:{enabled:!1,minLevel:"high",chunkSize:1e4,difficulty:{medium:12,high:16,critical:20},ui:{enabled:!0,message:"Verifying you're human...",successMessage:"Verified!",backgroundColor:"rgba(0, 0, 0, 0.7)",textColor:"#ffffff",spinnerColor:"#3b82f6",zIndex:999999}},formProtection:{mode:"auto",minTimeBeforeSubmit:500,maxHoldTime:3000,showLoadingUI:!0,loadingMessage:"Please wait..."},fallbackMode:"degraded"},F={action:"challenge",challenge:{difficulty:{suspicious:14,bot:18},timeout_ms:30000},form_protection_mode:"holdUntilReady"};function h(Q){let X=Q.action??q.action,Y=X==="challenge"||Q.challenge?.enabled;return{apiKey:Q.apiKey,accountId:Q.accountId,endpoint:Q.endpoint??q.endpoint,debug:Q.debug??q.debug,sendInterval:Q.sendInterval??q.sendInterval,maxBufferSize:Q.maxBufferSize??q.maxBufferSize,mouseSampleRate:Q.mouseSampleRate??q.mouseSampleRate,autoStart:Q.autoStart??q.autoStart,actionThreshold:Q.actionThreshold??q.actionThreshold,action:X,minAlertLevel:Q.minAlertLevel??q.minAlertLevel,botScoreThresholds:{...q.botScoreThresholds,...Q.botScoreThresholds},hashVerification:{...q.hashVerification,...Q.hashVerification},challenge:{enabled:Y,minLevel:Q.challenge?.minLevel??q.challenge.minLevel,chunkSize:Q.challenge?.chunkSize??q.challenge.chunkSize,difficulty:{...q.challenge.difficulty,...Q.challenge?.difficulty},ui:{...q.challenge.ui,...Q.challenge?.ui},onChallengeStart:Q.challenge?.onChallengeStart,onChallengeComplete:Q.challenge?.onChallengeComplete,onChallengeProgress:Q.challenge?.onChallengeProgress},formProtection:{mode:Q.formProtection?.mode??q.formProtection.mode,minTimeBeforeSubmit:Q.formProtection?.minTimeBeforeSubmit??q.formProtection.minTimeBeforeSubmit,maxHoldTime:Q.formProtection?.maxHoldTime??q.formProtection.maxHoldTime,showLoadingUI:Q.formProtection?.showLoadingUI??q.formProtection.showLoadingUI,loadingMessage:Q.formProtection?.loadingMessage??q.formProtection.loadingMessage,onHold:Q.formProtection?.onHold,onRelease:Q.formProtection?.onRelease,onBlock:Q.formProtection?.onBlock},fallbackMode:Q.fallbackMode??q.fallbackMode,cookie:Q.cookie,headers:Q.headers,formInject:Q.formInject,onScoreUpdate:Q.onScoreUpdate,onConnectionChange:Q.onConnectionChange,onError:Q.onError,onUsageLimitExceeded:Q.onUsageLimitExceeded,onHighBotScore:Q.onHighBotScore,onServerConfig:Q.onServerConfig,onServerAction:Q.onServerAction}}class k{events=[];startTime=0;sampleRate;maxBufferSize;isListening=!1;boundHandleMouseMove;boundHandleMouseDown;boundHandleMouseUp;boundHandleClick;constructor(Q={}){this.sampleRate=Q.sampleRate??0.5,this.maxBufferSize=Q.maxBufferSize??500,this.boundHandleMouseMove=this.handleMouseMove.bind(this),this.boundHandleMouseDown=this.handleMouseDown.bind(this),this.boundHandleMouseUp=this.handleMouseUp.bind(this),this.boundHandleClick=this.handleClick.bind(this)}start(){if(this.isListening)return;this.startTime=Date.now(),document.addEventListener("mousemove",this.boundHandleMouseMove,{passive:!0}),document.addEventListener("mousedown",this.boundHandleMouseDown,{passive:!0}),document.addEventListener("mouseup",this.boundHandleMouseUp,{passive:!0}),document.addEventListener("click",this.boundHandleClick,{passive:!0}),this.isListening=!0}stop(){if(!this.isListening)return;document.removeEventListener("mousemove",this.boundHandleMouseMove),document.removeEventListener("mousedown",this.boundHandleMouseDown),document.removeEventListener("mouseup",this.boundHandleMouseUp),document.removeEventListener("click",this.boundHandleClick),this.isListening=!1}addEvent(Q){if(this.events.push(Q),this.events.length>this.maxBufferSize)this.events.shift()}handleMouseMove(Q){if(Math.random()>this.sampleRate)return;this.addEvent({type:"move",x:Q.clientX,y:Q.clientY,t:Date.now()})}handleMouseDown(Q){this.addEvent({type:"down",x:Q.clientX,y:Q.clientY,t:Date.now(),button:Q.button})}handleMouseUp(Q){this.addEvent({type:"up",x:Q.clientX,y:Q.clientY,t:Date.now(),button:Q.button})}handleClick(Q){let X=Q.target,Y,Z;if(X&&X.getBoundingClientRect){let $=X.getBoundingClientRect();Y={top:$.top,left:$.left,width:$.width,height:$.height},Z=X.tagName?.toLowerCase()}this.addEvent({type:"click",x:Q.clientX,y:Q.clientY,t:Date.now(),button:Q.button,targetRect:Y,targetTag:Z})}getSignal(){return{events:[...this.events],start_time:this.startTime}}flush(){this.events=[]}getBufferSize(){return this.events.length}reset(){this.events=[],this.startTime=Date.now()}}class x{events=[];startTime=0;maxBufferSize;isListening=!1;boundHandleScroll;constructor(Q={}){this.maxBufferSize=Q.maxBufferSize??200,this.boundHandleScroll=this.handleScroll.bind(this)}start(){if(this.isListening)return;this.startTime=Date.now(),window.addEventListener("scroll",this.boundHandleScroll,{passive:!0}),this.isListening=!0}stop(){if(!this.isListening)return;window.removeEventListener("scroll",this.boundHandleScroll),this.isListening=!1}handleScroll(){if(this.events.push({y:window.scrollY,t:Date.now()}),this.events.length>this.maxBufferSize)this.events.shift()}getSignal(){return{events:[...this.events],start_time:this.startTime}}flush(){this.events=[]}getBufferSize(){return this.events.length}reset(){this.events=[],this.startTime=Date.now()}}class w{static instance=null;timings={signalRoundtrips:[]};pendingSignals=new Map;constructor(){this.timings.scriptStart=performance.now()}static getInstance(){if(!w.instance)w.instance=new w;return w.instance}static reset(){w.instance=null}markScriptStart(){this.timings.scriptStart=performance.now()}markConstructorStart(){this.timings.constructorStart=performance.now()}markConstructorEnd(){this.timings.constructorEnd=performance.now()}markStartCalled(){this.timings.startCalled=performance.now()}markSdkReady(){this.timings.sdkReady=performance.now()}markFingerprintStart(){this.timings.fingerprintStart=performance.now()}markFingerprintEnd(){this.timings.fingerprintEnd=performance.now()}markWsConnectStart(){this.timings.wsConnectStart=performance.now()}markWsConnectEnd(){this.timings.wsConnectEnd=performance.now()}markChannelJoinStart(){this.timings.channelJoinStart=performance.now()}markChannelJoinEnd(){this.timings.channelJoinEnd=performance.now()}markInitialScoreReceived(){this.timings.initialScoreReceived=performance.now()}markFormCollectorStart(){this.timings.formCollectorStart=performance.now()}markFormCollectorReady(){this.timings.formCollectorReady=performance.now()}markFirstFormInteraction(){if(!this.timings.firstFormInteraction){if(this.timings.firstFormInteraction=performance.now(),this.timings.sdkReady)this.timings.timeToFirstInteraction=this.timings.firstFormInteraction-this.timings.sdkReady}}markFirstSubmitAttempt(Q){if(!this.timings.firstSubmitAttempt)this.timings.firstSubmitAttempt=performance.now(),this.timings.hadScoreBeforeSubmit=Q}markSignalSent(Q){this.pendingSignals.set(Q,performance.now())}markSignalResponseReceived(Q){let X=this.pendingSignals.get(Q);if(X!==void 0){let Y=performance.now(),Z={sentAt:X,receivedAt:Y,roundtripMs:Y-X,seq:Q};this.timings.signalRoundtrips?.push(Z),this.pendingSignals.delete(Q)}}getTimings(){return{...this.timings}}getSummary(){let Q=this.timings,X=Q.signalRoundtrips||[],Y=0,Z=1/0,$=0;if(X.length>0)Y=X.reduce((G,g)=>G+g.roundtripMs,0)/X.length,Z=Math.min(...X.map((G)=>G.roundtripMs)),$=Math.max(...X.map((G)=>G.roundtripMs));let J=(Q.sdkReady??0)-(Q.scriptStart??0),z=(Q.fingerprintEnd??0)-(Q.fingerprintStart??0),W=(Q.wsConnectEnd??0)-(Q.wsConnectStart??0),B=(Q.channelJoinEnd??0)-(Q.channelJoinStart??0),V=(Q.initialScoreReceived??0)-(Q.startCalled??0),R=(Q.initialScoreReceived??0)-(Q.scriptStart??0);return{totalStartupMs:Math.round(J),fingerprintMs:Math.round(z),wsConnectionMs:Math.round(W),channelJoinMs:Math.round(B),timeToFirstScoreMs:Math.round(V),avgSignalRoundtripMs:Math.round(Y),minSignalRoundtripMs:Z===1/0?0:Math.round(Z),maxSignalRoundtripMs:Math.round($),vulnerabilityWindowMs:Math.round(R),protectedBeforeSubmit:Q.hadScoreBeforeSubmit??!1}}logSummary(){let Q=this.getSummary(),X=this.timings;if(X.firstFormInteraction);if(X.firstSubmitAttempt);if(Q.vulnerabilityWindowMs>0);}getReport(){return{timings:this.timings,summary:this.getSummary(),userAgent:navigator.userAgent,timestamp:Date.now()}}}var K=w.getInstance();function N(){return w.getInstance()}function l(){return K.getSummary()}function f(){K.logSummary()}var j="__bs_ghost_value";class C{keyEvents=[];focusEvents=[];pasteEvents=[];inputEvents=[];submitCount=0;startTime=0;maxKeyEvents;maxFocusEvents;maxInputEvents;isListening=!1;valueSetterHooked=!1;onSubmit;originalInputDescriptor;originalTextareaDescriptor;lastKeyWasTab=!1;currentField=null;emailDomains=new Set;boundHandleFocusIn;boundHandleFocusOut;boundHandleKeyDown;boundHandleKeyUp;boundHandlePaste;boundHandleSubmit;boundHandleClick;boundHandleInput;boundHandleGhostValue;constructor(Q={}){this.maxKeyEvents=Q.maxKeyEvents??500,this.maxFocusEvents=Q.maxFocusEvents??100,this.maxInputEvents=Q.maxInputEvents??200,this.onSubmit=Q.onSubmit,this.boundHandleFocusIn=this.handleFocusIn.bind(this),this.boundHandleFocusOut=this.handleFocusOut.bind(this),this.boundHandleKeyDown=this.handleKeyDown.bind(this),this.boundHandleKeyUp=this.handleKeyUp.bind(this),this.boundHandlePaste=this.handlePaste.bind(this),this.boundHandleSubmit=this.handleSubmit.bind(this),this.boundHandleClick=this.handleClick.bind(this),this.boundHandleInput=this.handleInput.bind(this),this.boundHandleGhostValue=this.handleGhostValue.bind(this)}start(){if(this.isListening)return;this.startTime=Date.now(),document.addEventListener("focusin",this.boundHandleFocusIn,{passive:!0,capture:!0}),document.addEventListener("focusout",this.boundHandleFocusOut,{passive:!0,capture:!0}),document.addEventListener("keydown",this.boundHandleKeyDown,{passive:!0}),document.addEventListener("keyup",this.boundHandleKeyUp,{passive:!0}),document.addEventListener("paste",this.boundHandlePaste,{passive:!0}),document.addEventListener("submit",this.boundHandleSubmit,{passive:!0}),document.addEventListener("click",this.boundHandleClick,{passive:!0}),document.addEventListener("input",this.boundHandleInput,{passive:!0}),document.addEventListener(j,this.boundHandleGhostValue,{passive:!0}),this.hookValueSetters(),this.isListening=!0}stop(){if(!this.isListening)return;document.removeEventListener("focusin",this.boundHandleFocusIn,{capture:!0}),document.removeEventListener("focusout",this.boundHandleFocusOut,{capture:!0}),document.removeEventListener("keydown",this.boundHandleKeyDown),document.removeEventListener("keyup",this.boundHandleKeyUp),document.removeEventListener("paste",this.boundHandlePaste),document.removeEventListener("submit",this.boundHandleSubmit),document.removeEventListener("click",this.boundHandleClick),document.removeEventListener("input",this.boundHandleInput),document.removeEventListener(j,this.boundHandleGhostValue),this.unhookValueSetters(),this.isListening=!1}isFormInput(Q){if(!Q||!(Q instanceof HTMLElement))return!1;let X=Q.tagName.toLowerCase();if(X==="textarea"||X==="select")return!0;if(X==="input"){let Y=Q.type.toLowerCase();return!["submit","button","reset","hidden","image"].includes(Y)}return!1}isEmailField(Q){let X=Q.type?.toLowerCase()||"",Y=(Q.name||"").toLowerCase(),Z=(Q.id||"").toLowerCase();return X==="email"||Y.includes("email")||Y.includes("e-mail")||Z.includes("email")||Z.includes("e-mail")}extractEmailDomain(Q){if(!Q||typeof Q!=="string")return null;let X=Q.trim();if(!X)return null;let Y=X.match(/@([a-zA-Z0-9.-]+\.[a-zA-Z]{2,})$/);return Y?Y[1].toLowerCase():null}getFieldId(Q){return Q.id||Q.getAttribute("name")||`field-${Q.tagName.toLowerCase()}`}handleFocusIn(Q){if(!this.isFormInput(Q.target))return;N().markFirstFormInteraction();let X=this.getFieldId(Q.target),Y="direct";if(this.lastKeyWasTab)Y="tab";if(this.focusEvents.push({type:"focus",field:X,t:Date.now(),method:Y}),this.focusEvents.length>this.maxFocusEvents)this.focusEvents.shift();this.currentField=X,this.lastKeyWasTab=!1}handleFocusOut(Q){if(!this.isFormInput(Q.target))return;let X=Q.target,Y=this.getFieldId(X);if(this.focusEvents.push({type:"blur",field:Y,t:Date.now()}),this.focusEvents.length>this.maxFocusEvents)this.focusEvents.shift();if(X instanceof HTMLInputElement&&this.isEmailField(X)){let Z=this.extractEmailDomain(X.value);if(Z)this.emailDomains.add(Z)}this.currentField=null}handleClick(Q){if(!this.isFormInput(Q.target))return;let X=this.focusEvents[this.focusEvents.length-1];if(X&&X.type==="focus"&&Date.now()-X.t<50)X.method="click"}handleKeyDown(Q){if(Q.key==="Tab"){this.lastKeyWasTab=!0;return}if(!this.isFormInput(Q.target))return;let X="key";if(Q.key==="Backspace")X="backspace";else if(Q.key==="Delete")X="delete";else if(Q.key==="Enter")X="enter";else if(Q.key==="Tab")X="tab";else if(Q.key.length===1)X="char";else if(Q.key.startsWith("Arrow"))X="arrow";if(this.keyEvents.push({type:"down",code:X,t:Date.now(),field:this.currentField||void 0}),this.keyEvents.length>this.maxKeyEvents)this.keyEvents.shift()}handleKeyUp(Q){if(!this.isFormInput(Q.target))return;let X="key";if(Q.key==="Backspace")X="backspace";else if(Q.key==="Delete")X="delete";else if(Q.key.length===1)X="char";if(this.keyEvents.push({type:"up",code:X,t:Date.now(),field:this.currentField||void 0}),this.keyEvents.length>this.maxKeyEvents)this.keyEvents.shift()}handleInput(Q){if(!this.isFormInput(Q.target))return;let X=Q.target,Z=Q.inputType||"unknown",$=X.value?.length??0;if(this.inputEvents.push({field:this.getFieldId(X),t:Date.now(),inputType:Z,valueLength:$}),this.inputEvents.length>this.maxInputEvents)this.inputEvents.shift()}handlePaste(Q){if(!this.isFormInput(Q.target))return;let X=Q.clipboardData?.getData("text")||"";this.pasteEvents.push({field:this.getFieldId(Q.target),t:Date.now(),length:X.length})}handleSubmit(Q){this.submitCount++;let X=Q.target;if(X&&X.elements)for(let Y=0;Y<X.elements.length;Y++){let Z=X.elements[Y];if(Z instanceof HTMLInputElement&&this.isEmailField(Z)){let $=this.extractEmailDomain(Z.value);if($)this.emailDomains.add($)}}this.onSubmit?.()}getSignal(){return{keys:[...this.keyEvents],focus:[...this.focusEvents],pastes:[...this.pasteEvents],inputs:[...this.inputEvents],submits:this.submitCount,start_time:this.startTime,email_domains:this.emailDomains.size>0?Array.from(this.emailDomains):void 0}}flush(){this.keyEvents=[],this.focusEvents=[],this.pasteEvents=[],this.inputEvents=[]}getBufferSize(){return this.keyEvents.length+this.focusEvents.length+this.pasteEvents.length+this.inputEvents.length}reset(){this.keyEvents=[],this.focusEvents=[],this.pasteEvents=[],this.inputEvents=[],this.submitCount=0,this.startTime=Date.now(),this.lastKeyWasTab=!1,this.currentField=null,this.emailDomains.clear()}hookValueSetters(){if(this.valueSetterHooked)return;if(this.originalInputDescriptor=Object.getOwnPropertyDescriptor(HTMLInputElement.prototype,"value"),this.originalInputDescriptor){let Q=this.originalInputDescriptor.set,X=this.originalInputDescriptor.get;Object.defineProperty(HTMLInputElement.prototype,"value",{configurable:!0,enumerable:!0,get(){return X?.call(this)},set(Y){let Z=X?.call(this)??"";Q?.call(this,Y);let $=Y??"";if($!==Z)this.dispatchEvent(new CustomEvent(j,{bubbles:!0,detail:{valueLength:$.length,wasEmpty:Z.length===0}}))}})}if(this.originalTextareaDescriptor=Object.getOwnPropertyDescriptor(HTMLTextAreaElement.prototype,"value"),this.originalTextareaDescriptor){let Q=this.originalTextareaDescriptor.set,X=this.originalTextareaDescriptor.get;Object.defineProperty(HTMLTextAreaElement.prototype,"value",{configurable:!0,enumerable:!0,get(){return X?.call(this)},set(Y){let Z=X?.call(this)??"";Q?.call(this,Y);let $=Y??"";if($!==Z)this.dispatchEvent(new CustomEvent(j,{bubbles:!0,detail:{valueLength:$.length,wasEmpty:Z.length===0}}))}})}this.valueSetterHooked=!0}unhookValueSetters(){if(!this.valueSetterHooked)return;if(this.originalInputDescriptor)Object.defineProperty(HTMLInputElement.prototype,"value",this.originalInputDescriptor);if(this.originalTextareaDescriptor)Object.defineProperty(HTMLTextAreaElement.prototype,"value",this.originalTextareaDescriptor);this.valueSetterHooked=!1}handleGhostValue(Q){let X=Q.target;if(!this.isFormInput(X))return;let Z=Q.detail?.valueLength??0;if(this.inputEvents.push({field:this.getFieldId(X),t:Date.now(),inputType:"programmatic",valueLength:Z}),this.inputEvents.length>this.maxInputEvents)this.inputEvents.shift()}}class L{cachedSignal=null;collect(){if(this.cachedSignal)return this.cachedSignal;let Q=navigator,X=window;return this.cachedSignal={user_agent:navigator.userAgent,platform:navigator.platform,language:navigator.language,languages:[...navigator.languages||[]],hardware_concurrency:navigator.hardwareConcurrency??null,device_memory:Q.deviceMemory??null,max_touch_points:navigator.maxTouchPoints??0,screen_width:screen.width,screen_height:screen.height,screen_avail_width:screen.availWidth,screen_avail_height:screen.availHeight,color_depth:screen.colorDepth,pixel_ratio:window.devicePixelRatio??1,...this.getWebGLInfo(),plugins_count:navigator.plugins?.length??0,mime_types_count:navigator.mimeTypes?.length??0,timezone:this.getTimezone(),timezone_offset:new Date().getTimezoneOffset(),has_webdriver:Q.webdriver===!0,has_chrome_runtime:!!X.chrome?.runtime,has_chrome_app:!!X.chrome?.app,has_notification_api:"Notification"in window,has_permissions_api:"permissions"in navigator,outer_dimensions:{width:window.outerWidth,height:window.outerHeight},inner_dimensions:{width:window.innerWidth,height:window.innerHeight},notification_permission:this.getNotificationPermission()},this.cachedSignal}getWebGLInfo(){try{let Q=document.createElement("canvas"),X=Q.getContext("webgl")||Q.getContext("experimental-webgl");if(!X||!(X instanceof WebGLRenderingContext))return{webgl_vendor:null,webgl_renderer:null};let Y=X.getExtension("WEBGL_debug_renderer_info");if(!Y)return{webgl_vendor:null,webgl_renderer:null};return{webgl_vendor:X.getParameter(Y.UNMASKED_VENDOR_WEBGL),webgl_renderer:X.getParameter(Y.UNMASKED_RENDERER_WEBGL)}}catch{return{webgl_vendor:null,webgl_renderer:null}}}getTimezone(){try{return Intl.DateTimeFormat().resolvedOptions().timeZone}catch{return null}}getNotificationPermission(){if("Notification"in window)return Notification.permission;return null}getSignal(){return this.collect()}reset(){this.cachedSignal=null}}class b{cachedFingerprint=null;async generate(){if(this.cachedFingerprint)return this.cachedFingerprint;let[Q,X,Y,Z,$]=await Promise.all([this.getCanvasHash(),this.getWebGLData(),this.getAudioHash(),this.getFontData(),this.getScreenHash()]),J={hash:"",canvas_hash:Q,webgl_hash:X.hash,audio_hash:Y,font_hash:Z.hash,screen_hash:$,webgl_vendor:X.vendor,webgl_renderer:X.renderer,timezone:this.getTimezone(),language:this.getLanguage(),platform:this.getPlatform(),font_count:Z.count};return J.hash=await this.generateMainHash(J),this.cachedFingerprint=J,J}getFingerprint(){return this.cachedFingerprint}reset(){this.cachedFingerprint=null}async getCanvasHash(){try{let Q=document.createElement("canvas");Q.width=200,Q.height=50;let X=Q.getContext("2d");if(!X)return null;X.textBaseline="top",X.font="14px 'Arial'",X.fillStyle="#f60",X.fillRect(125,1,62,20),X.fillStyle="#069",X.fillText("BotSigged,\uD83C\uDFA8",2,15),X.fillStyle="rgba(102, 204, 0, 0.7)",X.fillText("BotSigged,\uD83C\uDFA8",4,17);let Y=Q.toDataURL();return this.hashString(Y)}catch{return null}}async getWebGLData(){try{let Q=document.createElement("canvas"),X=Q.getContext("webgl")||Q.getContext("experimental-webgl");if(!X||!(X instanceof WebGLRenderingContext))return{hash:null,vendor:null,renderer:null};let Y=[],Z=[X.ALIASED_LINE_WIDTH_RANGE,X.ALIASED_POINT_SIZE_RANGE,X.ALPHA_BITS,X.BLUE_BITS,X.DEPTH_BITS,X.GREEN_BITS,X.MAX_COMBINED_TEXTURE_IMAGE_UNITS,X.MAX_CUBE_MAP_TEXTURE_SIZE,X.MAX_FRAGMENT_UNIFORM_VECTORS,X.MAX_RENDERBUFFER_SIZE,X.MAX_TEXTURE_IMAGE_UNITS,X.MAX_TEXTURE_SIZE,X.MAX_VARYING_VECTORS,X.MAX_VERTEX_ATTRIBS,X.MAX_VERTEX_TEXTURE_IMAGE_UNITS,X.MAX_VERTEX_UNIFORM_VECTORS,X.MAX_VIEWPORT_DIMS,X.RED_BITS,X.RENDERER,X.SHADING_LANGUAGE_VERSION,X.STENCIL_BITS,X.VENDOR,X.VERSION];for(let V of Z)try{let R=X.getParameter(V);Y.push(String(R))}catch{Y.push("")}let $=X.getSupportedExtensions();if($)Y.push($.sort().join(","));let J=null,z=null,W=X.getExtension("WEBGL_debug_renderer_info");if(W)J=X.getParameter(W.UNMASKED_VENDOR_WEBGL),z=X.getParameter(W.UNMASKED_RENDERER_WEBGL);return{hash:this.hashString(Y.join("|")),vendor:J,renderer:z}}catch{return{hash:null,vendor:null,renderer:null}}}async getAudioHash(){try{let Q=window.OfflineAudioContext||window.webkitOfflineAudioContext;if(!Q)return null;let X=new Q(1,4500,44100),Y=X.createOscillator(),Z=X.createDynamicsCompressor();Y.type="triangle",Y.frequency.setValueAtTime(1e4,X.currentTime),Z.threshold.setValueAtTime(-50,X.currentTime),Z.knee.setValueAtTime(40,X.currentTime),Z.ratio.setValueAtTime(12,X.currentTime),Z.attack.setValueAtTime(0,X.currentTime),Z.release.setValueAtTime(0.25,X.currentTime),Y.connect(Z),Z.connect(X.destination),Y.start(0);let J=(await X.startRendering()).getChannelData(0),z=[];for(let W=0;W<J.length;W+=100)z.push(J[W]);return this.hashString(z.join(","))}catch{return null}}async getFontData(){let Q=["Arial","Arial Black","Arial Narrow","Calibri","Cambria","Cambria Math","Comic Sans MS","Consolas","Courier","Courier New","Georgia","Helvetica","Impact","Lucida Console","Lucida Sans Unicode","Microsoft Sans Serif","MS Gothic","MS PGothic","MS Sans Serif","MS Serif","Palatino Linotype","Segoe Print","Segoe Script","Segoe UI","Symbol","Tahoma","Times","Times New Roman","Trebuchet MS","Verdana","Wingdings"],X=["monospace","sans-serif","serif"],Y="mmmmmmmmmmlli",Z="72px",$=document.createElement("span");$.style.position="absolute",$.style.left="-9999px",$.style.fontSize="72px",$.style.lineHeight="normal",$.innerHTML="mmmmmmmmmmlli",document.body.appendChild($);let J={};for(let B of X)$.style.fontFamily=B,J[B]=$.offsetWidth;let z=[];for(let B of Q){let V=!1;for(let R of X)if($.style.fontFamily=`'${B}', ${R}`,$.offsetWidth!==J[R]){V=!0;break}if(V)z.push(B)}return document.body.removeChild($),{hash:this.hashString(z.join(",")),count:z.length}}async getScreenHash(){let Q=[String(screen.width),String(screen.height),String(screen.availWidth),String(screen.availHeight),String(screen.colorDepth),String(screen.pixelDepth),String(window.devicePixelRatio||1)];return this.hashString(Q.join("|"))}getTimezone(){try{return Intl.DateTimeFormat().resolvedOptions().timeZone}catch{return null}}getLanguage(){return navigator.language||null}getPlatform(){return navigator.platform||null}generateMainHash(Q){let X=[Q.canvas_hash||"",Q.webgl_hash||"",Q.audio_hash||"",Q.font_hash||"",Q.screen_hash||"",Q.timezone||"",Q.language||"",Q.platform||""];return this.hashString(X.join("|"))}hashString(Q){return v(Q)}}class A{ws=null;endpoint;apiKey;heartbeatInterval;reconnectAttempts;reconnectDelay;debug;state="disconnected";channelState="closed";refCounter=0;joinRef=null;heartbeatTimer=null;reconnectTimer=null;reconnectCount=0;pendingReplies=new Map;onConnectionChange;onError;channelCallbacks={};topic=null;constructor(Q){this.endpoint=Q.endpoint,this.apiKey=Q.apiKey,this.heartbeatInterval=Q.heartbeatInterval??30000,this.reconnectAttempts=Q.reconnectAttempts??10,this.reconnectDelay=Q.reconnectDelay??((X)=>Math.min(1000*Math.pow(2,X),30000)),this.debug=Q.debug??!1,this.onConnectionChange=Q.onConnectionChange,this.onError=Q.onError}connect(){return new Promise((Q,X)=>{if(this.ws&&this.state==="connected"){Q();return}this.setState("connecting");let Y=this.buildUrl();this.log("Connecting to",Y);try{this.ws=new WebSocket(Y),this.ws.onopen=()=>{this.log("WebSocket connected"),this.setState("connected"),this.reconnectCount=0,this.startHeartbeat(),Q()},this.ws.onclose=(Z)=>{this.log("WebSocket closed",Z.code,Z.reason),this.handleClose()},this.ws.onerror=(Z)=>{this.log("WebSocket error",Z);let $=Error("WebSocket connection error");this.handleError($),X($)},this.ws.onmessage=(Z)=>{this.handleMessage(Z.data)}}catch(Z){let $=Z instanceof Error?Z:Error(String(Z));this.handleError($),X($)}})}disconnect(){if(this.stopHeartbeat(),this.stopReconnect(),this.ws)this.ws.close(1000,"Client disconnect"),this.ws=null;this.setState("disconnected"),this.setChannelState("closed")}joinChannel(Q,X,Y,Z,$={},J){return this.channelCallbacks=$,this.topic=`detection:${Q}`,new Promise((z,W)=>{if(this.state!=="connected"){W(Error("WebSocket not connected"));return}this.setChannelState("joining"),this.joinRef=this.makeRef();let B={session_id:Q,api_key:this.apiKey,fingerprint:X,session:Y,browser:Z};if(J)B.account_id=J;this.push("phx_join",B,this.joinRef).then((V)=>{this.log("Channel joined",V),this.setChannelState("joined"),this.channelCallbacks.onJoin?.(),z(V)}).catch((V)=>{this.log("Channel join failed",V),this.setChannelState("error"),this.channelCallbacks.onError?.(V),W(V)})})}leaveChannel(){return new Promise((Q,X)=>{if(this.channelState!=="joined"){Q();return}this.setChannelState("leaving"),this.push("phx_leave",{}).then(()=>{this.log("Channel left"),this.setChannelState("closed"),this.joinRef=null,this.topic=null,this.channelCallbacks.onLeave?.(),Q()}).catch((Y)=>{this.setChannelState("error"),X(Y)})})}sendSignal(Q){if(this.channelState!=="joined")return Promise.reject(Error("Channel not joined"));return this.push("signal",Q)}sendFormStatus(Q){if(this.channelState!=="joined")return Promise.reject(Error("Channel not joined"));return this.push("form_status",{status:Q})}sendEvent(Q,X){if(this.channelState!=="joined")return Promise.reject(Error("Channel not joined"));return this.push(Q,X)}getState(){return this.state}getChannelState(){return this.channelState}isReady(){return this.state==="connected"&&this.channelState==="joined"}buildUrl(){let Q=new URL(this.endpoint);return Q.searchParams.set("vsn","2.0.0"),Q.searchParams.set("api_key",this.apiKey),Q.toString()}makeRef(){return this.refCounter++,String(this.refCounter)}push(Q,X,Y){return new Promise((Z,$)=>{if(!this.ws||this.ws.readyState!==WebSocket.OPEN){$(Error("WebSocket not open"));return}if(!this.topic){$(Error("Channel topic not set"));return}let J=Y??this.makeRef(),z=[this.joinRef,J,this.topic,Q,X],W=setTimeout(()=>{this.pendingReplies.delete(J),$(Error(`Timeout waiting for reply to ${Q}`))},1e4);this.pendingReplies.set(J,{resolve:Z,reject:$,timeout:W}),this.log("Sending",Q,X),this.ws.send(JSON.stringify(z))})}handleMessage(Q){try{let[X,Y,Z,$,J]=JSON.parse(Q);if(this.log("Received",$,J),$==="phx_reply"&&Y){let z=this.pendingReplies.get(Y);if(z){clearTimeout(z.timeout),this.pendingReplies.delete(Y);let W=J;if(W.status==="ok")z.resolve(W.response??{});else if(W.response&&typeof W.response==="object"&&"code"in W.response)z.reject(W.response);else{let B=this.buildErrorMessage(W.status,W.response);z.reject(Error(B))}}return}if($==="phx_error"){let z=Error("Channel error");this.setChannelState("error"),this.channelCallbacks.onError?.(z);return}if($==="phx_close"){this.setChannelState("closed"),this.channelCallbacks.onLeave?.();return}if($==="score_update"){this.channelCallbacks.onScoreUpdate?.(J);return}if($==="action"){this.channelCallbacks.onAction?.(J);return}this.channelCallbacks.onMessage?.($,J)}catch(X){this.log("Error parsing message",X)}}handleClose(){this.stopHeartbeat(),this.setState("disconnected"),this.setChannelState("closed");for(let[Q,X]of this.pendingReplies)clearTimeout(X.timeout),X.reject(Error("Connection closed"));this.pendingReplies.clear(),this.scheduleReconnect()}handleError(Q){this.setState("error"),this.onError?.(Q)}startHeartbeat(){this.stopHeartbeat(),this.heartbeatTimer=setInterval(()=>{if(this.ws&&this.ws.readyState===WebSocket.OPEN){let Q=[null,this.makeRef(),"phoenix","heartbeat",{}];if(this.ws.send(JSON.stringify(Q)),this.channelState==="joined")this.push("heartbeat",{}).then((X)=>{if(X.bot_score!==void 0)this.channelCallbacks.onScoreUpdate?.({bot_score:X.bot_score,classification:X.classification,triggered_rules:[],event_count:0})}).catch(()=>{})}},this.heartbeatInterval)}stopHeartbeat(){if(this.heartbeatTimer)clearInterval(this.heartbeatTimer),this.heartbeatTimer=null}scheduleReconnect(){if(this.reconnectCount>=this.reconnectAttempts){this.log("Max reconnect attempts reached");return}let Q=this.reconnectDelay(this.reconnectCount);this.reconnectCount++,this.log(`Scheduling reconnect attempt ${this.reconnectCount} in ${Q}ms`),this.reconnectTimer=setTimeout(()=>{this.connect().catch((X)=>{this.log("Reconnect failed",X)})},Q)}stopReconnect(){if(this.reconnectTimer)clearTimeout(this.reconnectTimer),this.reconnectTimer=null;this.reconnectCount=0}setState(Q){if(this.state!==Q)this.state=Q,this.onConnectionChange?.(Q)}setChannelState(Q){this.channelState=Q}buildErrorMessage(Q,X){if(X){if(typeof X.reason==="string")return`Channel error: ${X.reason}`;if(Object.keys(X).length>0)return`Channel error (${Q??"error"}): ${JSON.stringify(X)}`}return Q??"Unknown error"}log(...Q){if(this.debug);}}class D{config;isReady=!1;hasScore=!1;hasFormScore=!1;currentScore=null;pendingSubmissions=[];pendingRequests=[];protectedForms=new Set;releasingForms=new Set;loadingOverlay=null;formObserver=null;startTime;originalFetch=null;originalXHROpen=null;originalXHRSend=null;constructor(Q={}){if(this.startTime=performance.now(),this.config={mode:Q.mode??"none",minTimeBeforeSubmit:Q.minTimeBeforeSubmit??500,maxHoldTime:Q.maxHoldTime??5000,showLoadingUI:Q.showLoadingUI??!0,loadingMessage:Q.loadingMessage??"Please wait...",onHold:Q.onHold,onRelease:Q.onRelease,onBlock:Q.onBlock,flushAndWaitForScore:Q.flushAndWaitForScore},this.config.mode!=="none")this.setup()}setup(){if(this.config.mode==="auto")this.interceptFetch(),this.interceptXHR();let Q=()=>{document.querySelectorAll("form").forEach((X)=>{this.protectForm(X)}),this.formObserver=new MutationObserver((X)=>{X.forEach((Y)=>{Y.addedNodes.forEach((Z)=>{if(Z instanceof HTMLFormElement)this.protectForm(Z);if(Z instanceof HTMLElement)Z.querySelectorAll("form").forEach(($)=>{this.protectForm($)})})})}),this.formObserver.observe(document.body,{childList:!0,subtree:!0})};if(document.body)Q();else document.addEventListener("DOMContentLoaded",Q,{once:!0})}isFormLikeRequest(Q,X){if((X?.method?.toUpperCase()||"GET")!=="POST")return!1;try{if((typeof Q==="string"?new URL(Q,window.location.origin):Q instanceof URL?Q:new URL(Q.url)).origin!==window.location.origin)return!1}catch{return!1}let Z=X?.headers instanceof Headers?X.headers.get("content-type"):typeof X?.headers==="object"&&X.headers!==null?X.headers["content-type"]||X.headers["Content-Type"]:null;if(Z){let $=Z.toLowerCase();if($.includes("application/x-www-form-urlencoded")||$.includes("multipart/form-data")||$.includes("application/json"))return!0;return!1}if(X?.body)return!0;return!1}interceptFetch(){this.originalFetch=window.fetch.bind(window);let Q=this;window.fetch=async function(X,Y){if(!Q.isFormLikeRequest(X,Y))return Q.originalFetch(X,Y);if(Q.hasScore)return Q.originalFetch(X,Y);return new Promise((Z,$)=>{let J={resolve:Z,reject:$,execute:()=>Q.originalFetch(X,Y),timestamp:performance.now()};if(Q.pendingRequests.push(J),Q.config.showLoadingUI&&Q.pendingRequests.length===1)Q.showLoading(document.createElement("form"));if(setTimeout(()=>{if(Q.pendingRequests.includes(J))Q.releaseRequest(J)},Q.config.maxHoldTime),Q.hasScore)Q.releaseRequest(J)})}}interceptXHR(){this.originalXHROpen=XMLHttpRequest.prototype.open,this.originalXHRSend=XMLHttpRequest.prototype.send;let Q=this;XMLHttpRequest.prototype.open=function(X,Y,Z=!0,$,J){let z=this;return z._bsMethod=X.toUpperCase(),z._bsUrl=Y.toString(),Q.originalXHROpen.call(this,X,Y,Z,$,J)},XMLHttpRequest.prototype.send=function(X){let Y=this,Z=Y._bsMethod||"GET",$=Y._bsUrl||"";if(Z!=="POST")return Q.originalXHRSend.call(this,X);try{if(new URL($,window.location.origin).origin!==window.location.origin)return Q.originalXHRSend.call(this,X)}catch{return Q.originalXHRSend.call(this,X)}if(Q.hasScore)return Q.originalXHRSend.call(this,X);let J=performance.now(),z=()=>{if(Q.hasScore){if(Q.config.showLoadingUI)Q.hideLoading();Q.originalXHRSend.call(Y,X)}else if(performance.now()-J>=Q.config.maxHoldTime){if(Q.config.showLoadingUI)Q.hideLoading();Q.originalXHRSend.call(Y,X)}else setTimeout(z,50)};if(Q.config.showLoadingUI)Q.showLoading(document.createElement("form"));z()}}releaseRequest(Q){let X=this.pendingRequests.indexOf(Q);if(X===-1)return;if(this.pendingRequests.splice(X,1),this.pendingRequests.length===0&&this.config.showLoadingUI)this.hideLoading();Q.execute().then(Q.resolve).catch(Q.reject)}protectForm(Q){if(this.protectedForms.has(Q))return;this.protectedForms.add(Q),Q.addEventListener("submit",(X)=>this.handleSubmit(X,Q),{capture:!0})}handleSubmit(Q,X){if(this.releasingForms.has(X)){this.releasingForms.delete(X);return}let Z=performance.now()-this.startTime;switch(N().markFirstSubmitAttempt(this.hasScore),this.config.mode){case"holdUntilReady":if(!this.hasScore)Q.preventDefault(),Q.stopPropagation(),this.holdSubmission(X,Q);break;case"holdUntilFormScored":Q.preventDefault(),Q.stopPropagation(),this.holdAndScoreSubmission(X,Q);break;case"blockInstant":if(Z<this.config.minTimeBeforeSubmit)Q.preventDefault(),Q.stopPropagation(),this.config.onBlock?.(X,"instant_submission");break;case"challengeFirst":if(!this.hasScore)Q.preventDefault(),Q.stopPropagation(),this.holdSubmission(X,Q);break;case"none":default:break}}holdSubmission(Q,X){if(this.config.onHold?.(Q),this.config.showLoadingUI)this.showLoading(Q);let Y={form:Q,event:X,timestamp:performance.now(),resolver:()=>{},rejecter:()=>{}},Z=new Promise(($,J)=>{Y.resolver=$,Y.rejecter=J});if(this.pendingSubmissions.push(Y),setTimeout(()=>{if(this.pendingSubmissions.includes(Y))this.releaseSubmission(Y,!1)},this.config.maxHoldTime),this.hasScore)this.releaseSubmission(Y,!1);Z.catch(()=>{})}async holdAndScoreSubmission(Q,X){if(this.config.onHold?.(Q),this.config.showLoadingUI)this.showLoading(Q);let Y=performance.now();try{if(!this.config.flushAndWaitForScore){this.submitForm(Q);return}let Z=this.config.flushAndWaitForScore(),$=new Promise((W)=>{setTimeout(()=>W(null),this.config.maxHoldTime)}),J=await Promise.race([Z,$]),z=performance.now()-Y;if(J===null);else this.currentScore=J,this.hasFormScore=!0;if(this.config.showLoadingUI)this.hideLoading();this.config.onRelease?.(Q,!1),this.submitForm(Q)}catch(Z){if(this.config.showLoadingUI)this.hideLoading();this.config.onRelease?.(Q,!1),this.submitForm(Q)}}submitForm(Q){if(this.releasingForms.add(Q),Q.requestSubmit)Q.requestSubmit();else Q.submit()}releaseSubmission(Q,X){let Y=this.pendingSubmissions.indexOf(Q);if(Y===-1)return;if(this.pendingSubmissions.splice(Y,1),this.config.showLoadingUI)this.hideLoading();if(this.config.onRelease?.(Q.form,X),!X)if(Q.resolver(),Q.form.requestSubmit)Q.form.requestSubmit();else Q.form.submit();else Q.rejecter("blocked")}showLoading(Q){if(this.loadingOverlay)return;this.loadingOverlay=document.createElement("div"),this.loadingOverlay.innerHTML=`
|
|
1
|
+
import{a as y,b as U,d as v}from"./hash-q46pgar4.js";function T(Q){return typeof Q==="object"&&Q!==null&&"code"in Q&&Q.code==="LIMIT_EXCEEDED"}var q={endpoint:"wss://botsigged.com/sdk/websocket",debug:!1,sendInterval:2000,maxBufferSize:1000,mouseSampleRate:0.5,autoStart:!0,actionThreshold:70,action:"none",minAlertLevel:"high",botScoreThresholds:{medium:40,high:70,critical:90},hashVerification:{enabled:!1,preferWasm:!0},challenge:{enabled:!1,minLevel:"high",chunkSize:1e4,difficulty:{medium:12,high:16,critical:20},ui:{enabled:!0,message:"Verifying you're human...",successMessage:"Verified!",backgroundColor:"rgba(0, 0, 0, 0.7)",textColor:"#ffffff",spinnerColor:"#3b82f6",zIndex:999999}},formProtection:{mode:"auto",minTimeBeforeSubmit:500,maxHoldTime:3000,showLoadingUI:!0,loadingMessage:"Please wait..."},fallbackMode:"degraded"},F={action:"challenge",challenge:{difficulty:{suspicious:14,bot:18},timeout_ms:30000},form_protection_mode:"holdUntilReady"};function h(Q){let X=Q.action??q.action,Y=X==="challenge"||Q.challenge?.enabled;return{apiKey:Q.apiKey,accountId:Q.accountId,endpoint:Q.endpoint??q.endpoint,debug:Q.debug??q.debug,sendInterval:Q.sendInterval??q.sendInterval,maxBufferSize:Q.maxBufferSize??q.maxBufferSize,mouseSampleRate:Q.mouseSampleRate??q.mouseSampleRate,autoStart:Q.autoStart??q.autoStart,actionThreshold:Q.actionThreshold??q.actionThreshold,action:X,minAlertLevel:Q.minAlertLevel??q.minAlertLevel,botScoreThresholds:{...q.botScoreThresholds,...Q.botScoreThresholds},hashVerification:{...q.hashVerification,...Q.hashVerification},challenge:{enabled:Y,minLevel:Q.challenge?.minLevel??q.challenge.minLevel,chunkSize:Q.challenge?.chunkSize??q.challenge.chunkSize,difficulty:{...q.challenge.difficulty,...Q.challenge?.difficulty},ui:{...q.challenge.ui,...Q.challenge?.ui},onChallengeStart:Q.challenge?.onChallengeStart,onChallengeComplete:Q.challenge?.onChallengeComplete,onChallengeProgress:Q.challenge?.onChallengeProgress},formProtection:{mode:Q.formProtection?.mode??q.formProtection.mode,minTimeBeforeSubmit:Q.formProtection?.minTimeBeforeSubmit??q.formProtection.minTimeBeforeSubmit,maxHoldTime:Q.formProtection?.maxHoldTime??q.formProtection.maxHoldTime,showLoadingUI:Q.formProtection?.showLoadingUI??q.formProtection.showLoadingUI,loadingMessage:Q.formProtection?.loadingMessage??q.formProtection.loadingMessage,onHold:Q.formProtection?.onHold,onRelease:Q.formProtection?.onRelease,onBlock:Q.formProtection?.onBlock},fallbackMode:Q.fallbackMode??q.fallbackMode,cookie:Q.cookie,headers:Q.headers,formInject:Q.formInject,onScoreUpdate:Q.onScoreUpdate,onConnectionChange:Q.onConnectionChange,onError:Q.onError,onUsageLimitExceeded:Q.onUsageLimitExceeded,onHighBotScore:Q.onHighBotScore,onServerConfig:Q.onServerConfig,onServerAction:Q.onServerAction}}class k{events=[];startTime=0;sampleRate;maxBufferSize;isListening=!1;boundHandleMouseMove;boundHandleMouseDown;boundHandleMouseUp;boundHandleClick;constructor(Q={}){this.sampleRate=Q.sampleRate??0.5,this.maxBufferSize=Q.maxBufferSize??500,this.boundHandleMouseMove=this.handleMouseMove.bind(this),this.boundHandleMouseDown=this.handleMouseDown.bind(this),this.boundHandleMouseUp=this.handleMouseUp.bind(this),this.boundHandleClick=this.handleClick.bind(this)}start(){if(this.isListening)return;this.startTime=Date.now(),document.addEventListener("mousemove",this.boundHandleMouseMove,{passive:!0}),document.addEventListener("mousedown",this.boundHandleMouseDown,{passive:!0}),document.addEventListener("mouseup",this.boundHandleMouseUp,{passive:!0}),document.addEventListener("click",this.boundHandleClick,{passive:!0}),this.isListening=!0}stop(){if(!this.isListening)return;document.removeEventListener("mousemove",this.boundHandleMouseMove),document.removeEventListener("mousedown",this.boundHandleMouseDown),document.removeEventListener("mouseup",this.boundHandleMouseUp),document.removeEventListener("click",this.boundHandleClick),this.isListening=!1}addEvent(Q){if(this.events.push(Q),this.events.length>this.maxBufferSize)this.events.shift()}handleMouseMove(Q){if(Math.random()>this.sampleRate)return;this.addEvent({type:"move",x:Q.clientX,y:Q.clientY,t:Date.now()})}handleMouseDown(Q){this.addEvent({type:"down",x:Q.clientX,y:Q.clientY,t:Date.now(),button:Q.button})}handleMouseUp(Q){this.addEvent({type:"up",x:Q.clientX,y:Q.clientY,t:Date.now(),button:Q.button})}handleClick(Q){let X=Q.target,Y,Z;if(X&&X.getBoundingClientRect){let $=X.getBoundingClientRect();Y={top:$.top,left:$.left,width:$.width,height:$.height},Z=X.tagName?.toLowerCase()}this.addEvent({type:"click",x:Q.clientX,y:Q.clientY,t:Date.now(),button:Q.button,targetRect:Y,targetTag:Z})}getSignal(){return{events:[...this.events],start_time:this.startTime}}flush(){this.events=[]}getBufferSize(){return this.events.length}reset(){this.events=[],this.startTime=Date.now()}}class x{events=[];startTime=0;maxBufferSize;isListening=!1;boundHandleScroll;constructor(Q={}){this.maxBufferSize=Q.maxBufferSize??200,this.boundHandleScroll=this.handleScroll.bind(this)}start(){if(this.isListening)return;this.startTime=Date.now(),window.addEventListener("scroll",this.boundHandleScroll,{passive:!0}),this.isListening=!0}stop(){if(!this.isListening)return;window.removeEventListener("scroll",this.boundHandleScroll),this.isListening=!1}handleScroll(){if(this.events.push({y:window.scrollY,t:Date.now()}),this.events.length>this.maxBufferSize)this.events.shift()}getSignal(){return{events:[...this.events],start_time:this.startTime}}flush(){this.events=[]}getBufferSize(){return this.events.length}reset(){this.events=[],this.startTime=Date.now()}}class w{static instance=null;timings={signalRoundtrips:[]};pendingSignals=new Map;constructor(){this.timings.scriptStart=performance.now()}static getInstance(){if(!w.instance)w.instance=new w;return w.instance}static reset(){w.instance=null}markScriptStart(){this.timings.scriptStart=performance.now()}markConstructorStart(){this.timings.constructorStart=performance.now()}markConstructorEnd(){this.timings.constructorEnd=performance.now()}markStartCalled(){this.timings.startCalled=performance.now()}markSdkReady(){this.timings.sdkReady=performance.now()}markFingerprintStart(){this.timings.fingerprintStart=performance.now()}markFingerprintEnd(){this.timings.fingerprintEnd=performance.now()}markWsConnectStart(){this.timings.wsConnectStart=performance.now()}markWsConnectEnd(){this.timings.wsConnectEnd=performance.now()}markChannelJoinStart(){this.timings.channelJoinStart=performance.now()}markChannelJoinEnd(){this.timings.channelJoinEnd=performance.now()}markInitialScoreReceived(){this.timings.initialScoreReceived=performance.now()}markFormCollectorStart(){this.timings.formCollectorStart=performance.now()}markFormCollectorReady(){this.timings.formCollectorReady=performance.now()}markFirstFormInteraction(){if(!this.timings.firstFormInteraction){if(this.timings.firstFormInteraction=performance.now(),this.timings.sdkReady)this.timings.timeToFirstInteraction=this.timings.firstFormInteraction-this.timings.sdkReady}}markFirstSubmitAttempt(Q){if(!this.timings.firstSubmitAttempt)this.timings.firstSubmitAttempt=performance.now(),this.timings.hadScoreBeforeSubmit=Q}markSignalSent(Q){this.pendingSignals.set(Q,performance.now())}markSignalResponseReceived(Q){let X=this.pendingSignals.get(Q);if(X!==void 0){let Y=performance.now(),Z={sentAt:X,receivedAt:Y,roundtripMs:Y-X,seq:Q};this.timings.signalRoundtrips?.push(Z),this.pendingSignals.delete(Q)}}getTimings(){return{...this.timings}}getSummary(){let Q=this.timings,X=Q.signalRoundtrips||[],Y=0,Z=1/0,$=0;if(X.length>0)Y=X.reduce((G,g)=>G+g.roundtripMs,0)/X.length,Z=Math.min(...X.map((G)=>G.roundtripMs)),$=Math.max(...X.map((G)=>G.roundtripMs));let J=(Q.sdkReady??0)-(Q.scriptStart??0),z=(Q.fingerprintEnd??0)-(Q.fingerprintStart??0),W=(Q.wsConnectEnd??0)-(Q.wsConnectStart??0),B=(Q.channelJoinEnd??0)-(Q.channelJoinStart??0),V=(Q.initialScoreReceived??0)-(Q.startCalled??0),R=(Q.initialScoreReceived??0)-(Q.scriptStart??0);return{totalStartupMs:Math.round(J),fingerprintMs:Math.round(z),wsConnectionMs:Math.round(W),channelJoinMs:Math.round(B),timeToFirstScoreMs:Math.round(V),avgSignalRoundtripMs:Math.round(Y),minSignalRoundtripMs:Z===1/0?0:Math.round(Z),maxSignalRoundtripMs:Math.round($),vulnerabilityWindowMs:Math.round(R),protectedBeforeSubmit:Q.hadScoreBeforeSubmit??!1}}logSummary(){let Q=this.getSummary(),X=this.timings;if(X.firstFormInteraction);if(X.firstSubmitAttempt);if(Q.vulnerabilityWindowMs>0);}getReport(){return{timings:this.timings,summary:this.getSummary(),userAgent:navigator.userAgent,timestamp:Date.now()}}}var K=w.getInstance();function N(){return w.getInstance()}function l(){return K.getSummary()}function f(){K.logSummary()}var j="__bs_ghost_value";class C{keyEvents=[];focusEvents=[];pasteEvents=[];inputEvents=[];submitCount=0;startTime=0;maxKeyEvents;maxFocusEvents;maxInputEvents;isListening=!1;valueSetterHooked=!1;onSubmit;originalInputDescriptor;originalTextareaDescriptor;lastKeyWasTab=!1;currentField=null;emailDomains=new Set;boundHandleFocusIn;boundHandleFocusOut;boundHandleKeyDown;boundHandleKeyUp;boundHandlePaste;boundHandleSubmit;boundHandleClick;boundHandleInput;boundHandleGhostValue;constructor(Q={}){this.maxKeyEvents=Q.maxKeyEvents??500,this.maxFocusEvents=Q.maxFocusEvents??100,this.maxInputEvents=Q.maxInputEvents??200,this.onSubmit=Q.onSubmit,this.boundHandleFocusIn=this.handleFocusIn.bind(this),this.boundHandleFocusOut=this.handleFocusOut.bind(this),this.boundHandleKeyDown=this.handleKeyDown.bind(this),this.boundHandleKeyUp=this.handleKeyUp.bind(this),this.boundHandlePaste=this.handlePaste.bind(this),this.boundHandleSubmit=this.handleSubmit.bind(this),this.boundHandleClick=this.handleClick.bind(this),this.boundHandleInput=this.handleInput.bind(this),this.boundHandleGhostValue=this.handleGhostValue.bind(this)}start(){if(this.isListening)return;this.startTime=Date.now(),document.addEventListener("focusin",this.boundHandleFocusIn,{passive:!0,capture:!0}),document.addEventListener("focusout",this.boundHandleFocusOut,{passive:!0,capture:!0}),document.addEventListener("keydown",this.boundHandleKeyDown,{passive:!0}),document.addEventListener("keyup",this.boundHandleKeyUp,{passive:!0}),document.addEventListener("paste",this.boundHandlePaste,{passive:!0}),document.addEventListener("submit",this.boundHandleSubmit,{passive:!0}),document.addEventListener("click",this.boundHandleClick,{passive:!0}),document.addEventListener("input",this.boundHandleInput,{passive:!0}),document.addEventListener(j,this.boundHandleGhostValue,{passive:!0}),this.hookValueSetters(),this.isListening=!0}stop(){if(!this.isListening)return;document.removeEventListener("focusin",this.boundHandleFocusIn,{capture:!0}),document.removeEventListener("focusout",this.boundHandleFocusOut,{capture:!0}),document.removeEventListener("keydown",this.boundHandleKeyDown),document.removeEventListener("keyup",this.boundHandleKeyUp),document.removeEventListener("paste",this.boundHandlePaste),document.removeEventListener("submit",this.boundHandleSubmit),document.removeEventListener("click",this.boundHandleClick),document.removeEventListener("input",this.boundHandleInput),document.removeEventListener(j,this.boundHandleGhostValue),this.unhookValueSetters(),this.isListening=!1}isFormInput(Q){if(!Q||!(Q instanceof HTMLElement))return!1;let X=Q.tagName.toLowerCase();if(X==="textarea"||X==="select")return!0;if(X==="input"){let Y=Q.type.toLowerCase();return!["submit","button","reset","hidden","image"].includes(Y)}return!1}isEmailField(Q){let X=Q.type?.toLowerCase()||"",Y=(Q.name||"").toLowerCase(),Z=(Q.id||"").toLowerCase();return X==="email"||Y.includes("email")||Y.includes("e-mail")||Z.includes("email")||Z.includes("e-mail")}extractEmailDomain(Q){if(!Q||typeof Q!=="string")return null;let X=Q.trim();if(!X)return null;let Y=X.match(/@([a-zA-Z0-9.-]+\.[a-zA-Z]{2,})$/);return Y?Y[1].toLowerCase():null}getFieldId(Q){return Q.id||Q.getAttribute("name")||`field-${Q.tagName.toLowerCase()}`}handleFocusIn(Q){if(!this.isFormInput(Q.target))return;N().markFirstFormInteraction();let X=this.getFieldId(Q.target),Y="direct";if(this.lastKeyWasTab)Y="tab";if(this.focusEvents.push({type:"focus",field:X,t:Date.now(),method:Y}),this.focusEvents.length>this.maxFocusEvents)this.focusEvents.shift();this.currentField=X,this.lastKeyWasTab=!1}handleFocusOut(Q){if(!this.isFormInput(Q.target))return;let X=Q.target,Y=this.getFieldId(X);if(this.focusEvents.push({type:"blur",field:Y,t:Date.now()}),this.focusEvents.length>this.maxFocusEvents)this.focusEvents.shift();if(X instanceof HTMLInputElement&&this.isEmailField(X)){let Z=this.extractEmailDomain(X.value);if(Z)this.emailDomains.add(Z)}this.currentField=null}handleClick(Q){if(!this.isFormInput(Q.target))return;let X=this.focusEvents[this.focusEvents.length-1];if(X&&X.type==="focus"&&Date.now()-X.t<50)X.method="click"}handleKeyDown(Q){if(Q.key==="Tab"){this.lastKeyWasTab=!0;return}if(!this.isFormInput(Q.target))return;let X="key";if(Q.key==="Backspace")X="backspace";else if(Q.key==="Delete")X="delete";else if(Q.key==="Enter")X="enter";else if(Q.key==="Tab")X="tab";else if(Q.key.length===1)X="char";else if(Q.key.startsWith("Arrow"))X="arrow";if(this.keyEvents.push({type:"down",code:X,t:Date.now(),field:this.currentField||void 0}),this.keyEvents.length>this.maxKeyEvents)this.keyEvents.shift()}handleKeyUp(Q){if(!this.isFormInput(Q.target))return;let X="key";if(Q.key==="Backspace")X="backspace";else if(Q.key==="Delete")X="delete";else if(Q.key.length===1)X="char";if(this.keyEvents.push({type:"up",code:X,t:Date.now(),field:this.currentField||void 0}),this.keyEvents.length>this.maxKeyEvents)this.keyEvents.shift()}handleInput(Q){if(!this.isFormInput(Q.target))return;let X=Q.target,Z=Q.inputType||"unknown",$=X.value?.length??0;if(this.inputEvents.push({field:this.getFieldId(X),t:Date.now(),inputType:Z,valueLength:$}),this.inputEvents.length>this.maxInputEvents)this.inputEvents.shift()}handlePaste(Q){if(!this.isFormInput(Q.target))return;let X=Q.clipboardData?.getData("text")||"";this.pasteEvents.push({field:this.getFieldId(Q.target),t:Date.now(),length:X.length})}handleSubmit(Q){this.submitCount++;let X=Q.target;if(X&&X.elements)for(let Y=0;Y<X.elements.length;Y++){let Z=X.elements[Y];if(Z instanceof HTMLInputElement&&this.isEmailField(Z)){let $=this.extractEmailDomain(Z.value);if($)this.emailDomains.add($)}}this.onSubmit?.()}getSignal(){return{keys:[...this.keyEvents],focus:[...this.focusEvents],pastes:[...this.pasteEvents],inputs:[...this.inputEvents],submits:this.submitCount,start_time:this.startTime,email_domains:this.emailDomains.size>0?Array.from(this.emailDomains):void 0}}flush(){this.keyEvents=[],this.focusEvents=[],this.pasteEvents=[],this.inputEvents=[]}getBufferSize(){return this.keyEvents.length+this.focusEvents.length+this.pasteEvents.length+this.inputEvents.length}reset(){this.keyEvents=[],this.focusEvents=[],this.pasteEvents=[],this.inputEvents=[],this.submitCount=0,this.startTime=Date.now(),this.lastKeyWasTab=!1,this.currentField=null,this.emailDomains.clear()}hookValueSetters(){if(this.valueSetterHooked)return;if(this.originalInputDescriptor=Object.getOwnPropertyDescriptor(HTMLInputElement.prototype,"value"),this.originalInputDescriptor){let Q=this.originalInputDescriptor.set,X=this.originalInputDescriptor.get;Object.defineProperty(HTMLInputElement.prototype,"value",{configurable:!0,enumerable:!0,get(){return X?.call(this)},set(Y){let Z=X?.call(this)??"";Q?.call(this,Y);let $=Y??"";if($!==Z)this.dispatchEvent(new CustomEvent(j,{bubbles:!0,detail:{valueLength:$.length,wasEmpty:Z.length===0}}))}})}if(this.originalTextareaDescriptor=Object.getOwnPropertyDescriptor(HTMLTextAreaElement.prototype,"value"),this.originalTextareaDescriptor){let Q=this.originalTextareaDescriptor.set,X=this.originalTextareaDescriptor.get;Object.defineProperty(HTMLTextAreaElement.prototype,"value",{configurable:!0,enumerable:!0,get(){return X?.call(this)},set(Y){let Z=X?.call(this)??"";Q?.call(this,Y);let $=Y??"";if($!==Z)this.dispatchEvent(new CustomEvent(j,{bubbles:!0,detail:{valueLength:$.length,wasEmpty:Z.length===0}}))}})}this.valueSetterHooked=!0}unhookValueSetters(){if(!this.valueSetterHooked)return;if(this.originalInputDescriptor)Object.defineProperty(HTMLInputElement.prototype,"value",this.originalInputDescriptor);if(this.originalTextareaDescriptor)Object.defineProperty(HTMLTextAreaElement.prototype,"value",this.originalTextareaDescriptor);this.valueSetterHooked=!1}handleGhostValue(Q){let X=Q.target;if(!this.isFormInput(X))return;let Z=Q.detail?.valueLength??0;if(this.inputEvents.push({field:this.getFieldId(X),t:Date.now(),inputType:"programmatic",valueLength:Z}),this.inputEvents.length>this.maxInputEvents)this.inputEvents.shift()}}class L{cachedSignal=null;collect(){if(this.cachedSignal)return this.cachedSignal;let Q=navigator,X=window;return this.cachedSignal={user_agent:navigator.userAgent,platform:navigator.platform,language:navigator.language,languages:[...navigator.languages||[]],hardware_concurrency:navigator.hardwareConcurrency??null,device_memory:Q.deviceMemory??null,max_touch_points:navigator.maxTouchPoints??0,screen_width:screen.width,screen_height:screen.height,screen_avail_width:screen.availWidth,screen_avail_height:screen.availHeight,color_depth:screen.colorDepth,pixel_ratio:window.devicePixelRatio??1,...this.getWebGLInfo(),plugins_count:navigator.plugins?.length??0,mime_types_count:navigator.mimeTypes?.length??0,timezone:this.getTimezone(),timezone_offset:new Date().getTimezoneOffset(),has_webdriver:Q.webdriver===!0,has_chrome_runtime:!!X.chrome?.runtime,has_chrome_app:!!X.chrome?.app,has_notification_api:"Notification"in window,has_permissions_api:"permissions"in navigator,outer_dimensions:{width:window.outerWidth,height:window.outerHeight},inner_dimensions:{width:window.innerWidth,height:window.innerHeight},notification_permission:this.getNotificationPermission()},this.cachedSignal}getWebGLInfo(){try{let Q=document.createElement("canvas"),X=Q.getContext("webgl")||Q.getContext("experimental-webgl");if(!X||!(X instanceof WebGLRenderingContext))return{webgl_vendor:null,webgl_renderer:null};let Y=X.getExtension("WEBGL_debug_renderer_info");if(!Y)return{webgl_vendor:null,webgl_renderer:null};return{webgl_vendor:X.getParameter(Y.UNMASKED_VENDOR_WEBGL),webgl_renderer:X.getParameter(Y.UNMASKED_RENDERER_WEBGL)}}catch{return{webgl_vendor:null,webgl_renderer:null}}}getTimezone(){try{return Intl.DateTimeFormat().resolvedOptions().timeZone}catch{return null}}getNotificationPermission(){if("Notification"in window)return Notification.permission;return null}getSignal(){return this.collect()}reset(){this.cachedSignal=null}}class b{cachedFingerprint=null;async generate(){if(this.cachedFingerprint)return this.cachedFingerprint;let[Q,X,Y,Z,$]=await Promise.all([this.getCanvasHash(),this.getWebGLData(),this.getAudioHash(),this.getFontData(),this.getScreenHash()]),J={hash:"",canvas_hash:Q,webgl_hash:X.hash,audio_hash:Y,font_hash:Z.hash,screen_hash:$,webgl_vendor:X.vendor,webgl_renderer:X.renderer,timezone:this.getTimezone(),language:this.getLanguage(),platform:this.getPlatform(),font_count:Z.count};return J.hash=await this.generateMainHash(J),this.cachedFingerprint=J,J}getFingerprint(){return this.cachedFingerprint}reset(){this.cachedFingerprint=null}async getCanvasHash(){try{let Q=document.createElement("canvas");Q.width=200,Q.height=50;let X=Q.getContext("2d");if(!X)return null;X.textBaseline="top",X.font="14px 'Arial'",X.fillStyle="#f60",X.fillRect(125,1,62,20),X.fillStyle="#069",X.fillText("BotSigged,\uD83C\uDFA8",2,15),X.fillStyle="rgba(102, 204, 0, 0.7)",X.fillText("BotSigged,\uD83C\uDFA8",4,17);let Y=Q.toDataURL();return this.hashString(Y)}catch{return null}}async getWebGLData(){try{let Q=document.createElement("canvas"),X=Q.getContext("webgl")||Q.getContext("experimental-webgl");if(!X||!(X instanceof WebGLRenderingContext))return{hash:null,vendor:null,renderer:null};let Y=[],Z=[X.ALIASED_LINE_WIDTH_RANGE,X.ALIASED_POINT_SIZE_RANGE,X.ALPHA_BITS,X.BLUE_BITS,X.DEPTH_BITS,X.GREEN_BITS,X.MAX_COMBINED_TEXTURE_IMAGE_UNITS,X.MAX_CUBE_MAP_TEXTURE_SIZE,X.MAX_FRAGMENT_UNIFORM_VECTORS,X.MAX_RENDERBUFFER_SIZE,X.MAX_TEXTURE_IMAGE_UNITS,X.MAX_TEXTURE_SIZE,X.MAX_VARYING_VECTORS,X.MAX_VERTEX_ATTRIBS,X.MAX_VERTEX_TEXTURE_IMAGE_UNITS,X.MAX_VERTEX_UNIFORM_VECTORS,X.MAX_VIEWPORT_DIMS,X.RED_BITS,X.RENDERER,X.SHADING_LANGUAGE_VERSION,X.STENCIL_BITS,X.VENDOR,X.VERSION];for(let V of Z)try{let R=X.getParameter(V);Y.push(String(R))}catch{Y.push("")}let $=X.getSupportedExtensions();if($)Y.push($.sort().join(","));let J=null,z=null,W=X.getExtension("WEBGL_debug_renderer_info");if(W)J=X.getParameter(W.UNMASKED_VENDOR_WEBGL),z=X.getParameter(W.UNMASKED_RENDERER_WEBGL);return{hash:this.hashString(Y.join("|")),vendor:J,renderer:z}}catch{return{hash:null,vendor:null,renderer:null}}}async getAudioHash(){try{let Q=window.OfflineAudioContext||window.webkitOfflineAudioContext;if(!Q)return null;let X=new Q(1,4500,44100),Y=X.createOscillator(),Z=X.createDynamicsCompressor();Y.type="triangle",Y.frequency.setValueAtTime(1e4,X.currentTime),Z.threshold.setValueAtTime(-50,X.currentTime),Z.knee.setValueAtTime(40,X.currentTime),Z.ratio.setValueAtTime(12,X.currentTime),Z.attack.setValueAtTime(0,X.currentTime),Z.release.setValueAtTime(0.25,X.currentTime),Y.connect(Z),Z.connect(X.destination),Y.start(0);let J=(await X.startRendering()).getChannelData(0),z=[];for(let W=0;W<J.length;W+=100)z.push(J[W]);return this.hashString(z.join(","))}catch{return null}}async getFontData(){let Q=["Arial","Arial Black","Arial Narrow","Calibri","Cambria","Cambria Math","Comic Sans MS","Consolas","Courier","Courier New","Georgia","Helvetica","Impact","Lucida Console","Lucida Sans Unicode","Microsoft Sans Serif","MS Gothic","MS PGothic","MS Sans Serif","MS Serif","Palatino Linotype","Segoe Print","Segoe Script","Segoe UI","Symbol","Tahoma","Times","Times New Roman","Trebuchet MS","Verdana","Wingdings"],X=["monospace","sans-serif","serif"],Y="mmmmmmmmmmlli",Z="72px",$=document.createElement("span");$.style.position="absolute",$.style.left="-9999px",$.style.fontSize="72px",$.style.lineHeight="normal",$.innerHTML="mmmmmmmmmmlli",document.body.appendChild($);let J={};for(let B of X)$.style.fontFamily=B,J[B]=$.offsetWidth;let z=[];for(let B of Q){let V=!1;for(let R of X)if($.style.fontFamily=`'${B}', ${R}`,$.offsetWidth!==J[R]){V=!0;break}if(V)z.push(B)}return document.body.removeChild($),{hash:this.hashString(z.join(",")),count:z.length}}async getScreenHash(){let Q=[String(screen.width),String(screen.height),String(screen.availWidth),String(screen.availHeight),String(screen.colorDepth),String(screen.pixelDepth),String(window.devicePixelRatio||1)];return this.hashString(Q.join("|"))}getTimezone(){try{return Intl.DateTimeFormat().resolvedOptions().timeZone}catch{return null}}getLanguage(){return navigator.language||null}getPlatform(){return navigator.platform||null}generateMainHash(Q){let X=[Q.canvas_hash||"",Q.webgl_hash||"",Q.audio_hash||"",Q.font_hash||"",Q.screen_hash||"",Q.timezone||"",Q.language||"",Q.platform||""];return this.hashString(X.join("|"))}hashString(Q){return v(Q)}}class A{ws=null;endpoint;apiKey;heartbeatInterval;reconnectAttempts;reconnectDelay;debug;state="disconnected";channelState="closed";refCounter=0;joinRef=null;heartbeatTimer=null;reconnectTimer=null;reconnectCount=0;pendingReplies=new Map;onConnectionChange;onError;channelCallbacks={};topic=null;constructor(Q){this.endpoint=Q.endpoint,this.apiKey=Q.apiKey,this.heartbeatInterval=Q.heartbeatInterval??30000,this.reconnectAttempts=Q.reconnectAttempts??10,this.reconnectDelay=Q.reconnectDelay??((X)=>Math.min(1000*Math.pow(2,X),30000)),this.debug=Q.debug??!1,this.onConnectionChange=Q.onConnectionChange,this.onError=Q.onError}connect(){return new Promise((Q,X)=>{if(this.ws&&this.state==="connected"){Q();return}this.setState("connecting");let Y=this.buildUrl();this.log("Connecting to",Y);try{this.ws=new WebSocket(Y),this.ws.onopen=()=>{this.log("WebSocket connected"),this.setState("connected"),this.reconnectCount=0,this.startHeartbeat(),Q()},this.ws.onclose=(Z)=>{this.log("WebSocket closed",Z.code,Z.reason),this.handleClose()},this.ws.onerror=(Z)=>{this.log("WebSocket error",Z);let $=Error("WebSocket connection error");this.handleError($),X($)},this.ws.onmessage=(Z)=>{this.handleMessage(Z.data)}}catch(Z){let $=Z instanceof Error?Z:Error(String(Z));this.handleError($),X($)}})}disconnect(){if(this.stopHeartbeat(),this.stopReconnect(),this.ws)this.ws.close(1000,"Client disconnect"),this.ws=null;this.setState("disconnected"),this.setChannelState("closed")}joinChannel(Q,X,Y,Z,$={},J){return this.channelCallbacks=$,this.topic=`detection:${Q}`,new Promise((z,W)=>{if(this.state!=="connected"){W(Error("WebSocket not connected"));return}this.setChannelState("joining"),this.joinRef=this.makeRef();let B={session_id:Q,api_key:this.apiKey,fingerprint:X,session:Y,browser:Z};if(J)B.account_id=J;this.push("phx_join",B,this.joinRef).then((V)=>{this.log("Channel joined",V),this.setChannelState("joined"),this.channelCallbacks.onJoin?.(),z(V)}).catch((V)=>{this.log("Channel join failed",V),this.setChannelState("error"),this.channelCallbacks.onError?.(V),W(V)})})}leaveChannel(){return new Promise((Q,X)=>{if(this.channelState!=="joined"){Q();return}this.setChannelState("leaving"),this.push("phx_leave",{}).then(()=>{this.log("Channel left"),this.setChannelState("closed"),this.joinRef=null,this.topic=null,this.channelCallbacks.onLeave?.(),Q()}).catch((Y)=>{this.setChannelState("error"),X(Y)})})}sendSignal(Q){if(this.channelState!=="joined")return Promise.reject(Error("Channel not joined"));return this.push("signal",Q)}sendFormStatus(Q){if(this.channelState!=="joined")return Promise.reject(Error("Channel not joined"));return this.push("form_status",{status:Q})}sendEvent(Q,X){if(this.channelState!=="joined")return Promise.reject(Error("Channel not joined"));return this.push(Q,X)}getState(){return this.state}getChannelState(){return this.channelState}isReady(){return this.state==="connected"&&this.channelState==="joined"}buildUrl(){let Q=new URL(this.endpoint);return Q.searchParams.set("vsn","2.0.0"),Q.searchParams.set("api_key",this.apiKey),Q.toString()}makeRef(){return this.refCounter++,String(this.refCounter)}push(Q,X,Y){return new Promise((Z,$)=>{if(!this.ws||this.ws.readyState!==WebSocket.OPEN){$(Error("WebSocket not open"));return}if(!this.topic){$(Error("Channel topic not set"));return}let J=Y??this.makeRef(),z=[this.joinRef,J,this.topic,Q,X],W=setTimeout(()=>{this.pendingReplies.delete(J),$(Error(`Timeout waiting for reply to ${Q}`))},1e4);this.pendingReplies.set(J,{resolve:Z,reject:$,timeout:W}),this.log("Sending",Q,X),this.ws.send(JSON.stringify(z))})}handleMessage(Q){try{let[X,Y,Z,$,J]=JSON.parse(Q);if(this.log("Received",$,J),$==="phx_reply"&&Y){let z=this.pendingReplies.get(Y);if(z){clearTimeout(z.timeout),this.pendingReplies.delete(Y);let W=J;if(W.status==="ok")z.resolve(W.response??{});else if(W.response&&typeof W.response==="object"&&"code"in W.response)z.reject(W.response);else{let B=this.buildErrorMessage(W.status,W.response);z.reject(Error(B))}}return}if($==="phx_error"){let z=Error("Channel error");this.setChannelState("error"),this.channelCallbacks.onError?.(z);return}if($==="phx_close"){this.setChannelState("closed"),this.channelCallbacks.onLeave?.();return}if($==="score_update"){this.channelCallbacks.onScoreUpdate?.(J);return}if($==="action"){this.channelCallbacks.onAction?.(J);return}this.channelCallbacks.onMessage?.($,J)}catch(X){this.log("Error parsing message",X)}}handleClose(){this.stopHeartbeat(),this.setState("disconnected"),this.setChannelState("closed");for(let[Q,X]of this.pendingReplies)clearTimeout(X.timeout),X.reject(Error("Connection closed"));this.pendingReplies.clear(),this.scheduleReconnect()}handleError(Q){this.setState("error"),this.onError?.(Q)}startHeartbeat(){this.stopHeartbeat(),this.heartbeatTimer=setInterval(()=>{if(this.ws&&this.ws.readyState===WebSocket.OPEN){let Q=[null,this.makeRef(),"phoenix","heartbeat",{}];if(this.ws.send(JSON.stringify(Q)),this.channelState==="joined")this.push("heartbeat",{}).then((X)=>{if(X.bot_score!==void 0)this.channelCallbacks.onScoreUpdate?.({bot_score:X.bot_score,classification:X.classification,triggered_rules:[],event_count:0})}).catch(()=>{})}},this.heartbeatInterval)}stopHeartbeat(){if(this.heartbeatTimer)clearInterval(this.heartbeatTimer),this.heartbeatTimer=null}scheduleReconnect(){if(this.reconnectCount>=this.reconnectAttempts){this.log("Max reconnect attempts reached");return}let Q=this.reconnectDelay(this.reconnectCount);this.reconnectCount++,this.log(`Scheduling reconnect attempt ${this.reconnectCount} in ${Q}ms`),this.reconnectTimer=setTimeout(()=>{this.connect().catch((X)=>{this.log("Reconnect failed",X)})},Q)}stopReconnect(){if(this.reconnectTimer)clearTimeout(this.reconnectTimer),this.reconnectTimer=null;this.reconnectCount=0}setState(Q){if(this.state!==Q)this.state=Q,this.onConnectionChange?.(Q)}setChannelState(Q){this.channelState=Q}buildErrorMessage(Q,X){if(X){if(typeof X.reason==="string")return`Channel error: ${X.reason}`;if(Object.keys(X).length>0)return`Channel error (${Q??"error"}): ${JSON.stringify(X)}`}return Q??"Unknown error"}log(...Q){if(this.debug);}}class D{config;isReady=!1;hasScore=!1;hasFormScore=!1;currentScore=null;pendingSubmissions=[];pendingRequests=[];protectedForms=new Set;releasingForms=new Set;loadingOverlay=null;formObserver=null;startTime;originalFetch=null;originalXHROpen=null;originalXHRSend=null;constructor(Q={}){if(this.startTime=performance.now(),this.config={mode:Q.mode??"none",minTimeBeforeSubmit:Q.minTimeBeforeSubmit??500,maxHoldTime:Q.maxHoldTime??5000,showLoadingUI:Q.showLoadingUI??!0,loadingMessage:Q.loadingMessage??"Please wait...",onHold:Q.onHold,onRelease:Q.onRelease,onBlock:Q.onBlock,flushAndWaitForScore:Q.flushAndWaitForScore},this.config.mode!=="none")this.setup()}setup(){if(this.config.mode==="auto")this.interceptFetch(),this.interceptXHR();let Q=()=>{document.querySelectorAll("form").forEach((X)=>{this.protectForm(X)}),this.formObserver=new MutationObserver((X)=>{X.forEach((Y)=>{Y.addedNodes.forEach((Z)=>{if(Z instanceof HTMLFormElement)this.protectForm(Z);if(Z instanceof HTMLElement)Z.querySelectorAll("form").forEach(($)=>{this.protectForm($)})})})}),this.formObserver.observe(document.body,{childList:!0,subtree:!0})};if(document.body)Q();else document.addEventListener("DOMContentLoaded",Q,{once:!0})}isFormLikeRequest(Q,X){if((X?.method?.toUpperCase()||"GET")!=="POST")return!1;try{if((typeof Q==="string"?new URL(Q,window.location.origin):Q instanceof URL?Q:new URL(Q.url)).origin!==window.location.origin)return!1}catch{return!1}let Z=X?.headers instanceof Headers?X.headers.get("content-type"):typeof X?.headers==="object"&&X.headers!==null?X.headers["content-type"]||X.headers["Content-Type"]:null;if(Z){let $=Z.toLowerCase();if($.includes("application/x-www-form-urlencoded")||$.includes("multipart/form-data")||$.includes("application/json"))return!0;return!1}if(X?.body)return!0;return!1}interceptFetch(){this.originalFetch=window.fetch.bind(window);let Q=this;window.fetch=async function(X,Y){if(!Q.isFormLikeRequest(X,Y))return Q.originalFetch(X,Y);if(Q.hasScore)return Q.originalFetch(X,Y);return new Promise((Z,$)=>{let J={resolve:Z,reject:$,execute:()=>Q.originalFetch(X,Y),timestamp:performance.now()};if(Q.pendingRequests.push(J),Q.config.showLoadingUI&&Q.pendingRequests.length===1)Q.showLoading(document.createElement("form"));if(setTimeout(()=>{if(Q.pendingRequests.includes(J))Q.releaseRequest(J)},Q.config.maxHoldTime),Q.hasScore)Q.releaseRequest(J)})}}interceptXHR(){this.originalXHROpen=XMLHttpRequest.prototype.open,this.originalXHRSend=XMLHttpRequest.prototype.send;let Q=this;XMLHttpRequest.prototype.open=function(X,Y,Z=!0,$,J){let z=this;return z._bsMethod=X.toUpperCase(),z._bsUrl=Y.toString(),Q.originalXHROpen.call(this,X,Y,Z,$,J)},XMLHttpRequest.prototype.send=function(X){let Y=this,Z=Y._bsMethod||"GET",$=Y._bsUrl||"";if(Z!=="POST")return Q.originalXHRSend.call(this,X);try{if(new URL($,window.location.origin).origin!==window.location.origin)return Q.originalXHRSend.call(this,X)}catch{return Q.originalXHRSend.call(this,X)}if(Q.hasScore)return Q.originalXHRSend.call(this,X);let J=performance.now(),z=()=>{if(Q.hasScore){if(Q.config.showLoadingUI)Q.hideLoading();Q.originalXHRSend.call(Y,X)}else if(performance.now()-J>=Q.config.maxHoldTime){if(Q.config.showLoadingUI)Q.hideLoading();Q.originalXHRSend.call(Y,X)}else setTimeout(z,50)};if(Q.config.showLoadingUI)Q.showLoading(document.createElement("form"));z()}}releaseRequest(Q){let X=this.pendingRequests.indexOf(Q);if(X===-1)return;if(this.pendingRequests.splice(X,1),this.pendingRequests.length===0&&this.config.showLoadingUI)this.hideLoading();Q.execute().then(Q.resolve).catch(Q.reject)}protectForm(Q){if(this.protectedForms.has(Q))return;this.protectedForms.add(Q),Q.addEventListener("submit",(X)=>this.handleSubmit(X,Q),{capture:!0})}handleSubmit(Q,X){if(this.releasingForms.has(X)){this.releasingForms.delete(X);return}let Z=performance.now()-this.startTime;switch(N().markFirstSubmitAttempt(this.hasScore),this.config.mode){case"holdUntilReady":if(!this.hasScore)Q.preventDefault(),Q.stopPropagation(),this.holdSubmission(X,Q);break;case"holdUntilFormScored":Q.preventDefault(),Q.stopPropagation(),this.holdAndScoreSubmission(X,Q);break;case"blockInstant":if(Z<this.config.minTimeBeforeSubmit)Q.preventDefault(),Q.stopPropagation(),this.config.onBlock?.(X,"instant_submission");break;case"challengeFirst":if(!this.hasScore)Q.preventDefault(),Q.stopPropagation(),this.holdSubmission(X,Q);break;case"none":default:break}}holdSubmission(Q,X){if(this.config.onHold?.(Q),this.config.showLoadingUI)this.showLoading(Q);let Y={form:Q,event:X,timestamp:performance.now(),resolver:()=>{},rejecter:()=>{}},Z=new Promise(($,J)=>{Y.resolver=$,Y.rejecter=J});if(this.pendingSubmissions.push(Y),setTimeout(()=>{if(this.pendingSubmissions.includes(Y))this.releaseSubmission(Y,!1)},this.config.maxHoldTime),this.hasScore)this.releaseSubmission(Y,!1);Z.catch(()=>{})}async holdAndScoreSubmission(Q,X){if(this.config.onHold?.(Q),this.config.showLoadingUI)this.showLoading(Q);let Y=performance.now();try{if(!this.config.flushAndWaitForScore){this.submitForm(Q);return}let Z=this.config.flushAndWaitForScore(),$=new Promise((W)=>{setTimeout(()=>W(null),this.config.maxHoldTime)}),J=await Promise.race([Z,$]),z=performance.now()-Y;if(J===null);else this.currentScore=J,this.hasFormScore=!0;if(this.config.showLoadingUI)this.hideLoading();this.config.onRelease?.(Q,!1),this.submitForm(Q)}catch(Z){if(this.config.showLoadingUI)this.hideLoading();this.config.onRelease?.(Q,!1),this.submitForm(Q)}}submitForm(Q){if(this.releasingForms.add(Q),Q.requestSubmit)Q.requestSubmit();else Q.submit()}releaseSubmission(Q,X){let Y=this.pendingSubmissions.indexOf(Q);if(Y===-1)return;if(this.pendingSubmissions.splice(Y,1),this.config.showLoadingUI)this.hideLoading();if(this.config.onRelease?.(Q.form,X),!X)if(Q.resolver(),Q.form.requestSubmit)Q.form.requestSubmit();else Q.form.submit();else Q.rejecter("blocked")}showLoading(Q){if(this.loadingOverlay)return;this.loadingOverlay=document.createElement("div"),this.loadingOverlay.innerHTML=`
|
|
2
2
|
<div style="
|
|
3
3
|
position: fixed;
|
|
4
4
|
top: 0;
|
|
@@ -39,4 +39,4 @@ import{a as y,b as U,d as v}from"./hash-q46pgar4.js";function T(Q){return typeof
|
|
|
39
39
|
</style>
|
|
40
40
|
`,document.body.appendChild(this.loadingOverlay)}hideLoading(){if(this.loadingOverlay)this.loadingOverlay.remove(),this.loadingOverlay=null}notifyReady(Q){this.isReady=!0,this.hasScore=!0,this.currentScore=Q,[...this.pendingSubmissions].forEach((Z)=>{this.releaseSubmission(Z,!1)}),[...this.pendingRequests].forEach((Z)=>{this.releaseRequest(Z)}),this.hideLoading()}blockAllPending(Q){[...this.pendingSubmissions].forEach((Y)=>{this.config.onBlock?.(Y.form,Q),this.releaseSubmission(Y,!0)})}getStatus(){return{mode:this.config.mode,isReady:this.isReady,hasScore:this.hasScore,pendingCount:this.pendingSubmissions.length,protectedFormCount:this.protectedForms.size}}waitUntilReady(){if(this.hasScore)return Promise.resolve({score:this.currentScore,timedOut:!1});return new Promise((Q)=>{let X=performance.now(),Y=()=>{if(this.hasScore){Q({score:this.currentScore,timedOut:!1});return}if(performance.now()-X>=this.config.maxHoldTime){Q({score:null,timedOut:!0});return}setTimeout(Y,50)};Y()})}withProtection(Q){return async(...X)=>{let Y=performance.now()-this.startTime;if(N().markFirstSubmitAttempt(this.hasScore),this.config.mode==="blockInstant"&&Y<this.config.minTimeBeforeSubmit)throw this.config.onBlock?.(document.createElement("form"),"instant_submission"),Error("Submission blocked: too fast");if(this.config.mode==="holdUntilReady"&&!this.hasScore){if(this.config.showLoadingUI)this.showLoading(document.createElement("form"));let{timedOut:Z}=await this.waitUntilReady();if(this.config.showLoadingUI)this.hideLoading()}return Q(...X)}}protectedFetch(){return this.withProtection(async(Q,X)=>{return fetch(Q,X)})}setMode(Q){if(this.config.mode=Q,Q==="none")[...this.pendingSubmissions].forEach((Y)=>this.releaseSubmission(Y,!1))}setMaxHoldTime(Q){this.config.maxHoldTime=Q}canSubmit(){let Q=performance.now()-this.startTime;if(this.config.mode==="blockInstant"&&Q<this.config.minTimeBeforeSubmit)return{allowed:!1,reason:"too_fast",score:this.currentScore};if(this.config.mode==="holdUntilReady"&&!this.hasScore)return{allowed:!1,reason:"waiting_for_score",score:null};return{allowed:!0,score:this.currentScore}}destroy(){if(this.formObserver)this.formObserver.disconnect(),this.formObserver=null;if(this.originalFetch)window.fetch=this.originalFetch,this.originalFetch=null;if(this.originalXHROpen)XMLHttpRequest.prototype.open=this.originalXHROpen,this.originalXHROpen=null;if(this.originalXHRSend)XMLHttpRequest.prototype.send=this.originalXHRSend,this.originalXHRSend=null;this.hideLoading(),this.pendingSubmissions=[],this.pendingRequests=[],this.protectedForms.clear()}}var u={suspicious:40,bot:70},H={name:"_bsid",riskName:"_bsrisk",path:"/",sameSite:"Strict"};function d(Q){if(!Q)return null;if(Q===!0)return{...H};return{...H,...Q}}function a(Q){if(Q>=u.bot)return"bot";if(Q>=u.suspicious)return"suspicious";return"human"}class M{config;sessionIdGetter;sessionCookieSet=!1;currentRiskTier=null;constructor(Q,X){this.config={...H,...Q},this.sessionIdGetter=X}buildCookieString(Q,X){let Y=this.config.path||H.path,Z=this.config.sameSite||H.sameSite,$=this.config.secure??location.protocol==="https:",J=[`${encodeURIComponent(Q)}=${encodeURIComponent(X)}`,`Path=${Y}`,`SameSite=${Z}`];if($||Z==="None")J.push("Secure");return J.join("; ")}deleteCookie(Q){let X=this.config.path||H.path;document.cookie=`${encodeURIComponent(Q)}=; Path=${X}; Max-Age=0`}setSessionCookie(){if(this.sessionCookieSet)return;let Q=this.sessionIdGetter();if(!Q)return;let X=this.config.name||H.name;document.cookie=this.buildCookieString(X,Q),this.sessionCookieSet=!0}updateRiskTier(Q){let X=a(Q);if(X===this.currentRiskTier)return!1;let Y=this.config.riskName||H.riskName;document.cookie=this.buildCookieString(Y,X);let Z=this.currentRiskTier;return this.currentRiskTier=X,!0}removeCookies(){let Q=this.config.name||H.name,X=this.config.riskName||H.riskName;if(this.sessionCookieSet)this.deleteCookie(Q),this.sessionCookieSet=!1;if(this.currentRiskTier!==null)this.deleteCookie(X),this.currentRiskTier=null}setCookie(){this.setSessionCookie()}removeCookie(){this.removeCookies()}isSessionCookieSet(){return this.sessionCookieSet}getCurrentRiskTier(){return this.currentRiskTier}getSessionCookieName(){return this.config.name||H.name}getRiskCookieName(){return this.config.riskName||H.riskName}}var P={name:"X-BotSigged-ID"};function m(Q){if(!Q)return null;if(Q===!0)return{...P};return{...P,...Q}}class E{config;sessionIdGetter;started=!1;originalFetch=null;originalXHROpen=null;originalXHRSend=null;originalXHRSetRequestHeader=null;xhrInjectionMap=new WeakMap;constructor(Q,X){this.config={...P,...Q},this.sessionIdGetter=X}start(){if(this.started)return;this.started=!0,this.patchFetch(),this.patchXHR()}stop(){if(!this.started)return;if(this.originalFetch)window.fetch=this.originalFetch,this.originalFetch=null;if(this.originalXHROpen)XMLHttpRequest.prototype.open=this.originalXHROpen,this.originalXHROpen=null;if(this.originalXHRSend)XMLHttpRequest.prototype.send=this.originalXHRSend,this.originalXHRSend=null;if(this.originalXHRSetRequestHeader)XMLHttpRequest.prototype.setRequestHeader=this.originalXHRSetRequestHeader,this.originalXHRSetRequestHeader=null;this.started=!1}isSameOrigin(Q){try{let X;if(Q instanceof Request)X=new URL(Q.url,window.location.origin);else if(Q instanceof URL)X=Q;else X=new URL(Q,window.location.origin);return X.origin===window.location.origin}catch{return!0}}patchFetch(){this.originalFetch=window.fetch.bind(window);let Q=this,X=this.config.name||P.name;window.fetch=function(Y,Z){if(!Q.isSameOrigin(Y))return Q.originalFetch(Y,Z);let $=Q.sessionIdGetter();if(!$)return Q.originalFetch(Y,Z);let J=new Headers(Z?.headers);if(!J.has(X))J.set(X,$);return Q.originalFetch(Y,{...Z,headers:J})}}patchXHR(){this.originalXHROpen=XMLHttpRequest.prototype.open,this.originalXHRSend=XMLHttpRequest.prototype.send,this.originalXHRSetRequestHeader=XMLHttpRequest.prototype.setRequestHeader;let Q=this,X=this.config.name||P.name;XMLHttpRequest.prototype.open=function(Y,Z,$=!0,J,z){let W=Q.isSameOrigin(Z);return Q.xhrInjectionMap.set(this,W),Q.originalXHROpen.call(this,Y,Z,$,J,z)},XMLHttpRequest.prototype.send=function(Y){if(Q.xhrInjectionMap.get(this)){let Z=Q.sessionIdGetter();if(Z)try{Q.originalXHRSetRequestHeader.call(this,X,Z)}catch{}}return Q.originalXHRSend.call(this,Y)}}getHeaderName(){return this.config.name||P.name}isStarted(){return this.started}}var _={selector:"form",inputName:"_bsid"};function p(Q){if(!Q)return null;if(Q===!0)return{..._};return{..._,...Q}}class I{config;sessionIdGetter;observer=null;started=!1;constructor(Q,X){this.config={..._,...Q},this.sessionIdGetter=X}start(){if(this.started)return;this.started=!0;let Q=()=>{this.setupExistingForms(),this.setupObserver()};if(document.readyState==="loading")document.addEventListener("DOMContentLoaded",Q,{once:!0});else Q()}stop(){if(!this.started)return;if(this.observer)this.observer.disconnect(),this.observer=null;let Q=this.config.selector||_.selector,X=this.config.inputName||_.inputName;document.querySelectorAll(`${Q}[data-bs-inject-setup]`).forEach((Y)=>{if(Y instanceof HTMLFormElement)Y.removeEventListener("submit",this.handleSubmit,{capture:!0});Y.removeAttribute("data-bs-inject-setup");let Z=Y.querySelector(`input[name="${X}"][data-bs-injected]`);if(Z)Z.remove()}),this.started=!1}setupExistingForms(){let Q=this.config.selector||_.selector;document.querySelectorAll(Q).forEach((X)=>{if(X instanceof HTMLFormElement)this.setupForm(X)})}setupObserver(){if(!document.body)return;let Q=this.config.selector||_.selector;this.observer=new MutationObserver((X)=>{X.forEach((Y)=>{Y.addedNodes.forEach((Z)=>{if(Z instanceof HTMLFormElement&&Z.matches(Q))this.setupForm(Z);if(Z instanceof HTMLElement)Z.querySelectorAll(Q).forEach(($)=>{if($ instanceof HTMLFormElement)this.setupForm($)})})})}),this.observer.observe(document.body,{childList:!0,subtree:!0})}setupForm(Q){if(Q.hasAttribute("data-bs-inject-setup"))return;Q.setAttribute("data-bs-inject-setup","true"),Q.addEventListener("submit",this.handleSubmit,{capture:!0})}handleSubmit=(Q)=>{let X=Q.currentTarget;this.injectInput(X)};injectInput(Q){let X=this.config.inputName||_.inputName,Y=Q.querySelector(`input[name="${X}"]`);if(Y){if(Y.hasAttribute("data-bs-injected"))Y.value=this.sessionIdGetter();return}let Z=document.createElement("input");Z.type="hidden",Z.name=X,Z.value=this.sessionIdGetter(),Z.setAttribute("data-bs-injected","true"),Q.appendChild(Z)}getConfig(){return{...this.config}}isStarted(){return this.started}}async function kQ(){return await import("./hash-q46pgar4.js")}class S{config;mouseCollector;scrollCollector;formCollector;browserCollector;fingerprintGenerator;socket=null;sessionId;sequenceNumber=0;isRunning=!1;sendTimer=null;fingerprint=null;browserSignal=null;lastScore=null;hasSentInitial=!1;boundBeforeUnload=null;boundVisibilityChange=null;hashModule=null;formBlocked=!1;formObserver=null;highScoreTriggeredLevels=new Set;challengeManager=null;challengeManagerPromise=null;formProtectionManager=null;formSubmissionStatus="no_submission";cookieManager=null;headerInjector=null;formInjector=null;serverConfig=null;connectionState="disconnected";reconnectTimer=null;readyPromise;readyResolver=null;constructor(Q){if(K.markConstructorStart(),!Q.apiKey)throw Error("BotSigged: apiKey is required");if(this.config=h(Q),this.sessionId=this.generateSessionId(),this.readyPromise=new Promise(($)=>{this.readyResolver=$}),this.mouseCollector=new k({sampleRate:this.config.mouseSampleRate,maxBufferSize:this.config.maxBufferSize}),this.scrollCollector=new x({maxBufferSize:Math.floor(this.config.maxBufferSize/3)}),this.formCollector=new C({maxKeyEvents:this.config.maxBufferSize,onSubmit:()=>this.handleFormSubmit()}),this.browserCollector=new L,this.fingerprintGenerator=new b,this.config.hashVerification.enabled)this.initializeHashModule();if(this.config.action==="challenge"||this.config.challenge.enabled)this.challengeManagerPromise=this.initializeChallengeManager();if(this.config.formProtection.mode!=="none")this.formProtectionManager=new D({mode:this.config.formProtection.mode,minTimeBeforeSubmit:this.config.formProtection.minTimeBeforeSubmit,maxHoldTime:this.config.formProtection.maxHoldTime,showLoadingUI:this.config.formProtection.showLoadingUI,loadingMessage:this.config.formProtection.loadingMessage,onHold:($)=>{this.updateFormStatus("challenged"),this.config.formProtection.onHold?.($)},onRelease:($,J)=>{if(!J)this.updateFormStatus("completed");this.config.formProtection.onRelease?.($,J)},onBlock:($,J)=>{this.updateFormStatus("blocked"),this.config.formProtection.onBlock?.($,J)},flushAndWaitForScore:()=>this.sendSignalAndGetScore()}),this.log("Form protection enabled:",this.config.formProtection.mode);else this.log("Form protection disabled (mode='none')");let X=d(this.config.cookie);if(X)this.cookieManager=new M(X,()=>this.sessionId),this.log("Cookie manager enabled:",X.name);let Y=m(this.config.headers);if(Y)this.headerInjector=new E(Y,()=>this.sessionId),this.headerInjector.start(),this.log("Header injector enabled:",Y.name);let Z=p(this.config.formInject);if(Z)this.formInjector=new I(Z,()=>this.sessionId),this.formInjector.start(),this.log("Form injector enabled:",Z.inputName);if(this.config.autoStart)if(document.readyState==="loading")document.addEventListener("DOMContentLoaded",()=>this.start());else this.start();K.markConstructorEnd(),this.log("Constructor completed in",(K.getTimings().constructorEnd??0)-(K.getTimings().constructorStart??0),"ms")}async initializeHashModule(){try{let{initHashModule:Q}=await import("./hash-q46pgar4.js");this.hashModule=await Q({preferWasm:this.config.hashVerification.preferWasm,onWasmLoaded:()=>{this.log("WASM hash module loaded"),this.config.hashVerification.onWasmLoaded?.()},onFallback:(X)=>{this.log("Using JS hash fallback:",X),this.config.hashVerification.onWasmFallback?.(X)}})}catch(Q){this.log("Failed to initialize hash module",Q)}}async initializeChallengeManager(){try{let{ChallengeManager:Q}=await import("./challenge-8yg1wp51.js");this.challengeManager=new Q(this.config.challenge,this.config.debug),this.log("Challenge manager loaded")}catch(Q){this.log("Failed to initialize challenge manager",Q)}}async start(){if(this.isRunning){this.log("Already running");return}K.markStartCalled(),this.log("Starting BotSigged SDK"),this.isRunning=!0,this.connectionState="connecting";try{this.browserSignal=this.browserCollector.collect(),K.markFormCollectorStart(),this.mouseCollector.start(),this.scrollCollector.start(),this.formCollector.start(),K.markFormCollectorReady(),this.log("Collectors started in",(K.getTimings().formCollectorReady??0)-(K.getTimings().formCollectorStart??0),"ms"),K.markFingerprintStart(),K.markWsConnectStart();let[Q]=await Promise.all([this.fingerprintGenerator.generate(),this.connectWithRetry()]);this.fingerprint=Q,K.markFingerprintEnd(),this.log("Fingerprint generated in",(K.getTimings().fingerprintEnd??0)-(K.getTimings().fingerprintStart??0),"ms"),await this.joinChannel(),this.connectionState="connected",this.readyResolver?.(),K.markSdkReady(),this.startSendInterval(),this.registerBeforeUnload();let X=K.getSummary();if(this.log("SDK started successfully"),this.log("Total startup time:",X.totalStartupMs,"ms"),this.log("Time to first score:",X.timeToFirstScoreMs,"ms"),this.log("Vulnerability window:",X.vulnerabilityWindowMs,"ms"),this.config.debug)K.logSummary()}catch(Q){let X=Q instanceof Error?Q:Error(String(Q));this.log("Failed to start",X),this.handleConnectionFailure(X)}}async stop(){if(!this.isRunning)return;if(this.log("Stopping BotSigged SDK"),this.formProtectionManager)this.formProtectionManager.destroy(),this.formProtectionManager=null;if(this.cookieManager)this.cookieManager.removeCookies(),this.cookieManager=null;if(this.headerInjector)this.headerInjector.stop(),this.headerInjector=null;if(this.formInjector)this.formInjector.stop(),this.formInjector=null;if(this.formObserver)this.formObserver.disconnect(),this.formObserver=null;this.unregisterBeforeUnload(),this.mouseCollector.stop(),this.scrollCollector.stop(),this.formCollector.stop(),this.stopSendInterval(),await this.sendSignal(),await this.disconnect(),this.isRunning=!1,this.log("SDK stopped")}async sendSignal(){if(!this.socket?.isReady()){this.log("Cannot send signal: not connected");return}let Q=this.buildPayload(),X=Q.seq;this.log("Sending signal seq:",X),K.markSignalSent(X);try{let Y=await this.socket.sendSignal(Q);K.markSignalResponseReceived(X);let Z=K.getTimings().signalRoundtrips||[],$=Z[Z.length-1];if($)this.log("Signal roundtrip:",$.roundtripMs,"ms");if(Y.bot_score!==void 0){let J={bot_score:Y.bot_score,classification:Y.classification||"unknown",triggered_rules:Y.triggered_rules||[]};this.lastScore=J,this.config.onScoreUpdate?.(J),this.handleScoreUpdate(J)}this.mouseCollector.flush(),this.scrollCollector.flush(),this.formCollector.flush(),this.hasSentInitial=!0}catch(Y){let Z=Y instanceof Error?Y:Error(String(Y));this.log("Failed to send signal",Z),this.config.onError?.(Z)}}async sendSignalAndGetScore(){if(!this.socket?.isReady())return this.log("Cannot send signal: not connected"),null;let Q=this.buildPayload(),X=Q.seq;this.log("Sending signal for form scoring, seq:",X);try{let Y=await this.socket.sendSignal(Q);if(Y.bot_score!==void 0){let Z={bot_score:Y.bot_score,classification:Y.classification||"unknown",triggered_rules:Y.triggered_rules||[]};return this.lastScore=Z,this.config.onScoreUpdate?.(Z),this.handleScoreUpdate(Z),this.mouseCollector.flush(),this.scrollCollector.flush(),this.formCollector.flush(),this.hasSentInitial=!0,Z.bot_score}return this.mouseCollector.flush(),this.scrollCollector.flush(),this.formCollector.flush(),this.hasSentInitial=!0,null}catch(Y){let Z=Y instanceof Error?Y:Error(String(Y));return this.log("Failed to send signal for form scoring",Z),this.config.onError?.(Z),null}}getSessionId(){return this.sessionId}getFingerprint(){return this.fingerprint}getFormSubmissionStatus(){return this.formSubmissionStatus}getLastScore(){return this.lastScore}isConnected(){return this.socket?.isReady()??!1}whenReady(){if(this.connectionState==="connected")return Promise.resolve();return this.readyPromise}getConnectionState(){return this.connectionState}getServerConfig(){return this.serverConfig}async identify(Q){let{accountId:X}=Q;if(!X||typeof X!=="string")throw Error("BotSigged: accountId is required and must be a string");if(X.length>255)throw Error("BotSigged: accountId must be 255 characters or less");this.log("Identifying account:",X),await this.whenReady();try{let Y=await this.socket.sendEvent("identify",{account_id:X,timestamp:Date.now()});if(Y.identified)this.log("Account identified successfully");else throw Error(Y.reason?.toString()||"Failed to identify account")}catch(Y){let Z=Y instanceof Error?Y:Error(String(Y));throw this.log("Failed to identify account:",Z),this.config.onError?.(Z),Z}}isDegraded(){return this.connectionState==="degraded"||this.connectionState==="failed"}getCurrentSignals(){return{mouse:this.mouseCollector.getSignal(),scroll:this.scrollCollector.getSignal(),form:this.formCollector.getSignal(),browser:this.browserSignal}}getBufferSizes(){return{mouse:this.mouseCollector.getBufferSize(),scroll:this.scrollCollector.getBufferSize(),form:this.formCollector.getBufferSize()}}resetSignals(){this.mouseCollector.reset(),this.scrollCollector.reset(),this.formCollector.reset(),this.browserCollector.reset(),this.sequenceNumber=0,this.hasSentInitial=!1}async connectSocket(){this.socket=new A({endpoint:this.config.endpoint,apiKey:this.config.apiKey,debug:this.config.debug,onConnectionChange:(Q)=>{this.config.onConnectionChange?.(Q==="connected")},onError:(Q)=>{this.config.onError?.(Q)}}),await this.socket.connect(),K.markWsConnectEnd(),this.log("WebSocket connected in",(K.getTimings().wsConnectEnd??0)-(K.getTimings().wsConnectStart??0),"ms")}async connectWithRetry(){let X=[1000,2000,4000];for(let Y=0;Y<3;Y++)try{await this.connectSocket();return}catch(Z){if(this.log(`Connection attempt ${Y+1} failed:`,Z),Y<2)await this.sleep(X[Y]);else throw Z}}sleep(Q){return new Promise((X)=>setTimeout(X,Q))}handleConnectionFailure(Q){this.connectionState="failed";let X=this.config.fallbackMode||"degraded";switch(this.log("Connection failed, applying fallback mode:",X),X){case"open":if(this.connectionState="degraded",this.formProtectionManager)this.formProtectionManager.setMode("none"),this.formProtectionManager.notifyReady(0);break;case"closed":this.blockFormsUntilConnected(),this.scheduleReconnect();break;case"cached":let Y=this.loadCachedConfig();if(Y)this.applyServerConfig(Y),this.connectionState="degraded";else this.applyFallbackConfig();this.scheduleReconnect();break;case"degraded":default:this.applyFallbackConfig(),this.connectionState="degraded",this.scheduleReconnect();break}this.config.onError?.(Q),this.config.onConnectionChange?.(!1)}applyFallbackConfig(){if(this.log("Applying fallback config"),this.serverConfig=F,this.formProtectionManager&&this.serverConfig.form_protection_mode)this.formProtectionManager.setMode(this.serverConfig.form_protection_mode);this.config.onServerConfig?.(this.serverConfig,"fallback")}blockFormsUntilConnected(){if(this.formProtectionManager)this.formProtectionManager.setMode("holdUntilReady"),this.formProtectionManager.setMaxHoldTime(30000)}scheduleReconnect(){if(this.reconnectTimer)clearTimeout(this.reconnectTimer);this.reconnectTimer=setTimeout(()=>{this.attemptReconnect()},5000)}async attemptReconnect(){this.log("Attempting reconnection..."),this.connectionState="connecting";try{if(await this.connectWithRetry(),!this.fingerprint)this.fingerprint=await this.fingerprintGenerator.generate();if(await this.joinChannel(),this.connectionState="connected",this.readyResolver?.(),this.log("Reconnection successful"),!this.sendTimer)this.startSendInterval()}catch(Q){this.log("Reconnection failed:",Q),this.connectionState="failed"}}cacheServerConfig(Q){try{localStorage.setItem(`botsigged_config_${this.config.apiKey}`,JSON.stringify({config:Q,timestamp:Date.now()}))}catch{}}loadCachedConfig(){try{let Q=localStorage.getItem(`botsigged_config_${this.config.apiKey}`);if(!Q)return null;let{config:X,timestamp:Y}=JSON.parse(Q);if(Date.now()-Y>86400000)return localStorage.removeItem(`botsigged_config_${this.config.apiKey}`),null;return X}catch{return null}}applyServerConfig(Q){if(this.log("Applying server config:",Q),this.serverConfig=Q,this.formProtectionManager&&Q.form_protection_mode)this.formProtectionManager.setMode(Q.form_protection_mode);if(Q.action&&Q.action!=="none")this.applyServerAction(Q.action,Q.challenge);this.cacheServerConfig(Q),this.config.onServerConfig?.(Q,"server")}async applyServerAction(Q,X){switch(this.log("Applying server action:",Q),Q){case"block":if(this.updateFormStatus("blocked"),!this.formBlocked)this.blockForms();break;case"challenge":if(this.updateFormStatus("challenged"),!this.challengeManager&&!this.challengeManagerPromise)this.log("Lazily loading challenge manager for server-requested challenge"),this.challengeManagerPromise=this.initializeChallengeManager();if(this.challengeManagerPromise)await this.challengeManagerPromise;if(this.challengeManager){let Y=X?.difficulty?.bot??16,Z=Y>=18?"critical":Y>=16?"high":"medium";this.challengeManager.blockFormsUntilSolved(Z)}else this.log("Challenge requested but challenge manager failed to load");break;case"flag":this.updateFormStatus("flagged"),this.log("Session flagged by server");break;case"none":default:break}}handleServerAction(Q){this.log("Received server action:",Q),this.config.onServerAction?.(Q);let X=Q.challenge?{difficulty:{suspicious:Q.challenge.difficulty,bot:Q.challenge.difficulty},timeout_ms:Q.challenge.timeout_ms}:void 0;this.applyServerAction(Q.type,X)}async joinChannel(){if(!this.socket)throw Error("WebSocket not initialized");K.markChannelJoinStart();let Q;try{Q=await this.socket.joinChannel(this.sessionId,this.fingerprint,this.getSessionData(),this.browserSignal,{onScoreUpdate:(X)=>{this.lastScore=X,this.config.onScoreUpdate?.(X),this.handleScoreUpdate(X)},onError:(X)=>{this.config.onError?.(X)},onAction:(X)=>{this.handleServerAction(X)}},this.config.accountId)}catch(X){if(T(X)){if(this.log("Usage limit exceeded:",X),this.config.onUsageLimitExceeded)this.config.onUsageLimitExceeded(X);else this.config.onError?.(Error(`Usage limit exceeded: ${X.current_usage}/${X.limit} verifications (${X.plan_name} plan). Please upgrade your plan.`));return}throw X}if(K.markChannelJoinEnd(),this.log("Channel joined in",(K.getTimings().channelJoinEnd??0)-(K.getTimings().channelJoinStart??0),"ms"),Q.config){let X=Q.config;this.applyServerConfig(X)}if(Q.initial_score!==void 0){K.markInitialScoreReceived();let X={bot_score:Q.initial_score,classification:Q.classification||"unknown",triggered_rules:Q.triggered_rules||[]};if(this.lastScore=X,this.config.onScoreUpdate?.(X),this.handleScoreUpdate(X),this.formProtectionManager)this.formProtectionManager.notifyReady(X.bot_score);if(this.cookieManager)this.cookieManager.setCookie();this.log("Initial score received:",X.bot_score,"in",(K.getTimings().initialScoreReceived??0)-(K.getTimings().startCalled??0),"ms from start")}}handleScoreUpdate(Q){if(this.cookieManager)this.cookieManager.updateRiskTier(Q.bot_score);let X=this.getBotScoreLevel(Q.bot_score),Y=Q.bot_score>=this.config.actionThreshold;if(this.shouldTriggerAlert(X)){let Z={score:Q.bot_score,level:X,scoreUpdate:Q,sessionId:this.sessionId,fingerprintHash:this.fingerprint?.hash};if(Y&&!this.highScoreTriggeredLevels.has(X))this.executeAction(Z);this.config.onHighBotScore?.(Z),this.highScoreTriggeredLevels.add(X)}}getBotScoreLevel(Q){let X=this.config.botScoreThresholds;if(Q>=X.critical)return"critical";if(Q>=X.high)return"high";if(Q>=X.medium)return"medium";return"low"}shouldTriggerAlert(Q){if(this.highScoreTriggeredLevels.has(Q))return!1;let X=["low","medium","high","critical"],Y=this.config.minAlertLevel,Z=X.indexOf(Q),$=X.indexOf(Y);return Z>=$}async executeAction(Q){let X=this.config.action;switch(this.log(`Executing action '${X}' for score ${Q.score}`),X){case"challenge":if(this.challengeManagerPromise)await this.challengeManagerPromise;if(this.challengeManager)this.challengeManager.blockFormsUntilSolved(Q.level);break;case"block":if(!this.formBlocked)this.blockForms();break;case"none":default:break}}blockForms(){if(this.formBlocked)return;this.formBlocked=!0,document.querySelectorAll("form").forEach((Q)=>{Q.addEventListener("submit",this.blockFormSubmit,!0)}),this.formObserver=new MutationObserver((Q)=>{Q.forEach((X)=>{X.addedNodes.forEach((Y)=>{if(Y instanceof HTMLFormElement)Y.addEventListener("submit",this.blockFormSubmit,!0);if(Y instanceof HTMLElement)Y.querySelectorAll("form").forEach((Z)=>{Z.addEventListener("submit",this.blockFormSubmit,!0)})})})}),this.formObserver.observe(document.body,{childList:!0,subtree:!0}),this.log("Forms blocked due to high bot score")}blockFormSubmit=(Q)=>{Q.preventDefault(),Q.stopPropagation(),this.log("Form submission blocked due to high bot score");return};isFormsBlocked(){return this.formBlocked}unblockForms(){if(!this.formBlocked)return;if(this.formObserver)this.formObserver.disconnect(),this.formObserver=null;document.querySelectorAll("form").forEach((Q)=>{Q.removeEventListener("submit",this.blockFormSubmit,!0)}),this.formBlocked=!1,this.log("Forms unblocked")}getHashModule(){return this.hashModule}createSignature(Q){let X=this.config.hashVerification.secret;if(!X)return this.log("Cannot create signature: no secret configured"),null;return createSignature(Q,X)}verifySignature(Q,X){let Y=this.config.hashVerification.secret;if(!Y)return this.log("Cannot verify signature: no secret configured"),!1;return verifySignature(Q,X,Y)}isChallengeSolving(){return this.challengeManager?.isSolving()??!1}isChallengeSolved(){return this.challengeManager?.isSolved()??!1}getPerformanceSummary(){return K.getSummary()}logPerformance(){K.logSummary()}getPerformanceReport(){return K.getReport()}async waitUntilReady(){if(this.lastScore)return{score:this.lastScore.bot_score,timedOut:!1};if(this.formProtectionManager)return this.formProtectionManager.waitUntilReady();return new Promise((Q)=>{let X=performance.now(),Y=5000,Z=()=>{if(this.lastScore){Q({score:this.lastScore.bot_score,timedOut:!1});return}if(performance.now()-X>=5000){Q({score:null,timedOut:!0});return}setTimeout(Z,50)};Z()})}withProtection(Q,X={}){let Y=X.blockThreshold??this.config.actionThreshold;return async(...Z)=>{let{score:$,timedOut:J}=await this.waitUntilReady();if(K.markFirstSubmitAttempt($!==null),$!==null&&$>=Y)throw this.log(`Blocking submission: score ${$} >= threshold ${Y}`),Error(`Submission blocked: bot score ${$} exceeds threshold`);if(J)this.log("Warning: submitting without detection score (timed out)");return Q(...Z)}}protectedFetch(Q={}){return this.withProtection(async(X,Y)=>{return fetch(X,Y)},Q)}canSubmit(){if(!this.lastScore)return{allowed:!1,reason:"waiting_for_score",score:null};if(this.lastScore.bot_score>=this.config.actionThreshold)return{allowed:!1,reason:"high_bot_score",score:this.lastScore.bot_score};return{allowed:!0,score:this.lastScore.bot_score}}async triggerChallenge(Q="high"){if(this.challengeManagerPromise)await this.challengeManagerPromise;if(!this.challengeManager){this.log("Challenge not enabled");return}this.challengeManager.blockFormsUntilSolved(Q)}async disconnect(){if(this.socket)await this.socket.leaveChannel(),this.socket.disconnect(),this.socket=null}startSendInterval(){this.stopSendInterval(),this.sendTimer=setInterval(()=>{this.sendSignal()},this.config.sendInterval)}stopSendInterval(){if(this.sendTimer)clearInterval(this.sendTimer),this.sendTimer=null}registerBeforeUnload(){this.boundBeforeUnload=()=>{this.handleBeforeUnload()},this.boundVisibilityChange=()=>{if(document.visibilityState==="hidden")this.handleBeforeUnload()},window.addEventListener("beforeunload",this.boundBeforeUnload),document.addEventListener("visibilitychange",this.boundVisibilityChange)}unregisterBeforeUnload(){if(this.boundBeforeUnload)window.removeEventListener("beforeunload",this.boundBeforeUnload),this.boundBeforeUnload=null;if(this.boundVisibilityChange)document.removeEventListener("visibilitychange",this.boundVisibilityChange),this.boundVisibilityChange=null}handleBeforeUnload(){if(!this.isRunning||!this.socket)return;try{let Q=this.buildPayload();if(this.socket.isReady())this.socket.sendSignal(Q).catch(()=>{})}catch{}}handleFormSubmit(){if(!this.isRunning)return;if(K.markFirstSubmitAttempt(this.lastScore!==null),this.log("Form submitted, flushing signals via beacon"),this.log("Had score before submit:",this.lastScore!==null),this.updateFormStatus("completed"),!this.sessionId){this.log("No session ID yet, cannot send beacon");return}let Q=this.buildPayload();if(!this.sendViaBeacon(Q))this.sendSignal().catch((Y)=>{this.log("Failed to flush signals on form submit",Y)});else this.mouseCollector.flush(),this.scrollCollector.flush(),this.formCollector.flush()}sendViaBeacon(Q){if(!navigator.sendBeacon)return this.log("sendBeacon not available"),!1;try{let X=new URL(this.config.endpoint),Y=`${X.protocol==="wss:"?"https:":"http:"}//${X.host}/api/signal`,Z=JSON.stringify({session_id:this.sessionId,api_key:this.config.apiKey,payload:Q,form_status:this.formSubmissionStatus}),$=new Blob([Z],{type:"application/json"}),J=navigator.sendBeacon(Y,$);return this.log("Beacon sent:",J),J}catch(X){return this.log("Beacon send failed:",X),!1}}buildPayload(){this.sequenceNumber++;let Q={session_id:this.sessionId,seq:this.sequenceNumber,mouse:this.mouseCollector.getSignal(),scroll:this.scrollCollector.getSignal(),form:this.formCollector.getSignal(),timestamp:Date.now()};if(!this.hasSentInitial)Q.session=this.getSessionData(),Q.fingerprint=this.fingerprint,Q.browser=this.browserSignal;return Q}getSessionData(){let Q=new URL(window.location.href),X={};Q.searchParams.forEach((Z,$)=>{X[$]=Z});let Y=null;if(document.referrer)try{Y=new URL(document.referrer).hostname}catch{}return{url_path:Q.pathname,url_params:X,referrer_url:document.referrer||null,referrer_domain:Y,user_agent:navigator.userAgent}}generateSessionId(){if(crypto.randomUUID)return crypto.randomUUID();return"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,(Q)=>{let X=Math.random()*16|0;return(Q==="x"?X:X&3|8).toString(16)})}updateFormStatus(Q){if(this.formSubmissionStatus==="challenged"||this.formSubmissionStatus==="flagged"||this.formSubmissionStatus==="blocked"||this.formSubmissionStatus==="completed"){this.log(`Form status already terminal (${this.formSubmissionStatus}), ignoring ${Q}`);return}if(this.formSubmissionStatus=Q,this.log(`Form status updated to: ${Q}`),this.socket?.isReady())this.socket.sendFormStatus(Q).catch((X)=>{this.log("Failed to send form status:",X)})}log(...Q){if(this.config.debug);}}var O=null;function xQ(Q){if(O)return O;return O=new S(Q),O}function CQ(){return O}async function LQ(){if(O)await O.stop(),O=null}var AQ=S;export{f as logPerformanceSummary,kQ as loadHashModule,T as isUsageLimitError,xQ as init,l as getPerformanceSummary,N as getPerformanceMetrics,CQ as getInstance,LQ as destroy,AQ as default,q as DEFAULT_CONFIG,S as BotSigged};
|
|
41
41
|
|
|
42
|
-
//# debugId=
|
|
42
|
+
//# debugId=1DB83A96804B237464756E2164756E21
|