@hifilabs/pixel 0.15.1 → 0.16.1

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/browser.js CHANGED
@@ -78,10 +78,19 @@ var ArtistPixel = (() => {
78
78
  const googleTagManagerId = currentScript?.dataset.googleTagManagerId || gtmConfig.googleTagManagerId;
79
79
  const googleAnalyticsId = currentScript?.dataset.googleAnalyticsId || gtmConfig.googleAnalyticsId;
80
80
  const forwardingConfig = {
81
+ // Core events
81
82
  pageview: (currentScript?.dataset.forwardPageview ?? gtmConfig.forwardPageview) !== "false",
82
83
  purchase: (currentScript?.dataset.forwardPurchase ?? gtmConfig.forwardPurchase) !== "false",
83
84
  addToCart: (currentScript?.dataset.forwardAddToCart ?? gtmConfig.forwardAddToCart) !== "false",
84
85
  lead: (currentScript?.dataset.forwardLead ?? gtmConfig.forwardLead) !== "false",
86
+ // Standard events
87
+ viewContent: (currentScript?.dataset.forwardViewContent ?? gtmConfig.forwardViewContent) !== "false",
88
+ initiateCheckout: (currentScript?.dataset.forwardInitiateCheckout ?? gtmConfig.forwardInitiateCheckout) !== "false",
89
+ completeRegistration: (currentScript?.dataset.forwardCompleteRegistration ?? gtmConfig.forwardCompleteRegistration) !== "false",
90
+ subscribe: (currentScript?.dataset.forwardSubscribe ?? gtmConfig.forwardSubscribe) !== "false",
91
+ search: (currentScript?.dataset.forwardSearch ?? gtmConfig.forwardSearch) !== "false",
92
+ contact: (currentScript?.dataset.forwardContact ?? gtmConfig.forwardContact) !== "false",
93
+ // Custom events (comma-separated list)
85
94
  custom: (currentScript?.dataset.forwardCustom || gtmConfig.forwardCustom || "").split(",").filter(Boolean)
86
95
  };
87
96
  const hasPlatformPixels = !!(metaPixelId || tiktokPixelId || googleAdsId || googleTagManagerId || googleAnalyticsId);
@@ -635,6 +644,18 @@ var ArtistPixel = (() => {
635
644
  return forwardingConfig.addToCart;
636
645
  if (name === "lead" || name === "form_submit")
637
646
  return forwardingConfig.lead;
647
+ if (name === "viewcontent" || name === "view_content")
648
+ return forwardingConfig.viewContent;
649
+ if (name === "initiatecheckout" || name === "initiate_checkout")
650
+ return forwardingConfig.initiateCheckout;
651
+ if (name === "completeregistration" || name === "complete_registration")
652
+ return forwardingConfig.completeRegistration;
653
+ if (name === "subscribe")
654
+ return forwardingConfig.subscribe;
655
+ if (name === "search")
656
+ return forwardingConfig.search;
657
+ if (name === "contact")
658
+ return forwardingConfig.contact;
638
659
  if (forwardingConfig.custom.length > 0) {
639
660
  return forwardingConfig.custom.some((e) => e.toLowerCase() === name);
640
661
  }
@@ -1,4 +1,4 @@
1
- var ArtistPixel=(()=>{var Ue=Object.defineProperty;var qe=(h,b,y)=>b in h?Ue(h,b,{enumerable:!0,configurable:!0,writable:!0,value:y}):h[b]=y;var K=(h,b,y)=>(qe(h,typeof b!="symbol"?b+"":b,y),y);(function(){let h="0.15.0";function b(t){let e="desktop";/ipad|tablet|android(?!.*mobile)/i.test(t)?e="tablet":/mobile|iphone|android.*mobile|blackberry|iemobile/i.test(t)&&(e="mobile");let n="Unknown";/edg/i.test(t)?n="Edge":/opr|opera/i.test(t)?n="Opera":/firefox/i.test(t)?n="Firefox":/chrome/i.test(t)?n="Chrome":/safari/i.test(t)&&(n="Safari");let o="Unknown";return/iphone|ipad/i.test(t)?o="iOS":/android/i.test(t)?o="Android":/windows/i.test(t)?o="Windows":/mac os/i.test(t)?o="macOS":/linux/i.test(t)?o="Linux":/cros/i.test(t)&&(o="ChromeOS"),{device_type:e,browser:n,os:o}}let y=null;function Kt(){if(!y)try{y=b(navigator.userAgent)}catch{y={device_type:"desktop",browser:"Unknown",os:"Unknown"}}return y}let s=document.currentScript,Y=s?.dataset.artistId,J=s?.dataset.projectId,X=J?Yt(J):void 0;function Yt(t){return!t||t.startsWith("release_")||t.startsWith("merch_")||t.startsWith("link_")||t.startsWith("custom_")?t:`custom_${t}`}let Q=s?.dataset.emulator==="true",ht=s?.dataset.debug==="true",Z=parseInt(s?.dataset.heartbeatInterval||"120000",10),bt=s?.dataset.heartbeat!=="false",vt=s?.dataset.source,_t=s?.dataset.endpoint,w=window.__artistPixelConfig||{},O=s?.dataset.metaPixelId||w.metaPixelId,E=s?.dataset.tiktokPixelId||w.tiktokPixelId,f=s?.dataset.googleAdsId||w.googleAdsId,kt=s?.dataset.googleAdsConversionLabel||w.googleAdsConversionLabel,j=s?.dataset.googleTagManagerId||w.googleTagManagerId,m=s?.dataset.googleAnalyticsId||w.googleAnalyticsId,I={pageview:(s?.dataset.forwardPageview??w.forwardPageview)!=="false",purchase:(s?.dataset.forwardPurchase??w.forwardPurchase)!=="false",addToCart:(s?.dataset.forwardAddToCart??w.forwardAddToCart)!=="false",lead:(s?.dataset.forwardLead??w.forwardLead)!=="false",custom:(s?.dataset.forwardCustom||w.forwardCustom||"").split(",").filter(Boolean)},U=!!(O||E||f||j||m),tt=s?.dataset.consentUi==="true",Jt=s?.dataset.consentStyle||"brutalist",Xt=s?.dataset.primaryColor,Qt=s?.dataset.bannerPosition||"bottom",xt=s?.dataset.excludePages?.split(",").filter(Boolean)||[],It=s?.dataset.trackFileDownloads==="true",Zt=s?.dataset.hashRouting==="true";function te(){if(vt)return vt;let t=typeof window.dataLayer<"u"&&Array.isArray(window.dataLayer),e=typeof window.gtag=="function";return t&&e?"gtm":"pixel"}let G="pixel";if(!Y){C(" Error: data-artist-id attribute is required");return}let Ct="session_id",et="session_timestamp",St="attribution",T="fan_id_hash",nt="visitor_id",V="artistPixel_consent",ee=365*24*60*60*1e3,ne=30*24*60*60*1e3,ae=60*60*1e3,v="balance_";function oe(t){let e=t.replace(/[.+?^${}()|[\]\\]/g,"\\$&").replace(/\*/g,".*");return new RegExp("^"+e+"$")}function ie(t){if(xt.length===0)return!1;try{let e=new URL(t,window.location.origin).pathname;return xt.some(n=>oe(n).test(e))}catch{return!1}}let re=[".pdf",".zip",".tar",".gz",".rar",".7z",".doc",".docx",".xls",".xlsx",".ppt",".pptx",".mp3",".wav",".flac",".aac",".ogg",".mp4",".mov",".avi",".mkv",".webm",".exe",".dmg",".pkg",".deb",".rpm",".csv",".json",".xml",".txt"];function Pt(t){try{let e=new URL(t,window.location.origin).pathname.toLowerCase();return re.some(n=>e.endsWith(n))}catch{return!1}}function se(t,e){try{let o=new URL(t,window.location.origin).pathname.split("/").pop()||"unknown",c=o.includes(".")?o.split(".").pop():"unknown";a("File download tracked:",{url:t,fileName:o,fileExtension:c});let d=S({event_name:"custom",metadata:{event_type:"file_download",file_url:t,file_name:o,file_extension:c,link_text:e?.textContent?.trim().substring(0,100)||""}});P(d)}catch(n){C("Failed to track file download:",n)}}let ce="https://e.os.xyz",Et="https://us-central1-artist-os-distro.cloudfunctions.net/ingestEvents",L=_t||(Q?"http://localhost:5001/artist-os-distro/us-central1/ingestEvents":ce),q=null,p=null,u=null,g=null,A={},at={},_=[],ot=null,k="session",R=null,it=0,rt=0,D=0,F=!0,st=0,ct=!1,de=2*60*1e3,Tt=Date.now(),z=!1,le=!ht,a=(...t)=>{ht&&console.log("[artistPixel]",...t)},C=(...t)=>{le||console.error("[artistPixel]",...t)},dt={base:`
1
+ var ArtistPixel=(()=>{var Ue=Object.defineProperty;var qe=(b,v,y)=>v in b?Ue(b,v,{enumerable:!0,configurable:!0,writable:!0,value:y}):b[v]=y;var K=(b,v,y)=>(qe(b,typeof v!="symbol"?v+"":v,y),y);(function(){let b="0.15.0";function v(t){let e="desktop";/ipad|tablet|android(?!.*mobile)/i.test(t)?e="tablet":/mobile|iphone|android.*mobile|blackberry|iemobile/i.test(t)&&(e="mobile");let n="Unknown";/edg/i.test(t)?n="Edge":/opr|opera/i.test(t)?n="Opera":/firefox/i.test(t)?n="Firefox":/chrome/i.test(t)?n="Chrome":/safari/i.test(t)&&(n="Safari");let o="Unknown";return/iphone|ipad/i.test(t)?o="iOS":/android/i.test(t)?o="Android":/windows/i.test(t)?o="Windows":/mac os/i.test(t)?o="macOS":/linux/i.test(t)?o="Linux":/cros/i.test(t)&&(o="ChromeOS"),{device_type:e,browser:n,os:o}}let y=null;function Kt(){if(!y)try{y=v(navigator.userAgent)}catch{y={device_type:"desktop",browser:"Unknown",os:"Unknown"}}return y}let r=document.currentScript,Y=r?.dataset.artistId,J=r?.dataset.projectId,X=J?Yt(J):void 0;function Yt(t){return!t||t.startsWith("release_")||t.startsWith("merch_")||t.startsWith("link_")||t.startsWith("custom_")?t:`custom_${t}`}let Q=r?.dataset.emulator==="true",yt=r?.dataset.debug==="true",Z=parseInt(r?.dataset.heartbeatInterval||"120000",10),bt=r?.dataset.heartbeat!=="false",vt=r?.dataset.source,_t=r?.dataset.endpoint,g=window.__artistPixelConfig||{},O=r?.dataset.metaPixelId||g.metaPixelId,E=r?.dataset.tiktokPixelId||g.tiktokPixelId,w=r?.dataset.googleAdsId||g.googleAdsId,kt=r?.dataset.googleAdsConversionLabel||g.googleAdsConversionLabel,j=r?.dataset.googleTagManagerId||g.googleTagManagerId,p=r?.dataset.googleAnalyticsId||g.googleAnalyticsId,f={pageview:(r?.dataset.forwardPageview??g.forwardPageview)!=="false",purchase:(r?.dataset.forwardPurchase??g.forwardPurchase)!=="false",addToCart:(r?.dataset.forwardAddToCart??g.forwardAddToCart)!=="false",lead:(r?.dataset.forwardLead??g.forwardLead)!=="false",viewContent:(r?.dataset.forwardViewContent??g.forwardViewContent)!=="false",initiateCheckout:(r?.dataset.forwardInitiateCheckout??g.forwardInitiateCheckout)!=="false",completeRegistration:(r?.dataset.forwardCompleteRegistration??g.forwardCompleteRegistration)!=="false",subscribe:(r?.dataset.forwardSubscribe??g.forwardSubscribe)!=="false",search:(r?.dataset.forwardSearch??g.forwardSearch)!=="false",contact:(r?.dataset.forwardContact??g.forwardContact)!=="false",custom:(r?.dataset.forwardCustom||g.forwardCustom||"").split(",").filter(Boolean)},U=!!(O||E||w||j||p),tt=r?.dataset.consentUi==="true",Jt=r?.dataset.consentStyle||"brutalist",Xt=r?.dataset.primaryColor,Qt=r?.dataset.bannerPosition||"bottom",xt=r?.dataset.excludePages?.split(",").filter(Boolean)||[],It=r?.dataset.trackFileDownloads==="true",Zt=r?.dataset.hashRouting==="true";function te(){if(vt)return vt;let t=typeof window.dataLayer<"u"&&Array.isArray(window.dataLayer),e=typeof window.gtag=="function";return t&&e?"gtm":"pixel"}let V="pixel";if(!Y){C(" Error: data-artist-id attribute is required");return}let Ct="session_id",et="session_timestamp",St="attribution",T="fan_id_hash",nt="visitor_id",G="artistPixel_consent",ee=365*24*60*60*1e3,ne=30*24*60*60*1e3,ae=60*60*1e3,_="balance_";function oe(t){let e=t.replace(/[.+?^${}()|[\]\\]/g,"\\$&").replace(/\*/g,".*");return new RegExp("^"+e+"$")}function ie(t){if(xt.length===0)return!1;try{let e=new URL(t,window.location.origin).pathname;return xt.some(n=>oe(n).test(e))}catch{return!1}}let re=[".pdf",".zip",".tar",".gz",".rar",".7z",".doc",".docx",".xls",".xlsx",".ppt",".pptx",".mp3",".wav",".flac",".aac",".ogg",".mp4",".mov",".avi",".mkv",".webm",".exe",".dmg",".pkg",".deb",".rpm",".csv",".json",".xml",".txt"];function Pt(t){try{let e=new URL(t,window.location.origin).pathname.toLowerCase();return re.some(n=>e.endsWith(n))}catch{return!1}}function se(t,e){try{let o=new URL(t,window.location.origin).pathname.split("/").pop()||"unknown",c=o.includes(".")?o.split(".").pop():"unknown";a("File download tracked:",{url:t,fileName:o,fileExtension:c});let d=S({event_name:"custom",metadata:{event_type:"file_download",file_url:t,file_name:o,file_extension:c,link_text:e?.textContent?.trim().substring(0,100)||""}});P(d)}catch(n){C("Failed to track file download:",n)}}let ce="https://e.os.xyz",Et="https://us-central1-artist-os-distro.cloudfunctions.net/ingestEvents",L=_t||(Q?"http://localhost:5001/artist-os-distro/us-central1/ingestEvents":ce),q=null,h=null,m=null,u=null,A={},at={},k=[],ot=null,x="session",R=null,it=0,rt=0,D=0,F=!0,st=0,ct=!1,de=2*60*1e3,Tt=Date.now(),z=!1,le=!yt,a=(...t)=>{yt&&console.log("[artistPixel]",...t)},C=(...t)=>{le||console.error("[artistPixel]",...t)},dt={base:`
2
2
  :host {
3
3
  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
4
4
  position: fixed;
@@ -83,7 +83,7 @@ var ArtistPixel=(()=>{var Ue=Object.defineProperty;var qe=(h,b,y)=>b in h?Ue(h,b
83
83
  }
84
84
  .btn.accept { background: #fff; color: #000; border-color: #fff; }
85
85
  .btn:hover { opacity: 0.8; }
86
- `};class ge{constructor(e){K(this,"container",null);K(this,"shadow",null);K(this,"config");if(this.config=e,this.hasStoredConsent()){a("ConsentManager: Consent already exists, not showing banner");return}this.container=document.createElement("div"),this.container.id="artistPixel-consent-manager",this.shadow=this.container.attachShadow({mode:"closed"}),this.render(),document.body.appendChild(this.container),a("ConsentManager: Banner rendered")}hasStoredConsent(){try{return window._balanceConsentNeedsRefresh?!1:localStorage.getItem(V)!==null}catch{return!1}}render(){if(!this.shadow)return;let e=this.config.style||"brutalist",n=dt.base,o=dt[e]||dt.brutalist,c=this.config.position==="top"?"top: 0;":"bottom: 0;",d=this.config.primaryColor?`.btn.accept { background: ${this.config.primaryColor} !important; border-color: ${this.config.primaryColor} !important; color: #fff !important; }`:"";this.shadow.innerHTML=`
86
+ `};class ge{constructor(e){K(this,"container",null);K(this,"shadow",null);K(this,"config");if(this.config=e,this.hasStoredConsent()){a("ConsentManager: Consent already exists, not showing banner");return}this.container=document.createElement("div"),this.container.id="artistPixel-consent-manager",this.shadow=this.container.attachShadow({mode:"closed"}),this.render(),document.body.appendChild(this.container),a("ConsentManager: Banner rendered")}hasStoredConsent(){try{return window._balanceConsentNeedsRefresh?!1:localStorage.getItem(G)!==null}catch{return!1}}render(){if(!this.shadow)return;let e=this.config.style||"brutalist",n=dt.base,o=dt[e]||dt.brutalist,c=this.config.position==="top"?"top: 0;":"bottom: 0;",d=this.config.primaryColor?`.btn.accept { background: ${this.config.primaryColor} !important; border-color: ${this.config.primaryColor} !important; color: #fff !important; }`:"";this.shadow.innerHTML=`
87
87
  <style>
88
88
  ${n}
89
89
  :host { ${c} }
@@ -99,4 +99,4 @@ var ArtistPixel=(()=>{var Ue=Object.defineProperty;var qe=(h,b,y)=>b in h?Ue(h,b
99
99
  <button id="accept" class="btn accept">Accept</button>
100
100
  </div>
101
101
  </div>
102
- `,this.shadow.getElementById("accept")?.addEventListener("click",()=>this.handleConsent(!0)),this.shadow.getElementById("decline")?.addEventListener("click",()=>this.handleConsent(!1))}handleConsent(e){window.balance?.setConsent&&window.balance.setConsent({analytics:e,marketing:e,personalization:e,timestamp:new Date().toISOString()}),e&&!window._balanceInitialPageviewFired&&(window._balanceInitialPageviewFired=!0,window.balance?.page&&window.balance.page(),ft(),a("Initial pageview fired after consent granted")),this.remove()}remove(){this.container&&(this.container.remove(),this.container=null,this.shadow=null,a("ConsentManager: Banner removed"))}}let Lt=!1,N=!1;function ue(){if(!O)return;if(window.fbq){a("[Platform:Meta] Already loaded, skipping");return}a("[Platform:Meta] Injecting pixel:",O);let t=function(...n){t.callMethod?t.callMethod.apply(t,n):t.queue.push(n)};window._fbq||(window._fbq=t),t.push=t,t.loaded=!0,t.version="2.0",t.queue=[],window.fbq=t;let e=document.createElement("script");e.async=!0,e.src="https://connect.facebook.net/en_US/fbevents.js",e.onload=()=>{window.fbq("init",O),I.pageview&&window.fbq("track","PageView"),a("[Platform:Meta] Initialized and PageView tracked")},document.head.appendChild(e)}function fe(){if(!E)return;if(window.ttq?._i?.[E]){a("[Platform:TikTok] Already loaded, skipping");return}a("[Platform:TikTok] Injecting pixel:",E);let t=window,e="ttq";t.TiktokAnalyticsObject=e;let n=t[e]=t[e]||[];n.methods=["page","track","identify","instances","debug","on","off","once","ready","alias","group","enableCookie","disableCookie","holdConsent","revokeConsent","grantConsent"],n.setAndDefer=function(o,c){o[c]=function(...d){o.push([c].concat(d))}};for(let o=0;o<n.methods.length;o++)n.setAndDefer(n,n.methods[o]);n.instance=function(o){let c=n._i[o]||[];for(let d=0;d<n.methods.length;d++)n.setAndDefer(c,n.methods[d]);return c},n.load=function(o){let c="https://analytics.tiktok.com/i18n/pixel/events.js";n._i=n._i||{},n._i[o]=[],n._i[o]._u=c,n._t=n._t||{},n._t[o]=+new Date,n._o=n._o||{};let d=document.createElement("script");d.type="text/javascript",d.async=!0,d.src=c+"?sdkid="+o+"&lib="+e,document.head.appendChild(d)},n.load(E),I.pageview&&n.page(),a("[Platform:TikTok] Initialized and page() tracked")}function me(){if(!f)return;if(window.dataLayer=window.dataLayer||[],typeof window.gtag!="function"&&(window.gtag=function(...e){window.dataLayer.push(e)}),document.querySelector('script[src*="googletagmanager.com/gtag/js"]')){a("[Platform:GoogleAds] gtag.js already loaded, configuring"),window.gtag("config",f);return}a("[Platform:GoogleAds] Injecting gtag:",f),window.gtag("consent","default",{ad_storage:"granted",ad_user_data:"granted",ad_personalization:"granted",analytics_storage:"granted"});let t=document.createElement("script");t.async=!0,t.src=`https://www.googletagmanager.com/gtag/js?id=${f}`,t.onload=()=>{window.gtag("js",new Date),window.gtag("config",f),a("[Platform:GoogleAds] Initialized")},document.head.appendChild(t)}function we(){if(!j)return;if(document.querySelector(`script[src*="googletagmanager.com/gtm.js?id=${j}"]`)){a("[Platform:GTM] Already loaded, skipping");return}a("[Platform:GTM] Injecting GTM:",j),window.dataLayer=window.dataLayer||[],typeof window.gtag!="function"&&(window.gtag=function(...n){window.dataLayer.push(n)});let t=N?"granted":"denied";window.gtag("consent","default",{ad_storage:t,ad_user_data:t,ad_personalization:t,analytics_storage:t}),window.gtag("set","wait_for_update",500),window.dataLayer.push({"gtm.start":new Date().getTime(),event:"gtm.js"});let e=document.createElement("script");e.async=!0,e.src=`https://www.googletagmanager.com/gtm.js?id=${j}`,e.onload=()=>{a("[Platform:GTM] Initialized")},document.head.appendChild(e)}function pe(){if(!m)return;let t=document.querySelector('script[src*="googletagmanager.com/gtag/js"]');window.dataLayer=window.dataLayer||[],typeof window.gtag!="function"&&(window.gtag=function(...o){window.dataLayer.push(o)});let e=N?"granted":"denied";if(window.gtag("consent","default",{ad_storage:e,ad_user_data:e,ad_personalization:e,analytics_storage:e}),t){a("[Platform:GA4] gtag.js already loaded, configuring"),window.gtag("config",m,{send_page_view:!1});return}a("[Platform:GA4] Injecting gtag:",m);let n=document.createElement("script");n.async=!0,n.src=`https://www.googletagmanager.com/gtag/js?id=${m}`,n.onload=()=>{window.gtag("js",new Date),window.gtag("config",m,{send_page_view:!1}),a("[Platform:GA4] Initialized")},document.head.appendChild(n)}function ye(){if(U){if(Lt){a("[Platform] Already loaded, skipping");return}if(!N){a("[Platform] Marketing consent not granted, deferring");return}a("[Platform] Injecting platform pixels (consent granted)"),Lt=!0,ue(),fe(),me(),we(),pe()}}function At(t){if(N=t,a("[Platform] Marketing consent:",t?"granted":"denied"),t&&ye(),window.ttq&&(t?window.ttq.grantConsent?.():window.ttq.revokeConsent?.()),typeof window.gtag=="function"){let e=t?"granted":"denied";window.gtag("consent","update",{ad_storage:e,ad_user_data:e,ad_personalization:e,analytics_storage:e})}}function lt(t){if(!U||!N)return!1;let e=t.toLowerCase();return e==="pageview"||e==="page_view"?I.pageview:e==="purchase"?I.purchase:e==="addtocart"||e==="add_to_cart"?I.addToCart:e==="lead"||e==="form_submit"?I.lead:I.custom.length>0?I.custom.some(n=>n.toLowerCase()===e):!1}function he(){lt("pageview")&&(a("[Platform] Forwarding PageView"),window.fbq&&window.fbq("track","PageView"),window.ttq&&window.ttq.page(),typeof window.gtag=="function"&&m&&window.gtag("event","page_view",{send_to:m}))}function be(t,e,n){if(lt("purchase")){if(a("[Platform] Forwarding Purchase:",t,e),window.fbq&&window.fbq("track","Purchase",{value:t,currency:e,content_ids:n?.contentIds,content_type:n?.contentType||"product",order_id:n?.transactionId}),window.ttq&&window.ttq.track("CompletePayment",{value:t,currency:e,order_id:n?.transactionId}),typeof window.gtag=="function"&&f){let o=kt?`${f}/${kt}`:f;window.gtag("event","conversion",{send_to:o,value:t,currency:e,transaction_id:n?.transactionId}),window.gtag("event","purchase",{send_to:f,value:t,currency:e,transaction_id:n?.transactionId})}typeof window.gtag=="function"&&m&&window.gtag("event","purchase",{send_to:m,value:t,currency:e,transaction_id:n?.transactionId,items:n?.items})}}function ve(t,e){if(!lt(t))return;let n=t.toLowerCase();a("[Platform] Forwarding custom event:",t);let o={addtocart:"AddToCart",add_to_cart:"AddToCart",lead:"Lead",form_submit:"Lead",viewcontent:"ViewContent",view_content:"ViewContent",search:"Search",subscribe:"Subscribe",contact:"Contact",completeregistration:"CompleteRegistration",complete_registration:"CompleteRegistration",initiatecheckout:"InitiateCheckout",initiate_checkout:"InitiateCheckout"},c={addtocart:"AddToCart",add_to_cart:"AddToCart",lead:"SubmitForm",form_submit:"SubmitForm",viewcontent:"ViewContent",view_content:"ViewContent",search:"Search",subscribe:"Subscribe",contact:"Contact",completeregistration:"CompleteRegistration",complete_registration:"CompleteRegistration",initiatecheckout:"InitiateCheckout",initiate_checkout:"InitiateCheckout"},d={addtocart:"add_to_cart",add_to_cart:"add_to_cart",lead:"generate_lead",form_submit:"generate_lead",viewcontent:"view_item",view_content:"view_item",search:"search",subscribe:"subscribe",contact:"contact",completeregistration:"sign_up",complete_registration:"sign_up",initiatecheckout:"begin_checkout",initiate_checkout:"begin_checkout"};if(window.fbq){let r=o[n];r?window.fbq("track",r,e):window.fbq("trackCustom",t,e)}if(window.ttq){let r=c[n]||t;window.ttq.track(r,e)}if(typeof window.gtag=="function"&&f){let r=d[n]||t;window.gtag("event",r,{send_to:f,...e})}if(typeof window.gtag=="function"&&m){let r=d[n]||t;window.gtag("event",r,{send_to:m,...e})}}function Rt(){try{return k==="local"?localStorage:sessionStorage}catch{return null}}function B(t){let e=Rt();if(!e)return null;try{let n=v+t,o=e.getItem(n);if(!o&&k==="session")try{o=localStorage.getItem(n)}catch{}return o}catch{return null}}function M(t,e){let n=Rt();if(n)try{n.setItem(v+t,e)}catch{}}function Dt(){if(k!=="local"){a("Upgrading storage tier: session -> local");try{let t=[];for(let e=0;e<sessionStorage.length;e++){let n=sessionStorage.key(e);n?.startsWith(v)&&t.push(n)}for(let e of t){let n=sessionStorage.getItem(e);n&&localStorage.setItem(e,n)}for(let e of t)sessionStorage.removeItem(e);k="local",a(`Storage tier upgraded, migrated ${t.length} items`)}catch(t){C(" Storage migration failed:",t)}}}function W(){return crypto&&crypto.randomUUID?crypto.randomUUID():"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,t=>{let e=Math.random()*16|0;return(t==="x"?e:e&3|8).toString(16)})}function _e(){try{let t=B(Ct),e=B(et);if(t&&e&&Date.now()-parseInt(e,10)<ae)return M(et,Date.now().toString()),t;let n=W();return M(Ct,n),M(et,Date.now().toString()),n}catch{return W()}}function ke(){let t=new URLSearchParams(window.location.search),e={};return["source","medium","campaign","content","term"].forEach(n=>{let o=t.get(`utm_${n}`);o&&(e[`utm_${n}`]=o)}),e}function xe(){try{let t=B(St);if(t){A=JSON.parse(t),a("Loaded attribution:",A);return}let e=ke();Object.keys(e).length>0&&(A=e,M(St,JSON.stringify(e)),a("Captured attribution:",A))}catch{}}function Ie(){try{u=localStorage.getItem(v+T),u&&a("Loaded fan ID hash:",u.substring(0,16)+"...")}catch{try{u=B(T)}catch{}}}function gt(){try{let t=localStorage.getItem(v+nt);if(t)return t;let e=W();return localStorage.setItem(v+nt,e),a("Created persistent visitor ID:",e.substring(0,8)+"..."),e}catch{return a("localStorage unavailable, using session ID as fallback"),q||W()}}function Ce(){try{p=localStorage.getItem(v+nt),p&&a("Loaded visitor ID:",p.substring(0,8)+"...")}catch{}}function Se(){try{let t=localStorage.getItem(V);if(t){let e=JSON.parse(t);if(e.expiresAt&&Date.now()>e.expiresAt){a("Consent expired - clearing stored consent"),localStorage.removeItem(V),g=null;return}if(e.expiresAt){let n=e.expiresAt-Date.now();n>0&&n<ne&&(a("Consent nearing expiration - will prompt for refresh"),window._balanceConsentNeedsRefresh=!0)}g=e.preferences||null,a("Loaded consent:",g)}}catch{}}function Mt(t){let e=g;g=t;try{let o={preferences:t,method:"explicit",version:1,expiresAt:Date.now()+ee};localStorage.setItem(V,JSON.stringify(o)),a("Consent saved with TTL:",t),window._balanceConsentNeedsRefresh=!1}catch(o){C(" Could not save consent:",o)}t.analytics===!0&&(Dt(),p||(p=gt()));let n=S({event_name:"consent_updated",metadata:{consent_preferences:t,consent_method:"explicit",previous_consent:e||void 0}});P(n);try{window.dispatchEvent(new CustomEvent("artistPixel:consent:updated",{detail:t})),a("DOM event artistPixel:consent:updated dispatched")}catch{}U&&At(t.marketing===!0)}function Pe(){return g}function Ee(t){return g?.[t]===!0}function Te(t){for(let[e,n]of Object.entries(t))try{let o=Ot(e);at[o]=n}catch{at[e]=n}a("Registered",Object.keys(t).length,"links for tracking enrichment")}function Ot(t){try{let e=new URL(t);return`${e.protocol}//${e.host}${e.pathname}${e.search}`}catch{return t}}function Le(t){let e=Ot(t);return at[e]||null}async function Ae(t){let e=t.toLowerCase().trim(),o=new TextEncoder().encode(e),c=await crypto.subtle.digest("SHA-256",o);return Array.from(new Uint8Array(c)).map(r=>r.toString(16).padStart(2,"0")).join("")}function S(t){let e=Kt(),n={artist_id:Y,fan_session_id:q,visitor_id:p||gt(),fan_id_hash:u||void 0,timestamp:new Date().toISOString(),source_url:window.location.href,referrer_url:document.referrer||void 0,user_agent:navigator.userAgent,device_type:e.device_type,browser:e.browser,os:e.os,tracking_source:G,...t,...A};return X&&!t.projectId&&(n.projectId=X),n}function P(t){_.push(t),a("Event queued:",t.event_name,"(queue:",_.length,")"),_.length>=10&&H()}async function H(){if(_.length===0)return;let t=[..._];_=[],a("Flushing",t.length,"events to",L);try{let e=await fetch(L,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({events:t}),keepalive:!0});if(!e.ok)throw new Error(`HTTP ${e.status}`);a("Events sent successfully")}catch(e){if(C(" Failed to send events, trying fallback:",e),L!==Et&&!Q)try{if((await fetch(Et,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({events:t}),keepalive:!0})).ok){a("Events sent via fallback (no geo)");return}}catch(n){C(" Fallback also failed:",n)}_.length<50&&_.push(...t)}}function Re(){ot&&clearInterval(ot),ot=window.setInterval(()=>{_.length>0&&H()},5e3)}function ut(){D||(it=Date.now()),D=Date.now(),F=!0,a("Active time tracking started/resumed")}function jt(){D&&F&&(rt+=Date.now()-D),F=!1,a("Active time tracking paused, accumulated:",rt,"ms")}function Ut(){let t=rt;return F&&D&&(t+=Date.now()-D),t}function De(){Tt=Date.now(),z&&(z=!1,ut(),a("User returned from idle"))}function Me(){if(document.visibilityState==="hidden"){a("Skipping heartbeat - tab hidden");return}if(Date.now()-Tt>de){z||(z=!0,jt(),a("User idle - pausing heartbeat"));return}let t=Ut(),e=Math.round(t/1e3),n=S({event_name:"engagement_heartbeat",metadata:{time_on_page_seconds:e,time_on_page_ms:t,heartbeat_interval_ms:Z,is_active:F&&!z}});P(n),st++,a("Heartbeat sent:",e,"seconds active")}function ft(){if(!bt){a('Heartbeat disabled via data-heartbeat="false"');return}R&&clearInterval(R),ut(),R=window.setInterval(()=>{Me()},Z),a("Heartbeat started with interval:",Z,"ms")}function mt(){if(!ct){if(ct=!0,R&&(clearInterval(R),R=null),bt){let t=it?Date.now()-it:0,e=Ut(),n=S({event_name:"engagement_summary",metadata:{total_time_ms:t,active_time_ms:e,heartbeat_samples:st,page_path:window.location.pathname}});if(navigator.sendBeacon&&L){let o=JSON.stringify({events:[n]});navigator.sendBeacon(L,o),a("Engagement summary sent via sendBeacon:",Math.round(e/1e3),"seconds active")}else P(n),a("Engagement summary enqueued:",Math.round(e/1e3),"seconds active")}st=0}}function $(t={}){let e=t.url||window.location.href;if(ie(e)){a("Page excluded from tracking:",e);return}let n=S({event_name:"pageview",page_title:t.title||document.title,source_url:e});P(n),he()}function wt(t,e={}){let n=S({event_name:"custom",metadata:{event_type:t,...e}});P(n),ve(t,e)}async function qt(t,e={}){try{if(g&&g.analytics===!1){a("Identify skipped - user declined analytics consent");return}u=await Ae(t),g?.analytics===!0&&Dt();try{localStorage.setItem(v+T,u)}catch{M(T,u)}let n=t.split("@"),o=n[0].charAt(0)+"***@"+(n[1]||"");a("Fan identified:",{name:e.name||"(no name)",email:o,hash:u.substring(0,16)+"...",traits:e,storageTier:k});let c=S({event_name:"identify",fan_id_hash:u,metadata:{email_sha256:u,email_display:o,traits:e,consent_preferences:g||void 0,storage_tier:k}});P(c)}catch(n){C(" Failed to identify:",n)}}function Oe(t){if(!t||typeof t!="string"){C("setFanIdHash: invalid hash provided");return}u=t;try{localStorage.setItem(v+T,t),a("Fan ID hash set from server:",t.substring(0,16)+"...")}catch{M(T,t)}}function Ft(t,e="USD",n={}){let o=S({event_name:"purchase",metadata:{revenue:t,currency:e,...n}});P(o),be(t,e,n)}function zt(){G=te(),a("Tracking source detected:",G),Se(),g?.analytics===!0?(k="local",a("Storage tier: local (analytics consent granted)")):(k="session",a("Storage tier: session (privacy by default)")),q=_e(),Ie(),Ce(),p||(p=gt()),g||a(tt?"Consent UI enabled, waiting for explicit user consent (Tier 0 mode)":"No consent - operating in privacy-first mode (session storage only, limited tracking)"),U&&g?.marketing===!0?(a("[Platform] Marketing consent already granted, initializing platform pixels"),At(!0)):U&&a("[Platform] Platform pixels configured:",{meta:O||"(none)",tiktok:E||"(none)",googleAds:f||"(none)"}),xe(),Re(),a("Initialized",{artistId:Y,projectId:X||"(none - will track to all projects)",rawProjectId:J||"(none)",sessionId:q,visitorId:p?p.substring(0,8)+"...":null,fanIdHash:u,consent:g,storageTier:k,trackingSource:G,useEmulator:Q,endpoint:L}),g?.analytics===!0?(window._balanceInitialPageviewFired=!0,$(),ft(),a("Full tracking enabled (user consented)")):tt?a("Tracking dormant - waiting for explicit consent via ConsentManager"):(window._balanceInitialPageviewFired=!0,$(),ft(),a("Privacy-first tracking enabled (session-scoped, visitor_id for deduplication)")),["mousemove","keydown","scroll","touchstart"].forEach(r=>{document.addEventListener(r,De,{passive:!0})});let t=window.location.hostname;function e(r){try{let i=new URL(r).hostname.toLowerCase();return i.includes("spotify")?"spotify":i.includes("apple")||i.includes("music.apple")?"apple_music":i.includes("youtube")||i.includes("youtu.be")?"youtube":i.includes("soundcloud")?"soundcloud":i.includes("tidal")?"tidal":i.includes("deezer")?"deezer":i.includes("amazon")||i.includes("music.amazon")?"amazon_music":i.includes("bandcamp")?"bandcamp":i.includes("lnk.to")||i.includes("linkfire")?"linkfire":i.includes("linktr.ee")?"linktree":i.includes("shop")||i.includes("store")||i.includes("merch")?"shop":i.includes("ticketmaster")||i.includes("eventbrite")||i.includes("dice.fm")?"tickets":i.includes("instagram")?"instagram":i.includes("twitter")||i.includes("x.com")?"twitter":i.includes("tiktok")?"tiktok":i.includes("facebook")?"facebook":"external"}catch{return"external"}}function n(r){try{return new URL(r,window.location.origin).hostname!==t}catch{return!1}}function o(r,i){let l=e(r),x=Le(r),Vt=x?.title||i?.textContent?.trim().substring(0,100)||"",Bt=x?.id||i?.id||i?.getAttribute("data-link-id")||void 0,Wt=x?.category;a("External link clicked:",{url:r,platform:l,linkText:Vt,linkId:Bt,fromRegistry:!!x}),wt("page_link_click",{link_url:r,link_text:Vt,link_id:Bt,platform:l,link_type:"external",...Wt&&{link_category:Wt},...x&&Object.fromEntries(Object.entries(x).filter(([yt])=>!["title","id","category"].includes(yt)).map(([yt,je])=>[`link_${yt}`,je]))})}let c=window.open;if(window.open=function(r,i,l){if(r){let x=r.toString();n(x)&&o(x)}return c.call(window,r,i,l)},a("window.open interception enabled (always on)"),s?.dataset.autoTrackLinks==="true"&&(document.addEventListener("click",r=>{let l=r.target.closest("a");if(l&&l.href&&n(l.href)){if(It&&(Pt(l.href)||l.hasAttribute("download")))return;o(l.href,l)}},{capture:!0,passive:!0}),a("External link click listener enabled (opt-in)")),It&&(document.addEventListener("click",r=>{let l=r.target.closest("a");l?.href&&(Pt(l.href)||l.hasAttribute("download"))&&se(l.href,l)},{capture:!0,passive:!0}),a("File download tracking enabled")),Zt){let r=window.location.href;window.addEventListener("hashchange",()=>{let i=window.location.href;i!==r&&(r=i,setTimeout(()=>{$({title:document.title,url:i})},0))}),a("Hash routing tracking enabled")}document.addEventListener("visibilitychange",()=>{document.visibilityState==="hidden"?(jt(),mt(),H()):(ut(),ct=!1)}),window.addEventListener("pagehide",()=>{mt(),H()}),window.addEventListener("beforeunload",()=>{mt(),H()})}if(window.balance?._version&&window.balance._version!==h){console.warn(`[artistPixel] Version conflict: ${window.balance._version} already loaded, skipping ${h}`);return}let pt=window.balance?.q||[];function Nt(){if(pt.length>0){a("Processing",pt.length,"queued commands");for(let t of pt){let[e,...n]=t;switch(e){case"track":wt(n[0],n[1]);break;case"identify":qt(n[0],n[1]);break;case"page":$(n[0]);break;case"purchase":Ft(n[0],n[1],n[2]);break;case"setConsent":Mt(n[0]);break;default:a("Unknown queued command:",e)}}}}let Ht={track:wt,identify:qt,page:$,purchase:Ft,getSessionId:()=>q,getVisitorId:()=>p,getFanIdHash:()=>u,setFanIdHash:Oe,getAttribution:()=>A,setConsent:Mt,getConsent:Pe,hasConsent:Ee,registerLinks:Te,_version:h};window.artistPixel=Ht,window.balance=Ht;function $t(){tt&&!g&&new ge({style:Jt,primaryColor:Xt,position:Qt})}let Gt=window.requestIdleCallback||(t=>setTimeout(t,1));document.readyState==="loading"?document.addEventListener("DOMContentLoaded",()=>{zt(),Nt(),Gt(()=>$t())}):(zt(),Nt(),Gt(()=>$t())),a("Pixel script loaded")})();})();
102
+ `,this.shadow.getElementById("accept")?.addEventListener("click",()=>this.handleConsent(!0)),this.shadow.getElementById("decline")?.addEventListener("click",()=>this.handleConsent(!1))}handleConsent(e){window.balance?.setConsent&&window.balance.setConsent({analytics:e,marketing:e,personalization:e,timestamp:new Date().toISOString()}),e&&!window._balanceInitialPageviewFired&&(window._balanceInitialPageviewFired=!0,window.balance?.page&&window.balance.page(),ft(),a("Initial pageview fired after consent granted")),this.remove()}remove(){this.container&&(this.container.remove(),this.container=null,this.shadow=null,a("ConsentManager: Banner removed"))}}let Lt=!1,N=!1;function ue(){if(!O)return;if(window.fbq){a("[Platform:Meta] Already loaded, skipping");return}a("[Platform:Meta] Injecting pixel:",O);let t=function(...n){t.callMethod?t.callMethod.apply(t,n):t.queue.push(n)};window._fbq||(window._fbq=t),t.push=t,t.loaded=!0,t.version="2.0",t.queue=[],window.fbq=t;let e=document.createElement("script");e.async=!0,e.src="https://connect.facebook.net/en_US/fbevents.js",e.onload=()=>{window.fbq("init",O),f.pageview&&window.fbq("track","PageView"),a("[Platform:Meta] Initialized and PageView tracked")},document.head.appendChild(e)}function fe(){if(!E)return;if(window.ttq?._i?.[E]){a("[Platform:TikTok] Already loaded, skipping");return}a("[Platform:TikTok] Injecting pixel:",E);let t=window,e="ttq";t.TiktokAnalyticsObject=e;let n=t[e]=t[e]||[];n.methods=["page","track","identify","instances","debug","on","off","once","ready","alias","group","enableCookie","disableCookie","holdConsent","revokeConsent","grantConsent"],n.setAndDefer=function(o,c){o[c]=function(...d){o.push([c].concat(d))}};for(let o=0;o<n.methods.length;o++)n.setAndDefer(n,n.methods[o]);n.instance=function(o){let c=n._i[o]||[];for(let d=0;d<n.methods.length;d++)n.setAndDefer(c,n.methods[d]);return c},n.load=function(o){let c="https://analytics.tiktok.com/i18n/pixel/events.js";n._i=n._i||{},n._i[o]=[],n._i[o]._u=c,n._t=n._t||{},n._t[o]=+new Date,n._o=n._o||{};let d=document.createElement("script");d.type="text/javascript",d.async=!0,d.src=c+"?sdkid="+o+"&lib="+e,document.head.appendChild(d)},n.load(E),f.pageview&&n.page(),a("[Platform:TikTok] Initialized and page() tracked")}function me(){if(!w)return;if(window.dataLayer=window.dataLayer||[],typeof window.gtag!="function"&&(window.gtag=function(...e){window.dataLayer.push(e)}),document.querySelector('script[src*="googletagmanager.com/gtag/js"]')){a("[Platform:GoogleAds] gtag.js already loaded, configuring"),window.gtag("config",w);return}a("[Platform:GoogleAds] Injecting gtag:",w),window.gtag("consent","default",{ad_storage:"granted",ad_user_data:"granted",ad_personalization:"granted",analytics_storage:"granted"});let t=document.createElement("script");t.async=!0,t.src=`https://www.googletagmanager.com/gtag/js?id=${w}`,t.onload=()=>{window.gtag("js",new Date),window.gtag("config",w),a("[Platform:GoogleAds] Initialized")},document.head.appendChild(t)}function we(){if(!j)return;if(document.querySelector(`script[src*="googletagmanager.com/gtm.js?id=${j}"]`)){a("[Platform:GTM] Already loaded, skipping");return}a("[Platform:GTM] Injecting GTM:",j),window.dataLayer=window.dataLayer||[],typeof window.gtag!="function"&&(window.gtag=function(...n){window.dataLayer.push(n)});let t=N?"granted":"denied";window.gtag("consent","default",{ad_storage:t,ad_user_data:t,ad_personalization:t,analytics_storage:t}),window.gtag("set","wait_for_update",500),window.dataLayer.push({"gtm.start":new Date().getTime(),event:"gtm.js"});let e=document.createElement("script");e.async=!0,e.src=`https://www.googletagmanager.com/gtm.js?id=${j}`,e.onload=()=>{a("[Platform:GTM] Initialized")},document.head.appendChild(e)}function pe(){if(!p)return;let t=document.querySelector('script[src*="googletagmanager.com/gtag/js"]');window.dataLayer=window.dataLayer||[],typeof window.gtag!="function"&&(window.gtag=function(...o){window.dataLayer.push(o)});let e=N?"granted":"denied";if(window.gtag("consent","default",{ad_storage:e,ad_user_data:e,ad_personalization:e,analytics_storage:e}),t){a("[Platform:GA4] gtag.js already loaded, configuring"),window.gtag("config",p,{send_page_view:!1});return}a("[Platform:GA4] Injecting gtag:",p);let n=document.createElement("script");n.async=!0,n.src=`https://www.googletagmanager.com/gtag/js?id=${p}`,n.onload=()=>{window.gtag("js",new Date),window.gtag("config",p,{send_page_view:!1}),a("[Platform:GA4] Initialized")},document.head.appendChild(n)}function he(){if(U){if(Lt){a("[Platform] Already loaded, skipping");return}if(!N){a("[Platform] Marketing consent not granted, deferring");return}a("[Platform] Injecting platform pixels (consent granted)"),Lt=!0,ue(),fe(),me(),we(),pe()}}function At(t){if(N=t,a("[Platform] Marketing consent:",t?"granted":"denied"),t&&he(),window.ttq&&(t?window.ttq.grantConsent?.():window.ttq.revokeConsent?.()),typeof window.gtag=="function"){let e=t?"granted":"denied";window.gtag("consent","update",{ad_storage:e,ad_user_data:e,ad_personalization:e,analytics_storage:e})}}function lt(t){if(!U||!N)return!1;let e=t.toLowerCase();return e==="pageview"||e==="page_view"?f.pageview:e==="purchase"?f.purchase:e==="addtocart"||e==="add_to_cart"?f.addToCart:e==="lead"||e==="form_submit"?f.lead:e==="viewcontent"||e==="view_content"?f.viewContent:e==="initiatecheckout"||e==="initiate_checkout"?f.initiateCheckout:e==="completeregistration"||e==="complete_registration"?f.completeRegistration:e==="subscribe"?f.subscribe:e==="search"?f.search:e==="contact"?f.contact:f.custom.length>0?f.custom.some(n=>n.toLowerCase()===e):!1}function ye(){lt("pageview")&&(a("[Platform] Forwarding PageView"),window.fbq&&window.fbq("track","PageView"),window.ttq&&window.ttq.page(),typeof window.gtag=="function"&&p&&window.gtag("event","page_view",{send_to:p}))}function be(t,e,n){if(lt("purchase")){if(a("[Platform] Forwarding Purchase:",t,e),window.fbq&&window.fbq("track","Purchase",{value:t,currency:e,content_ids:n?.contentIds,content_type:n?.contentType||"product",order_id:n?.transactionId}),window.ttq&&window.ttq.track("CompletePayment",{value:t,currency:e,order_id:n?.transactionId}),typeof window.gtag=="function"&&w){let o=kt?`${w}/${kt}`:w;window.gtag("event","conversion",{send_to:o,value:t,currency:e,transaction_id:n?.transactionId}),window.gtag("event","purchase",{send_to:w,value:t,currency:e,transaction_id:n?.transactionId})}typeof window.gtag=="function"&&p&&window.gtag("event","purchase",{send_to:p,value:t,currency:e,transaction_id:n?.transactionId,items:n?.items})}}function ve(t,e){if(!lt(t))return;let n=t.toLowerCase();a("[Platform] Forwarding custom event:",t);let o={addtocart:"AddToCart",add_to_cart:"AddToCart",lead:"Lead",form_submit:"Lead",viewcontent:"ViewContent",view_content:"ViewContent",search:"Search",subscribe:"Subscribe",contact:"Contact",completeregistration:"CompleteRegistration",complete_registration:"CompleteRegistration",initiatecheckout:"InitiateCheckout",initiate_checkout:"InitiateCheckout"},c={addtocart:"AddToCart",add_to_cart:"AddToCart",lead:"SubmitForm",form_submit:"SubmitForm",viewcontent:"ViewContent",view_content:"ViewContent",search:"Search",subscribe:"Subscribe",contact:"Contact",completeregistration:"CompleteRegistration",complete_registration:"CompleteRegistration",initiatecheckout:"InitiateCheckout",initiate_checkout:"InitiateCheckout"},d={addtocart:"add_to_cart",add_to_cart:"add_to_cart",lead:"generate_lead",form_submit:"generate_lead",viewcontent:"view_item",view_content:"view_item",search:"search",subscribe:"subscribe",contact:"contact",completeregistration:"sign_up",complete_registration:"sign_up",initiatecheckout:"begin_checkout",initiate_checkout:"begin_checkout"};if(window.fbq){let s=o[n];s?window.fbq("track",s,e):window.fbq("trackCustom",t,e)}if(window.ttq){let s=c[n]||t;window.ttq.track(s,e)}if(typeof window.gtag=="function"&&w){let s=d[n]||t;window.gtag("event",s,{send_to:w,...e})}if(typeof window.gtag=="function"&&p){let s=d[n]||t;window.gtag("event",s,{send_to:p,...e})}}function Rt(){try{return x==="local"?localStorage:sessionStorage}catch{return null}}function B(t){let e=Rt();if(!e)return null;try{let n=_+t,o=e.getItem(n);if(!o&&x==="session")try{o=localStorage.getItem(n)}catch{}return o}catch{return null}}function M(t,e){let n=Rt();if(n)try{n.setItem(_+t,e)}catch{}}function Dt(){if(x!=="local"){a("Upgrading storage tier: session -> local");try{let t=[];for(let e=0;e<sessionStorage.length;e++){let n=sessionStorage.key(e);n?.startsWith(_)&&t.push(n)}for(let e of t){let n=sessionStorage.getItem(e);n&&localStorage.setItem(e,n)}for(let e of t)sessionStorage.removeItem(e);x="local",a(`Storage tier upgraded, migrated ${t.length} items`)}catch(t){C(" Storage migration failed:",t)}}}function W(){return crypto&&crypto.randomUUID?crypto.randomUUID():"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,t=>{let e=Math.random()*16|0;return(t==="x"?e:e&3|8).toString(16)})}function _e(){try{let t=B(Ct),e=B(et);if(t&&e&&Date.now()-parseInt(e,10)<ae)return M(et,Date.now().toString()),t;let n=W();return M(Ct,n),M(et,Date.now().toString()),n}catch{return W()}}function ke(){let t=new URLSearchParams(window.location.search),e={};return["source","medium","campaign","content","term"].forEach(n=>{let o=t.get(`utm_${n}`);o&&(e[`utm_${n}`]=o)}),e}function xe(){try{let t=B(St);if(t){A=JSON.parse(t),a("Loaded attribution:",A);return}let e=ke();Object.keys(e).length>0&&(A=e,M(St,JSON.stringify(e)),a("Captured attribution:",A))}catch{}}function Ie(){try{m=localStorage.getItem(_+T),m&&a("Loaded fan ID hash:",m.substring(0,16)+"...")}catch{try{m=B(T)}catch{}}}function gt(){try{let t=localStorage.getItem(_+nt);if(t)return t;let e=W();return localStorage.setItem(_+nt,e),a("Created persistent visitor ID:",e.substring(0,8)+"..."),e}catch{return a("localStorage unavailable, using session ID as fallback"),q||W()}}function Ce(){try{h=localStorage.getItem(_+nt),h&&a("Loaded visitor ID:",h.substring(0,8)+"...")}catch{}}function Se(){try{let t=localStorage.getItem(G);if(t){let e=JSON.parse(t);if(e.expiresAt&&Date.now()>e.expiresAt){a("Consent expired - clearing stored consent"),localStorage.removeItem(G),u=null;return}if(e.expiresAt){let n=e.expiresAt-Date.now();n>0&&n<ne&&(a("Consent nearing expiration - will prompt for refresh"),window._balanceConsentNeedsRefresh=!0)}u=e.preferences||null,a("Loaded consent:",u)}}catch{}}function Mt(t){let e=u;u=t;try{let o={preferences:t,method:"explicit",version:1,expiresAt:Date.now()+ee};localStorage.setItem(G,JSON.stringify(o)),a("Consent saved with TTL:",t),window._balanceConsentNeedsRefresh=!1}catch(o){C(" Could not save consent:",o)}t.analytics===!0&&(Dt(),h||(h=gt()));let n=S({event_name:"consent_updated",metadata:{consent_preferences:t,consent_method:"explicit",previous_consent:e||void 0}});P(n);try{window.dispatchEvent(new CustomEvent("artistPixel:consent:updated",{detail:t})),a("DOM event artistPixel:consent:updated dispatched")}catch{}U&&At(t.marketing===!0)}function Pe(){return u}function Ee(t){return u?.[t]===!0}function Te(t){for(let[e,n]of Object.entries(t))try{let o=Ot(e);at[o]=n}catch{at[e]=n}a("Registered",Object.keys(t).length,"links for tracking enrichment")}function Ot(t){try{let e=new URL(t);return`${e.protocol}//${e.host}${e.pathname}${e.search}`}catch{return t}}function Le(t){let e=Ot(t);return at[e]||null}async function Ae(t){let e=t.toLowerCase().trim(),o=new TextEncoder().encode(e),c=await crypto.subtle.digest("SHA-256",o);return Array.from(new Uint8Array(c)).map(s=>s.toString(16).padStart(2,"0")).join("")}function S(t){let e=Kt(),n={artist_id:Y,fan_session_id:q,visitor_id:h||gt(),fan_id_hash:m||void 0,timestamp:new Date().toISOString(),source_url:window.location.href,referrer_url:document.referrer||void 0,user_agent:navigator.userAgent,device_type:e.device_type,browser:e.browser,os:e.os,tracking_source:V,...t,...A};return X&&!t.projectId&&(n.projectId=X),n}function P(t){k.push(t),a("Event queued:",t.event_name,"(queue:",k.length,")"),k.length>=10&&H()}async function H(){if(k.length===0)return;let t=[...k];k=[],a("Flushing",t.length,"events to",L);try{let e=await fetch(L,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({events:t}),keepalive:!0});if(!e.ok)throw new Error(`HTTP ${e.status}`);a("Events sent successfully")}catch(e){if(C(" Failed to send events, trying fallback:",e),L!==Et&&!Q)try{if((await fetch(Et,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({events:t}),keepalive:!0})).ok){a("Events sent via fallback (no geo)");return}}catch(n){C(" Fallback also failed:",n)}k.length<50&&k.push(...t)}}function Re(){ot&&clearInterval(ot),ot=window.setInterval(()=>{k.length>0&&H()},5e3)}function ut(){D||(it=Date.now()),D=Date.now(),F=!0,a("Active time tracking started/resumed")}function jt(){D&&F&&(rt+=Date.now()-D),F=!1,a("Active time tracking paused, accumulated:",rt,"ms")}function Ut(){let t=rt;return F&&D&&(t+=Date.now()-D),t}function De(){Tt=Date.now(),z&&(z=!1,ut(),a("User returned from idle"))}function Me(){if(document.visibilityState==="hidden"){a("Skipping heartbeat - tab hidden");return}if(Date.now()-Tt>de){z||(z=!0,jt(),a("User idle - pausing heartbeat"));return}let t=Ut(),e=Math.round(t/1e3),n=S({event_name:"engagement_heartbeat",metadata:{time_on_page_seconds:e,time_on_page_ms:t,heartbeat_interval_ms:Z,is_active:F&&!z}});P(n),st++,a("Heartbeat sent:",e,"seconds active")}function ft(){if(!bt){a('Heartbeat disabled via data-heartbeat="false"');return}R&&clearInterval(R),ut(),R=window.setInterval(()=>{Me()},Z),a("Heartbeat started with interval:",Z,"ms")}function mt(){if(!ct){if(ct=!0,R&&(clearInterval(R),R=null),bt){let t=it?Date.now()-it:0,e=Ut(),n=S({event_name:"engagement_summary",metadata:{total_time_ms:t,active_time_ms:e,heartbeat_samples:st,page_path:window.location.pathname}});if(navigator.sendBeacon&&L){let o=JSON.stringify({events:[n]});navigator.sendBeacon(L,o),a("Engagement summary sent via sendBeacon:",Math.round(e/1e3),"seconds active")}else P(n),a("Engagement summary enqueued:",Math.round(e/1e3),"seconds active")}st=0}}function $(t={}){let e=t.url||window.location.href;if(ie(e)){a("Page excluded from tracking:",e);return}let n=S({event_name:"pageview",page_title:t.title||document.title,source_url:e});P(n),ye()}function wt(t,e={}){let n=S({event_name:"custom",metadata:{event_type:t,...e}});P(n),ve(t,e)}async function qt(t,e={}){try{if(u&&u.analytics===!1){a("Identify skipped - user declined analytics consent");return}m=await Ae(t),u?.analytics===!0&&Dt();try{localStorage.setItem(_+T,m)}catch{M(T,m)}let n=t.split("@"),o=n[0].charAt(0)+"***@"+(n[1]||"");a("Fan identified:",{name:e.name||"(no name)",email:o,hash:m.substring(0,16)+"...",traits:e,storageTier:x});let c=S({event_name:"identify",fan_id_hash:m,metadata:{email_sha256:m,email_display:o,traits:e,consent_preferences:u||void 0,storage_tier:x}});P(c)}catch(n){C(" Failed to identify:",n)}}function Oe(t){if(!t||typeof t!="string"){C("setFanIdHash: invalid hash provided");return}m=t;try{localStorage.setItem(_+T,t),a("Fan ID hash set from server:",t.substring(0,16)+"...")}catch{M(T,t)}}function Ft(t,e="USD",n={}){let o=S({event_name:"purchase",metadata:{revenue:t,currency:e,...n}});P(o),be(t,e,n)}function zt(){V=te(),a("Tracking source detected:",V),Se(),u?.analytics===!0?(x="local",a("Storage tier: local (analytics consent granted)")):(x="session",a("Storage tier: session (privacy by default)")),q=_e(),Ie(),Ce(),h||(h=gt()),u||a(tt?"Consent UI enabled, waiting for explicit user consent (Tier 0 mode)":"No consent - operating in privacy-first mode (session storage only, limited tracking)"),U&&u?.marketing===!0?(a("[Platform] Marketing consent already granted, initializing platform pixels"),At(!0)):U&&a("[Platform] Platform pixels configured:",{meta:O||"(none)",tiktok:E||"(none)",googleAds:w||"(none)"}),xe(),Re(),a("Initialized",{artistId:Y,projectId:X||"(none - will track to all projects)",rawProjectId:J||"(none)",sessionId:q,visitorId:h?h.substring(0,8)+"...":null,fanIdHash:m,consent:u,storageTier:x,trackingSource:V,useEmulator:Q,endpoint:L}),u?.analytics===!0?(window._balanceInitialPageviewFired=!0,$(),ft(),a("Full tracking enabled (user consented)")):tt?a("Tracking dormant - waiting for explicit consent via ConsentManager"):(window._balanceInitialPageviewFired=!0,$(),ft(),a("Privacy-first tracking enabled (session-scoped, visitor_id for deduplication)")),["mousemove","keydown","scroll","touchstart"].forEach(s=>{document.addEventListener(s,De,{passive:!0})});let t=window.location.hostname;function e(s){try{let i=new URL(s).hostname.toLowerCase();return i.includes("spotify")?"spotify":i.includes("apple")||i.includes("music.apple")?"apple_music":i.includes("youtube")||i.includes("youtu.be")?"youtube":i.includes("soundcloud")?"soundcloud":i.includes("tidal")?"tidal":i.includes("deezer")?"deezer":i.includes("amazon")||i.includes("music.amazon")?"amazon_music":i.includes("bandcamp")?"bandcamp":i.includes("lnk.to")||i.includes("linkfire")?"linkfire":i.includes("linktr.ee")?"linktree":i.includes("shop")||i.includes("store")||i.includes("merch")?"shop":i.includes("ticketmaster")||i.includes("eventbrite")||i.includes("dice.fm")?"tickets":i.includes("instagram")?"instagram":i.includes("twitter")||i.includes("x.com")?"twitter":i.includes("tiktok")?"tiktok":i.includes("facebook")?"facebook":"external"}catch{return"external"}}function n(s){try{return new URL(s,window.location.origin).hostname!==t}catch{return!1}}function o(s,i){let l=e(s),I=Le(s),Gt=I?.title||i?.textContent?.trim().substring(0,100)||"",Bt=I?.id||i?.id||i?.getAttribute("data-link-id")||void 0,Wt=I?.category;a("External link clicked:",{url:s,platform:l,linkText:Gt,linkId:Bt,fromRegistry:!!I}),wt("page_link_click",{link_url:s,link_text:Gt,link_id:Bt,platform:l,link_type:"external",...Wt&&{link_category:Wt},...I&&Object.fromEntries(Object.entries(I).filter(([ht])=>!["title","id","category"].includes(ht)).map(([ht,je])=>[`link_${ht}`,je]))})}let c=window.open;if(window.open=function(s,i,l){if(s){let I=s.toString();n(I)&&o(I)}return c.call(window,s,i,l)},a("window.open interception enabled (always on)"),r?.dataset.autoTrackLinks==="true"&&(document.addEventListener("click",s=>{let l=s.target.closest("a");if(l&&l.href&&n(l.href)){if(It&&(Pt(l.href)||l.hasAttribute("download")))return;o(l.href,l)}},{capture:!0,passive:!0}),a("External link click listener enabled (opt-in)")),It&&(document.addEventListener("click",s=>{let l=s.target.closest("a");l?.href&&(Pt(l.href)||l.hasAttribute("download"))&&se(l.href,l)},{capture:!0,passive:!0}),a("File download tracking enabled")),Zt){let s=window.location.href;window.addEventListener("hashchange",()=>{let i=window.location.href;i!==s&&(s=i,setTimeout(()=>{$({title:document.title,url:i})},0))}),a("Hash routing tracking enabled")}document.addEventListener("visibilitychange",()=>{document.visibilityState==="hidden"?(jt(),mt(),H()):(ut(),ct=!1)}),window.addEventListener("pagehide",()=>{mt(),H()}),window.addEventListener("beforeunload",()=>{mt(),H()})}if(window.balance?._version&&window.balance._version!==b){console.warn(`[artistPixel] Version conflict: ${window.balance._version} already loaded, skipping ${b}`);return}let pt=window.balance?.q||[];function Nt(){if(pt.length>0){a("Processing",pt.length,"queued commands");for(let t of pt){let[e,...n]=t;switch(e){case"track":wt(n[0],n[1]);break;case"identify":qt(n[0],n[1]);break;case"page":$(n[0]);break;case"purchase":Ft(n[0],n[1],n[2]);break;case"setConsent":Mt(n[0]);break;default:a("Unknown queued command:",e)}}}}let Ht={track:wt,identify:qt,page:$,purchase:Ft,getSessionId:()=>q,getVisitorId:()=>h,getFanIdHash:()=>m,setFanIdHash:Oe,getAttribution:()=>A,setConsent:Mt,getConsent:Pe,hasConsent:Ee,registerLinks:Te,_version:b};window.artistPixel=Ht,window.balance=Ht;function $t(){tt&&!u&&new ge({style:Jt,primaryColor:Xt,position:Qt})}let Vt=window.requestIdleCallback||(t=>setTimeout(t,1));document.readyState==="loading"?document.addEventListener("DOMContentLoaded",()=>{zt(),Nt(),Vt(()=>$t())}):(zt(),Nt(),Vt(()=>$t())),a("Pixel script loaded")})();})();
@@ -131,13 +131,13 @@ export declare const identify: (email: string, traits?: Record<string, any>) =>
131
131
  export declare const page: (options?: { title?: string; url?: string }) => void;
132
132
  export declare const purchase: (revenue: number, currency?: string, properties?: Record<string, any>) => void;
133
133
  export declare const getSessionId: () => string | null;
134
- export declare const getVisitorId: () => string | null;
135
134
  export declare const getFanIdHash: () => string | null;
136
- export declare const setFanIdHash: (hash: string) => void;
137
135
  export declare const getAttribution: () => Record<string, string>;
138
136
  export declare const setConsent: (preferences: ConsentPreferences) => void;
139
137
  export declare const getConsent: () => ConsentPreferences | null;
140
138
  export declare const hasConsent: (type: 'analytics' | 'marketing' | 'personalization') => boolean;
139
+ export declare const getVisitorId: () => string | null;
140
+ export declare const setFanIdHash: (hash: string) => void;
141
141
 
142
142
  // ============================================
143
143
  // GTM Integration
package/dist/index.js CHANGED
@@ -1591,6 +1591,24 @@ function ArtistPixelProvider({
1591
1591
  trackFileDownloads = false,
1592
1592
  hashRouting = false,
1593
1593
  integrity,
1594
+ // Third-party pixels
1595
+ metaPixelId,
1596
+ tiktokPixelId,
1597
+ googleAdsId,
1598
+ googleAdsConversionLabel,
1599
+ googleAnalyticsId,
1600
+ // Event forwarding
1601
+ forwardPageview = true,
1602
+ forwardPurchase = true,
1603
+ forwardAddToCart = true,
1604
+ forwardLead = true,
1605
+ forwardViewContent = true,
1606
+ forwardInitiateCheckout = true,
1607
+ forwardCompleteRegistration = true,
1608
+ forwardSubscribe = true,
1609
+ forwardSearch = true,
1610
+ forwardContact = true,
1611
+ forwardCustom,
1594
1612
  children
1595
1613
  }) {
1596
1614
  const [isReady, setIsReady] = (0, import_react11.useState)(false);
@@ -1758,6 +1776,22 @@ function ArtistPixelProvider({
1758
1776
  "data-exclude-pages": exclude?.join(",") || void 0,
1759
1777
  "data-track-file-downloads": trackFileDownloads ? "true" : void 0,
1760
1778
  "data-hash-routing": hashRouting ? "true" : void 0,
1779
+ "data-meta-pixel-id": metaPixelId,
1780
+ "data-tiktok-pixel-id": tiktokPixelId,
1781
+ "data-google-ads-id": googleAdsId,
1782
+ "data-google-ads-conversion-label": googleAdsConversionLabel,
1783
+ "data-google-analytics-id": googleAnalyticsId,
1784
+ "data-forward-pageview": forwardPageview ? void 0 : "false",
1785
+ "data-forward-purchase": forwardPurchase ? void 0 : "false",
1786
+ "data-forward-add-to-cart": forwardAddToCart ? void 0 : "false",
1787
+ "data-forward-lead": forwardLead ? void 0 : "false",
1788
+ "data-forward-view-content": forwardViewContent ? void 0 : "false",
1789
+ "data-forward-initiate-checkout": forwardInitiateCheckout ? void 0 : "false",
1790
+ "data-forward-complete-registration": forwardCompleteRegistration ? void 0 : "false",
1791
+ "data-forward-subscribe": forwardSubscribe ? void 0 : "false",
1792
+ "data-forward-search": forwardSearch ? void 0 : "false",
1793
+ "data-forward-contact": forwardContact ? void 0 : "false",
1794
+ "data-forward-custom": forwardCustom?.join(",") || void 0,
1761
1795
  integrity,
1762
1796
  crossOrigin: integrity ? "anonymous" : void 0,
1763
1797
  strategy: "afterInteractive",
package/dist/index.mjs CHANGED
@@ -1507,6 +1507,24 @@ function ArtistPixelProvider({
1507
1507
  trackFileDownloads = false,
1508
1508
  hashRouting = false,
1509
1509
  integrity,
1510
+ // Third-party pixels
1511
+ metaPixelId,
1512
+ tiktokPixelId,
1513
+ googleAdsId,
1514
+ googleAdsConversionLabel,
1515
+ googleAnalyticsId,
1516
+ // Event forwarding
1517
+ forwardPageview = true,
1518
+ forwardPurchase = true,
1519
+ forwardAddToCart = true,
1520
+ forwardLead = true,
1521
+ forwardViewContent = true,
1522
+ forwardInitiateCheckout = true,
1523
+ forwardCompleteRegistration = true,
1524
+ forwardSubscribe = true,
1525
+ forwardSearch = true,
1526
+ forwardContact = true,
1527
+ forwardCustom,
1510
1528
  children
1511
1529
  }) {
1512
1530
  const [isReady, setIsReady] = useState4(false);
@@ -1674,6 +1692,22 @@ function ArtistPixelProvider({
1674
1692
  "data-exclude-pages": exclude?.join(",") || void 0,
1675
1693
  "data-track-file-downloads": trackFileDownloads ? "true" : void 0,
1676
1694
  "data-hash-routing": hashRouting ? "true" : void 0,
1695
+ "data-meta-pixel-id": metaPixelId,
1696
+ "data-tiktok-pixel-id": tiktokPixelId,
1697
+ "data-google-ads-id": googleAdsId,
1698
+ "data-google-ads-conversion-label": googleAdsConversionLabel,
1699
+ "data-google-analytics-id": googleAnalyticsId,
1700
+ "data-forward-pageview": forwardPageview ? void 0 : "false",
1701
+ "data-forward-purchase": forwardPurchase ? void 0 : "false",
1702
+ "data-forward-add-to-cart": forwardAddToCart ? void 0 : "false",
1703
+ "data-forward-lead": forwardLead ? void 0 : "false",
1704
+ "data-forward-view-content": forwardViewContent ? void 0 : "false",
1705
+ "data-forward-initiate-checkout": forwardInitiateCheckout ? void 0 : "false",
1706
+ "data-forward-complete-registration": forwardCompleteRegistration ? void 0 : "false",
1707
+ "data-forward-subscribe": forwardSubscribe ? void 0 : "false",
1708
+ "data-forward-search": forwardSearch ? void 0 : "false",
1709
+ "data-forward-contact": forwardContact ? void 0 : "false",
1710
+ "data-forward-custom": forwardCustom?.join(",") || void 0,
1677
1711
  integrity,
1678
1712
  crossOrigin: integrity ? "anonymous" : void 0,
1679
1713
  strategy: "afterInteractive",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hifilabs/pixel",
3
- "version": "0.15.1",
3
+ "version": "0.16.1",
4
4
  "description": "artistPixel - Lightweight browser tracking script for artist fan analytics",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.mjs",