"use strict";(()=>{function f(t){return typeof Symbol=="function"&&typeof Symbol.iterator=="symbol"?f=function(e){return typeof e}:f=function(e){return e&&typeof Symbol=="function"&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},f(t)}var j=function(e){return typeof e=="string"},$=function(e){return e instanceof Blob};W.call((typeof window>"u"?"undefined":f(window))==="object"?window:void 0);function W(){V.call(this)||("navigator"in this||(this.navigator={}),this.navigator.sendBeacon=G.bind(this))}function G(t,e){var r=this.event&&this.event.type,i=r==="unload"||r==="beforeunload",n="XMLHttpRequest"in this?new XMLHttpRequest:new ActiveXObject("Microsoft.XMLHTTP");n.open("POST",t,!i),n.withCredentials=!0,n.setRequestHeader("Accept","*/*"),j(e)?(n.setRequestHeader("Content-Type","text/plain;charset=UTF-8"),n.responseType="text/plain"):$(e)&&e.type&&n.setRequestHeader("Content-Type",e.type);try{n.send(e)}catch{return!1}return!0}function V(){return"navigator"in this&&"sendBeacon"in this.navigator}var D=["CompleteRegistration","Login","ViewContent","AddToCart","Purchase","Lead","SubmitApplication","Install"];function I(t){return t.type==="click"}function x(t){return t.type==="url"}function g(t){return typeof t=="object"&&t!==null&&!Array.isArray(t)}function X(t){return typeof t=="string"&&D.includes(t)}function z(t){if(!g(t)||typeof t.selector!="string"||t.selector.length===0)return null;let e={selector:t.selector};if(t.elementText!==void 0){if(typeof t.elementText!="string")return null;e.elementText=t.elementText}if(t.tagName!==void 0){if(typeof t.tagName!="string")return null;e.tagName=t.tagName}if(t.pathExact!==void 0){if(typeof t.pathExact!="string"||t.pathExact.length===0||t.pathExact.length>2048||!t.pathExact.startsWith("/")||t.pathExact.includes("?")||t.pathExact.includes("#")||t.pathExact.includes("%2F")||t.pathExact.includes("%2f"))return null;e.pathExact=t.pathExact}return e}function Q(t){if(!g(t))return null;if(t.type==="click"){let e=z(t.selector);return e?{type:"click",selector:e}:null}return t.type==="url"?!g(t.pattern)||t.pattern.type!=="contains"||typeof t.pattern.value!="string"?null:{type:"url",pattern:{type:"contains",value:t.pattern.value}}:null}function J(t){if(!g(t)||typeof t.id!="string"||t.id.length===0||!X(t.eventName))return null;let e=Q(t.trigger);return e?{id:t.id,eventName:t.eventName,trigger:e}:null}function Y(t){if(!g(t)||typeof t.url!="string"||t.url.length===0||!Array.isArray(t.rules))return null;let e=[];for(let r of t.rules){let i=J(r);if(!i){console.warn("[karrot-pixel] event-builder: skipping invalid rule",r);continue}e.push(i)}return{url:t.url,rules:e}}function L(t){if(!g(t))return null;t.schemaVersion!==1&&console.warn(`[karrot-pixel] event-builder config: schemaVersion=${JSON.stringify(t.schemaVersion)} is not supported by this SDK version, proceeding anyway`);let e;if(typeof t.pixelId=="string"){if(t.pixelId.length===0)return null;e=t.pixelId}else if(typeof t.pixelId=="number"&&Number.isFinite(t.pixelId))e=String(t.pixelId);else return null;if(!Array.isArray(t.websiteRuleSets))return null;let r=[];for(let i of t.websiteRuleSets){let n=Y(i);if(!n){console.warn("[karrot-pixel] event-builder: skipping invalid websiteRuleSet",i);continue}r.push(n)}return{schemaVersion:typeof t.schemaVersion=="number"?t.schemaVersion:1,pixelId:e,websiteRuleSets:r}}var N=["a","button","[role='button']","[role='link']","input[type='submit']","input[type='button']","input[type='image']","summary","[tabindex]:not([tabindex='-1'])","[class*=btn]","[class*=Btn]","[class*=button]","[class*=Button]","[role*=button]","[href^='tel:']","[href^='callto:']","[href^='mailto:']","[href^='sms:']","[href^='skype:']","[href^='whatsapp:']","[id*=btn]","[id*=Btn]","[id*=button]","[id*=Button]"].join(",");function U(t){return t.closest(N)}var E="karrot-event-builder";var Z=!0,b="Invariant failed";function u(t,e){if(!t){if(Z)throw new Error(b);var r=typeof e=="function"?e():e,i=r?"".concat(b,": ").concat(r):b;throw new Error(i)}}var k,tt=new Uint8Array(16);function S(){if(!k&&(k=typeof crypto<"u"&&crypto.getRandomValues&&crypto.getRandomValues.bind(crypto),!k))throw new Error("crypto.getRandomValues() not supported. See https://github.com/uuidjs/uuid#getrandomvalues-not-supported");return k(tt)}var c=[];for(let t=0;t<256;++t)c.push((t+256).toString(16).slice(1));function A(t,e=0){return(c[t[e+0]]+c[t[e+1]]+c[t[e+2]]+c[t[e+3]]+"-"+c[t[e+4]]+c[t[e+5]]+"-"+c[t[e+6]]+c[t[e+7]]+"-"+c[t[e+8]]+c[t[e+9]]+"-"+c[t[e+10]]+c[t[e+11]]+c[t[e+12]]+c[t[e+13]]+c[t[e+14]]+c[t[e+15]]).toLowerCase()}var et=typeof crypto<"u"&&crypto.randomUUID&&crypto.randomUUID.bind(crypto),P={randomUUID:et};function it(t,e,r){if(P.randomUUID&&!e&&!t)return P.randomUUID();t=t||{};let i=t.random||(t.rng||S)();if(i[6]=i[6]&15|64,i[8]=i[8]&63|128,e){r=r||0;for(let n=0;n<16;++n)e[r+n]=i[n];return e}return A(i)}var _=it;function w(t){for(var e=1;e"u")){a=w({},e,a),typeof a.expires=="number"&&(a.expires=new Date(Date.now()+a.expires*864e5)),a.expires&&(a.expires=a.expires.toUTCString()),n=encodeURIComponent(n).replace(/%(2[346B]|5E|60|7C)/g,decodeURIComponent).replace(/[()]/g,escape);var s="";for(var l in a)a[l]&&(s+="; "+l,a[l]!==!0&&(s+="="+a[l].split(";")[0]));return document.cookie=n+"="+t.write(o,n)+s}}function i(n){if(!(typeof document>"u"||arguments.length&&!n)){for(var o=document.cookie?document.cookie.split("; "):[],a={},s=0;s`_${r.charCodeAt(0).toString(16).padStart(4,"0")}`)}validateField(e){let r=[m.CLICK_THROUGH_COOKIE_FILED,m.DOMAIN_SCOPED_COOKIE_FIELD].includes(e),i=e.startsWith(m.CLICK_THROUGH_COOKIE_FIELD_PREFIX);u(r||i,"KarrotPixel - Invalid Cookie field")}isWritable(){return window.location.protocol.substring(0,4)==="http"}get(e){this.validateField(e);let r=h.get(e);return r?T.unpack(r):void 0}setNewCookie(e,r){this.validateField(e);let i=window.location.hostname.split("."),n=Date.now();i.forEach((o,a)=>{let s=i.slice(a).join("."),l=new T(n,r,s);h.set(e,l.pack(),{domain:s,expires:90,sameSite:"None",secure:!0,path:"/"}),this.get(e)})}setExistCookie(e,r,i){this.validateField(e);let n=Date.now(),o=new T(n,r,i);h.set(e,o.pack(),{domain:i,expires:90,sameSite:"None",secure:!0,path:"/"})}},at={name:"@karrot-pixel/core",private:!0,version:"0.7.3",description:"@karrot-pixel/core",type:"module",main:"./dist/index.cjs",module:"./dist/index.mjs",exports:{".":{require:{types:"./dist/index.d.cts",default:"./dist/index.cjs"},import:{types:"./dist/index.d.ts",default:"./dist/index.js"}},"./builder":{require:{types:"./dist/builder.d.cts",default:"./dist/builder.cjs"},import:{types:"./dist/builder.d.ts",default:"./dist/builder.js"}}},files:["dist"],scripts:{dev:"yarn build:alpha --watch",build:"tsup --env.STAGE production","build:alpha":"tsup --env.STAGE alpha",analyze:"yarn build --metafile",lint:"yarn run -T biome check src/","lint:fix":"yarn lint --write",test:"vitest","test:watch":"vitest --watch"},devDependencies:{"@types/js-cookie":"^3.0.2","@types/uuid":"^9.0.1","happy-dom":"^20.9.0",tsup:"^8.3.0",typescript:"4.9.4",vitest:"*"},dependencies:{"@medv/finder":"^4.0.2","js-cookie":"^3.0.1","query-string":"^8.1.0","tiny-invariant":"^1.3.1",uuid:"^9.0.0"},engines:{node:"20.18.0"},packageManager:"yarn@4.2.2",ultra:{concurrent:["dev"]},repository:{type:"git",url:"git+https://github.com/daangn/karrot-pixel.git"},author:"Danggeun Market Inc.",license:"ISC",bugs:{url:"https://github.com/daangn/karrot-pixel/issues"},homepage:"https://github.com/daangn/karrot-pixel#readme"},ot=class{constructor(t,e=new Map,r=Date.now()){this.karrotRequest=t,this.eventCountMap=e,this.initialTime=r}metadata(t){return{sw:window.screen.width,sh:window.screen.height,ec:this.eventCountMap.get(t)??0,it:this.initialTime,v:at.version,cvid:h.get("CVID"),cvid_y:h.get("CVID_Y")}}fire(t,e,r,i,n,o=Date.now()){let a={id:r,uid:i,cid:n,et:t,rl:window.document.referrer,l:window.location.href,ts:o,pl:e,md:this.metadata(t)};this.karrotRequest.send(a)}},st=class{constructor(t){this.endpoint=t}rebuildPayload(t){return JSON.parse(JSON.stringify({id:t.id,uid:t.uid,cid:t.cid,et:t.et,rl:t.rl,l:t.l,ts:t.ts.toString(),pl:JSON.stringify({tag:t.pl.tag,keyword:t.pl.keyword,id:t.pl.id,total_quantity:t.pl.total_quantity,total_price:t.pl.total_price,currency:t.pl.currency,products:t.pl.products?.map(e=>({id:e.id,name:e.name,quantity:e.quantity,price:e.price}))}),fp:t.fp,md:JSON.stringify({sw:t.md.sw,sh:t.md.sh,ec:t.md.ec,it:t.md.it,v:t.md.v,cvid:t.md.cvid,cvid_y:t.md.cvid_y})}))}makeUrl(t){let e=new URLSearchParams(this.rebuildPayload(t));return`${this.endpoint}?${e.toString()}`}send(t){let e=this.makeUrl(t);navigator.sendBeacon(e,"")}},K=class v{static PENDING_LIMIT=1e3;static MISINSTALL_WARN_MS=1e4;karrotEventManager;karrotCookieManager;trackerId;pendingClickId=null;plugins=[];pendingEvents=[];queueFullWarned=!1;misinstallWarned=!1;misinstallTimer;constructor(e){this.karrotEventManager=new ot(new st(e.collectEndpoint)),this.karrotCookieManager=new p,this.cookieInit()}cookieInit(){this.pendingClickId=this.getClickIdInQueryParams(),this.karrotCookieManager.isWritable()&&(this.karrotCookieManager.get(p.DOMAIN_SCOPED_COOKIE_FIELD)?.pack()||this.karrotCookieManager.setNewCookie(p.DOMAIN_SCOPED_COOKIE_FIELD,this.getRandomPixelId()))}applyPendingClickId(e){this.pendingClickId&&this.karrotCookieManager.isWritable()&&this.setClickCookieId(e,this.pendingClickId)}setClickCookieId(e,r){this.writeClickCookie(p.getClickThroughCookieField(e),r),this.writeClickCookie(p.CLICK_THROUGH_COOKIE_FILED,r)}writeClickCookie(e,r){let i=this.karrotCookieManager.get(e);i?this.karrotCookieManager.setExistCookie(e,r,i.cookieDomain):this.karrotCookieManager.setNewCookie(e,r)}getClickCookie(e){let r=p.getClickThroughCookieField(e);return this.karrotCookieManager.get(r)||this.karrotCookieManager.get(p.CLICK_THROUGH_COOKIE_FILED)}getClickIdInQueryParams(){return new URL(window.location.href).searchParams.get("kmckid")||this.getClickIdInReferrer()}getClickIdInReferrer(){if(!document.referrer)return null;try{return new URL(document.referrer).searchParams.get("kmckid")}catch{return null}}getRandomPixelId(){return _()}registerPlugin(e){this.plugins.push(e)}init(e){if(this.trackerId=e,this.applyPendingClickId(e),this.clearMisinstallTimer(),this.flushPending(),this.plugins.length===0)return;let r={trackerId:e,track:(i,n)=>{R.includes(i)&&this.track(i,n)}};Promise.allSettled(this.plugins.map(i=>Promise.resolve().then(()=>i.setup(r)))).then(i=>{i.forEach((n,o)=>{n.status==="rejected"&&console.warn(`[karrot-pixel] plugin "${this.plugins[o].name}" setup failed:`,n.reason)})})}destroy(){this.clearMisinstallTimer();for(let e of this.plugins)e.teardown?.();this.plugins=[]}track(e,r={}){u(R.includes(e),"KarrotPixel - Invalid Event Type"),this.trackAt(e,r,Date.now())}replayTrack(e,r,i){u(R.includes(e),"KarrotPixel - Invalid Event Type"),this.trackAt(e,r??{},i)}trackAt(e,r,i){if(this.trackerId===void 0){this.enqueuePending({type:e,payload:r,occurredAt:i});return}this.fireNow(e,r,i)}enqueuePending(e){if(this.pendingEvents.length>=v.PENDING_LIMIT){this.queueFullWarned||(console.warn(`[karrot-pixel] pending queue full (${v.PENDING_LIMIT}); dropping '${e.type}'`),this.queueFullWarned=!0);return}this.pendingEvents.push(e),this.startMisinstallTimerOnce()}startMisinstallTimerOnce(){this.misinstallWarned||this.misinstallTimer!==void 0||(this.misinstallTimer=window.setTimeout(()=>{this.misinstallTimer=void 0,this.trackerId===void 0&&this.pendingEvents.length>0&&!this.misinstallWarned&&(console.warn("[karrot-pixel] init() was never called; check your install snippet"),this.misinstallWarned=!0)},v.MISINSTALL_WARN_MS))}clearMisinstallTimer(){this.misinstallTimer!==void 0&&(window.clearTimeout(this.misinstallTimer),this.misinstallTimer=void 0)}flushPending(){let e=this.pendingEvents.splice(0);for(let r of e)this.fireNow(r.type,r.payload,r.occurredAt)}fireNow(e,r,i){u(this.trackerId!==void 0,"KarrotPixel - Need to initialize KarrotPixel with TrackerId");let n=this.trackerId,o=this.getClickCookie(n),a=this.karrotCookieManager.get(p.DOMAIN_SCOPED_COOKIE_FIELD);(async()=>{this.karrotEventManager.fire(e,r,n,a?.pack(),o?.pack(),i)})().then()}getClickCookieId(){return this.trackerId===void 0?null:this.getClickCookie(this.trackerId)?.pack()??null}};function F(t){return typeof t=="object"&&t!==null&&t.stub===!0&&Array.isArray(t.queue)}function H(t,e){for(let[r,i,n]of e.queue)try{r==="init"?t.init(String(i[0])):t.replayTrack(i[0],i[1],n)}catch(o){console.warn("[karrot-pixel] failed to replay queued call:",o)}}var lt=3e3,ct=1,ut=class{configUrl;pixelId;timeoutMs;maxRetries;constructor(t){this.configUrl=t.configUrl,this.pixelId=t.pixelId,this.timeoutMs=t.timeoutMs??lt,this.maxRetries=t.maxRetries??ct}async load(){let t=this.maxRetries+1,e="unknown";for(let r=0;re.abort(),this.timeoutMs);try{let i=await fetch(t,{signal:e.signal});if(!i.ok)return{kind:"retryable",reason:`http_${i.status}`};let n;try{n=await i.json()}catch{return{kind:"fatal",reason:"invalid_json"}}let o=L(n);return o?{kind:"ok",config:o}:{kind:"fatal",reason:"invalid_schema"}}catch(i){return i instanceof DOMException&&i.name==="AbortError"?{kind:"retryable",reason:"timeout"}:{kind:"retryable",reason:`network_error:${i instanceof Error?i.message:String(i)}`}}finally{clearTimeout(r)}}},B=class y{static WINDOW_MS=500;static MAX_ENTRIES=100;timestamps=new Map;isDuplicate(e,r=Date.now()){let i=this.timestamps.get(e);return i===void 0?!1:r-iy.MAX_ENTRIES&&this.cleanupExpired(r)}clear(){this.timestamps.clear()}cleanupExpired(e){for(let[r,i]of this.timestamps)e-i>=y.WINDOW_MS&&this.timestamps.delete(r)}},dt=class{constructor(t){this.options=t,this.handler=e=>this.handleClick(e)}dedup=new B;handler;running=!1;start(){this.running||(this.running=!0,document.addEventListener("click",this.handler,!0))}stop(){this.running&&(this.running=!1,document.removeEventListener("click",this.handler,!0))}handleClick(t){let e=t.target;if(!(e instanceof Element))return;let r=U(e);if(!r)return;let i=window.location.pathname;for(let n of this.options.rules){if(!I(n.trigger))continue;let o=n.trigger.selector.selector,a=n.trigger.selector.pathExact,s=!1;try{s=r.matches(o)}catch{continue}if(!s||a!=null&&a!==i)continue;let l=a!=null?`${n.eventName}:${o}:${a}`:`${n.eventName}:${o}`;if(!this.dedup.isDuplicate(l)){this.dedup.record(l);try{this.options.onMatch(n,r)}catch{}}}}},pt=class{constructor(t){this.options=t}running=!1;dedup=new B;originalPushState=null;originalReplaceState=null;wrappedPushState=null;wrappedReplaceState=null;popstateHandler=null;start(){this.running||(this.running=!0,this.originalPushState=history.pushState,this.originalReplaceState=history.replaceState,this.wrappedPushState=(...t)=>{this.originalPushState?.apply(history,t),this.evaluateRules()},this.wrappedReplaceState=(...t)=>{this.originalReplaceState?.apply(history,t),this.evaluateRules()},history.pushState=this.wrappedPushState,history.replaceState=this.wrappedReplaceState,this.popstateHandler=()=>this.evaluateRules(),window.addEventListener("popstate",this.popstateHandler),this.evaluateRules())}stop(){this.running&&(this.running=!1,history.pushState===this.wrappedPushState&&this.originalPushState?history.pushState=this.originalPushState:console.warn("[karrot-pixel] pushState was further patched; skipping restore"),history.replaceState===this.wrappedReplaceState&&this.originalReplaceState?history.replaceState=this.originalReplaceState:console.warn("[karrot-pixel] replaceState was further patched; skipping restore"),this.popstateHandler&&(window.removeEventListener("popstate",this.popstateHandler),this.popstateHandler=null),this.originalPushState=null,this.originalReplaceState=null,this.wrappedPushState=null,this.wrappedReplaceState=null)}evaluateRules(){let t=new URL(window.location.href).pathname;for(let e of this.options.rules){if(!x(e.trigger))continue;let r=e.trigger.pattern.value;if(!r||!t.includes(r))continue;let i=`${e.eventName}:url:${r}:${t}`;if(!this.dedup.isDuplicate(i)){this.dedup.record(i);try{this.options.onMatch(e)}catch{}}}}},ht=1e4;function gt(t){return new Promise((e,r)=>{let i=()=>{window.removeEventListener("message",n),clearTimeout(o)},n=s=>{if(s.origin!==t.proOrigin||s.source!==window.opener||typeof s.data!="object"||s.data===null||s.data.channel!==E)return;let l=s.data;l.type==="bootstrap_ack"?(i(),e(l.payload)):l.type==="bootstrap_error"&&(i(),r(new Error(l.payload.error.message)))},o=setTimeout(()=>{i(),r(new Error("bootstrap timeout"))},ht);window.addEventListener("message",n);let a={channel:E,type:"bootstrap",payload:{sdkVersion:"0.0.0",trackerId:t.trackerId,pageUrl:window.location.href,pageTitle:document.title}};window.opener?.postMessage(a,t.proOrigin)})}var mt=class{loadPromise=null;load(t){return typeof window>"u"||typeof document>"u"?Promise.reject(new Error("loadBuilderScript requires a browser environment")):window.__karrotPixelBuilder__?Promise.resolve():this.loadPromise?this.loadPromise:(this.loadPromise=new Promise((e,r)=>{let i=document.createElement("script");i.src=t,i.async=!0,i.onload=()=>e(),i.onerror=()=>{this.loadPromise=null,r(new Error(`Failed to load builder bundle: ${t}`))},document.head.appendChild(i)}),this.loadPromise)}reset(){this.loadPromise=null}},ft=new mt;function kt(t){return ft.load(t)}var q=class{constructor(t={}){this.options=t}name="event-builder";ruleEngine;urlTrigger;builderTeardown;async setup(t){if(this.passesQuickFilter())try{let e=this.options.builderBundleUrl;if(!e)throw new Error("builderBundleUrl is required in builder mode but was not provided");let r=this.options.proOrigin,i=await gt({proOrigin:r,trackerId:t.trackerId});if(i.trackerId!==t.trackerId)throw new Error(`tracker mismatch: embedded="${t.trackerId}" but Pro UI requested="${i.trackerId}"`);await kt(e);let n=typeof window<"u"?window.__karrotPixelBuilder__:void 0;if(!n?.activate)throw new Error("builder bundle loaded but window.__karrotPixelBuilder__.activate is missing");this.builderTeardown=await n.activate(t,{proOrigin:r,bootstrapAck:i});return}catch(e){console.warn("[karrot-pixel] builder mode failed, falling back to runtime:",e)}this.activateRuntimeMode(t)}teardown(){this.ruleEngine?.stop(),this.urlTrigger?.stop(),this.builderTeardown?.()}async activateRuntimeMode(t){let e=this.options.configUrl;if(!e){console.warn("[karrot-pixel] event-builder plugin: configUrl not provided, skipping runtime config fetch");return}let r=await new ut({configUrl:e,pixelId:t.trackerId}).load();if(!r.success)return;let i=typeof window<"u"?window.location.origin:"",n=r.config.websiteRuleSets.find(d=>d.url===i);if(!n||n.rules.length===0)return;let o=n.rules,a=o.filter(d=>I(d.trigger)),s=o.filter(d=>x(d.trigger)),l=d=>{t.track(d.eventName,{_source:"event-builder"})};a.length>0&&(this.ruleEngine=new dt({rules:a,onMatch:l}),this.ruleEngine.start()),s.length>0&&(this.urlTrigger=new pt({rules:s,onMatch:l}),this.urlTrigger.start())}passesQuickFilter(){if(typeof window>"u")return!1;let t=window.opener;if(!t||t.closed)return!1;let e=this.options.proOrigin;if(!e)return!1;let r=typeof document<"u"?document.referrer:"";if(!r)return!1;try{let i=new URL(r).origin;return i===e||i===window.location.origin}catch{return!1}}};var wt="https://karrot-pixel.business.daangn.com/karrot-pixel-builder.js",vt="https://karrot-dsp-conversion-event.daangn.com",yt="https://collect.daangn.com/p/c",Ct="https://ads-pro.business.daangn.com";function It(){if(typeof window>"u"||typeof document>"u")return;let t=window.karrotPixel;if(t&&!F(t))return;let e=new K({collectEndpoint:yt});e.registerPlugin(new q({builderBundleUrl:wt,configUrl:vt,proOrigin:Ct})),window.karrotPixel=e,t&&H(e,t)}It();})(); /*! Bundled license information: js-cookie/dist/js.cookie.mjs: (*! js-cookie v3.0.1 | MIT *) */ //# sourceMappingURL=karrot-pixel.js.map