UNPKG

altcha

Version:

Privacy-first CAPTCHA widget, compliant with global regulations (GDPR/HIPAA/CCPA/LGDP/DPDPA/PIPL) and WCAG accessible. No tracking, self-verifying.

2 lines (1 loc) 4.38 kB
(function(e,i){typeof exports=="object"&&typeof module<"u"?i(exports):typeof define=="function"&&define.amd?define(["exports"],i):(e=typeof globalThis<"u"?globalThis:e||self,i(e["[name]"]={}))})(this,function(e){"use strict";var N=Object.defineProperty;var A=e=>{throw TypeError(e)};var S=(e,i,o)=>i in e?N(e,i,{enumerable:!0,configurable:!0,writable:!0,value:o}):e[i]=o;var c=(e,i,o)=>S(e,typeof i!="symbol"?i+"":i,o),y=(e,i,o)=>i.has(e)||A("Cannot "+o);var s=(e,i,o)=>(y(e,i,"read from private field"),o?o.call(e):i.get(e)),l=(e,i,o)=>i.has(e)?A("Cannot add the same private member more than once"):i instanceof WeakSet?i.add(e):i.set(e,o),v=(e,i,o,d)=>(y(e,i,"write to private field"),d?d.call(e,o):i.set(e,o),o),w=(e,i,o)=>(y(e,i,"access private method"),o);var a,h,b,F,C,m,g,f,T,p;new TextEncoder;function i(){try{return Intl.DateTimeFormat().resolvedOptions().timeZone}catch{}}class o{constructor(t){this.context=t}static register(t){typeof globalThis.altchaPlugins!="object"&&(globalThis.altchaPlugins=[]),globalThis.altchaPlugins.includes(t)||globalThis.altchaPlugins.push(t)}destroy(){}onErrorChange(t){}onStateChange(t){}}c(o,"pluginName");class d extends o{constructor(n){super(n);l(this,F);l(this,a);l(this,h);l(this,b,w(this,F,C).bind(this));if(v(this,a,this.context.el.closest("form")),s(this,a)){let r=s(this,a).getAttribute("data-beacon-url");const u=s(this,a).getAttribute("action");!r&&u&&(r=u+"/beacon"),s(this,a).addEventListener("submit",s(this,b)),v(this,h,new L(s(this,a),r))}}destroy(){var n,r;(n=s(this,a))==null||n.removeEventListener("submit",s(this,b)),(r=s(this,h))==null||r.destroy()}onErrorChange(n){var r;(r=s(this,h))==null||r.trackError(n)}}a=new WeakMap,h=new WeakMap,b=new WeakMap,F=new WeakSet,C=function(){var n;if(s(this,h)&&!s(this,h).submitTime){s(this,h).end();const r=s(this,h).dataAsBase64();this.context.dispatch("session",r);const u=document.createElement("input");u.type="hidden",u.name="__session",u.value=r,(n=s(this,a))==null||n.appendChild(u)}},c(d,"pluginName","analytics");class L{constructor(t,n=null){c(this,"error",null);c(this,"loadTime",Date.now());c(this,"submitTime",null);c(this,"startTime",null);c(this,"viewTimeThresholdMs",1500);l(this,m,{});l(this,g,null);l(this,f,this.onFormChange.bind(this));l(this,T,this.onFormFocus.bind(this));l(this,p,this.onUnload.bind(this));this.elForm=t,this.beaconUrl=n,window.addEventListener("unload",s(this,p)),this.elForm.addEventListener("change",s(this,f)),this.elForm.addEventListener("focusin",s(this,T))}data(){const t=Object.entries(s(this,m));return{correction:t.length&&t.filter(([n,r])=>r>1).length/t.length||0,dropoff:!this.submitTime&&!this.error&&s(this,g)?s(this,g):null,error:this.error,mobile:this.isMobile(),start:this.startTime,submit:this.submitTime,tz:i()}}dataAsBase64(){try{return btoa(JSON.stringify(this.data()))}catch(t){console.error("failed to encode ALTCHA session data to base64",t)}return""}destroy(){window.removeEventListener("unload",s(this,p)),this.elForm.removeEventListener("change",s(this,f)),this.elForm.removeEventListener("focusin",s(this,T))}end(){this.submitTime||(this.submitTime=Date.now())}getFieldName(t,n=40){const r=t.getAttribute("data-group-label"),u=t.getAttribute("name")||t.getAttribute("aria-label");return((r?r+": ":"")+u).slice(0,n)}isMobile(){const t="userAgentData"in navigator&&navigator.userAgentData?navigator.userAgentData:{};return"mobile"in t?t.mobile===!0:/Mobi/i.test(window.navigator.userAgent)}isInput(t){return["INPUT","SELECT","TEXTAREA"].includes(t.tagName)}onFormFieldChange(t){const n=this.getFieldName(t);n&&this.trackFieldChange(n)}onFormChange(t){const n=t.target;n&&this.isInput(n)&&this.onFormFieldChange(n)}onFormFocus(t){const n=t.target;if(this.startTime||this.start(),n&&this.isInput(n)){const r=this.getFieldName(n);r&&v(this,g,r)}}onUnload(){this.loadTime<=Date.now()-this.viewTimeThresholdMs&&!this.submitTime&&this.sendBeacon()}async sendBeacon(){if(this.beaconUrl&&"sendBeacon"in navigator)try{navigator.sendBeacon(new URL(this.beaconUrl,location.origin),JSON.stringify(this.data()))}catch{}}start(){this.startTime=Date.now()}trackError(t){this.error=t===null?null:String(t)}trackFieldChange(t){s(this,m)[t]=(s(this,m)[t]||0)+1}}m=new WeakMap,g=new WeakMap,f=new WeakMap,T=new WeakMap,p=new WeakMap,o.register(d),e.PluginAnalytics=d,Object.defineProperty(e,Symbol.toStringTag,{value:"Module"})});