From d4516b658fcf9e581494f4e54fd76c458b0d1a98 Mon Sep 17 00:00:00 2001 From: Jaissica Date: Thu, 27 Aug 2026 14:10:24 -0400 Subject: [PATCH] chore(build): generate kit dist files --- kits/rokt/dist/Rokt-Kit.common.js | 2 +- kits/rokt/dist/Rokt-Kit.common.js.map | 2 +- kits/rokt/dist/Rokt-Kit.d.ts | 34 + kits/rokt/dist/Rokt-Kit.esm.js | 873 +++++++++++++++++--------- kits/rokt/dist/Rokt-Kit.esm.js.map | 2 +- kits/rokt/dist/Rokt-Kit.iife.js | 3 +- kits/rokt/dist/Rokt-Kit.iife.js.map | 2 +- 7 files changed, 609 insertions(+), 309 deletions(-) diff --git a/kits/rokt/dist/Rokt-Kit.common.js b/kits/rokt/dist/Rokt-Kit.common.js index c174b6984..4afad0442 100644 --- a/kits/rokt/dist/Rokt-Kit.common.js +++ b/kits/rokt/dist/Rokt-Kit.common.js @@ -1,2 +1,2 @@ -"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const B=["billingaddress1","billingaddress2","billingcity","billingstate","billingzipcode","cartitems","ccbin","confirmationref","conversiontype","country","couponcode","currency","language","paymentserviceprovider","paymentserviceproviderattribute","paymenttype","shippingaddress1","shippingcity","shippingcountry","shippingmethod","shippingstate","shippingzipcode","totalprice"],J=new Set(B);function G(n){return J.has(n.toLowerCase())}function w(n){const t={},e=n||{},i=Object.keys(e);for(let r=0;r=$)return;const r=window.__rokt_li_guid__;if(!r)return;const s=window.location.href.split("?")[0].split("#")[0],o="version="+encodeURIComponent(t??"")+"&launcherInstanceGuid="+encodeURIComponent(r)+"&pageUrl="+encodeURIComponent(s);O("https://"+(n||"apps.rokt.com")+"/v1/wsdk-init/index.html?"+o),O("https://"+X+"/v1/wsdk-init/index.html?"+o+"&isControl=true")}function ut(){return typeof window<"u"&&!!window.location?.search?.toLowerCase().includes("mp_enable_logging=true")}function dt(){return typeof window<"u"?window.location?.href:void 0}function ht(){return typeof window<"u"?window.navigator?.userAgent:void 0}class q{constructor(){this._logCount={}}incrementAndCheck(t){const i=(this._logCount[t]||0)+1;return this._logCount[t]=i,i>at}}class C{constructor(t,e,i,r,s){this._reporter="mp-wsdk";const o=t.isLoggingEnabled;this._integrationName=e||"",this._launcherInstanceGuid=i,this._accountId=r||null,this._rateLimiter=s||new q,this._isEnabled=ut()||o}send(t,e,i,r,s,o){if(!(!this._isEnabled||this._rateLimiter.incrementAndCheck(e)))try{const c={additionalInformation:{message:i,version:this._integrationName},severity:e,code:r||N.UNKNOWN_ERROR,url:dt(),deviceInfo:ht(),stackTrace:s,reporter:this._reporter,integration:this._integrationName},u={Accept:"text/plain;charset=UTF-8","Content-Type":"application/json","rokt-launcher-version":this._integrationName,"rokt-wsdk-version":"joint"};this._launcherInstanceGuid&&(u["rokt-launcher-instance-guid"]=this._launcherInstanceGuid),this._accountId&&(u["rokt-account-id"]=this._accountId),fetch(t,{method:"POST",headers:u,body:JSON.stringify(c)}).then(l=>{if(!l.ok){const h=new Error("HTTP "+l.status+" from log endpoint");throw h.statusCode=l.status,h}}).catch(l=>{console.error("ReportingTransport: Failed to send log",l),o&&o(l)})}catch(c){console.error("ReportingTransport: Failed to send log",c),o&&o(c)}}}class H{constructor(t,e,i,r,s){this._transport=new C(t,e,i,r,s),this._errorUrl=z(t?.errorUrl,t?.integrationDomain,ot)}report(t){if(!t)return;const e=t.severity||I.ERROR;this._transport.send(this._errorUrl,e,t.message,t.code,t.stackTrace)}}class W{constructor(t,e,i,r,s,o){this._transport=new C(t,i,r,s,o),this._loggingUrl=z(t?.loggingUrl,t?.integrationDomain,st),this._errorReportingService=e}log(t){t&&this._transport.send(this._loggingUrl,I.INFO,t.message,t.code,void 0,e=>{if(this._errorReportingService){const i=typeof e.statusCode=="number";this._errorReportingService.report({message:"LoggingService: Failed to send log: "+e.message,code:N.LOG_DELIVERY_FAILURE,severity:i?I.ERROR:I.WARNING})}})}}const p=class p{constructor(){this.name=d,this.id=b,this.moduleId=b,this.isInitialized=!1,this.launcher=null,this.filters={},this.userAttributes={},this.userIdentifiedInWorkspace=!1,this.testHelpers=null,this.placementEventMappingLookup={},this.placementEventAttributeMappingLookup={},this.integrationName=null,this.errorReportingService=null,this.loggingService=null,this._thankYouElementOnLoadCallback=null,this._isThankYouElementLoaded=!1,this._workspaceSearchInFlightPromise=null}getEventAttributeValue(t,e){const i=t&&t.EventAttributes;return!i||typeof i[e]>"u"?null:i[e]}doesEventAttributeConditionMatch(t,e){if(!t||!m(t.operator))return!1;const i=t.operator.toLowerCase(),r=t.attributeValue;return i==="exists"?e!==null:e==null?!1:i==="equals"?String(e)===String(r):i==="contains"?String(e).indexOf(String(r))!==-1:!1}doesEventMatchRule(t,e){if(!e||!m(e.eventAttributeKey))return!1;const i=e.conditions;if(!Array.isArray(i))return!1;const r=this.getEventAttributeValue(t,e.eventAttributeKey);if(i.length===0)return r!==null;for(let s=0;s{await ct(i,c),this.initRoktLauncher(c)}).catch(c=>{console.error("Error creating Rokt launcher:",c)})}initRoktLauncher(t){window.Rokt&&(window.Rokt.currentLauncher=t),this.launcher=t;const e=a().Rokt?.filters;e?(this.filters=e,e.filteredUser?this._workspaceSearchInFlightPromise=this.search(e.filteredUser):console.warn("Rokt Kit: No filtered user has been set.")):console.warn("Rokt Kit: No filters have been set."),this.isInitialized=!0,F(this.domain,this.integrationName),a().Rokt.attachKit(this)}fetchOptimizely(){const t=a()._getActiveForwarders().filter(e=>e.name==="Optimizely");try{if(t.length>0&&window.optimizely){const e=window.optimizely.get("state");return!e||!e.getActiveExperimentIds?{}:e.getActiveExperimentIds().reduce((s,o)=>(s["rokt.custom.optimizely.experiment."+o+".variationId"]=e.getVariationMap()[o].id,s),{})}}catch(e){console.error("Error fetching Optimizely attributes:",e)}return{}}isKitReady(){return!!(this.isInitialized&&this.launcher)}isPartnerInLocalLauncherTestGroup(){return!!(a().config&&a().config.isLocalLauncherEnabled&&this.isAssignedToSampleGroup())}isAssignedToSampleGroup(){return Math.random()>.5}captureTiming(t){window&&a()&&a().captureTiming&&t&&a().captureTiming(t)}init(t,e,i,r,s){const o=t,c=o.accountId;this.userAttributes=w(s),this._onboardingExpProvider=o.onboardingExpProvider;const u=L(o.placementEventMapping);this.placementEventMappingLookup=x(u);const l=L(o.placementEventAttributeMapping);this.placementEventAttributeMappingLookup=Y(l),o.hashedEmailUserIdentityType&&(this._mappedEmailSha256Key=o.hashedEmailUserIdentityType.toLowerCase()),this._workspaceIdSyncApiKey=m(o.workspaceIdSyncApiKey)?o.workspaceIdSyncApiKey:void 0;const h=a().Rokt?.domain,{roktExtensionsQueryParams:v,legacyRoktExtensions:R,loadThankYouElement:A}=D(o.roktExtensions),g={...a().Rokt?.launcherOptions||{}};this.integrationName=lt(g.integrationName),g.integrationName=this.integrationName,this.domain=h;const _={loggingUrl:o.loggingUrl,errorUrl:o.errorUrl,integrationDomain:h,isLoggingEnabled:a().config?.isLoggingEnabled===!0},y=new H(_,this.integrationName,window.__rokt_li_guid__,o.accountId),S=new W(_,y,this.integrationName,window.__rokt_li_guid__,o.accountId);return this.errorReportingService=y,this.loggingService=S,a()._registerErrorReportingService&&a()._registerErrorReportingService(y),a()._registerLoggingService&&a()._registerLoggingService(S),i?(this.testHelpers={generateLauncherScript:U,generateThankYouElementScript:K,extractRoktExtensionConfig:D,hashEventMessage:j,parseSettingsString:L,generateMappedEventLookup:x,generateMappedEventAttributeLookup:Y,sendAdBlockMeasurementSignals:F,createAutoRemovedIframe:O,djb2:V,setAllowedOriginHashes:f=>{p._allowedOriginHashes=f},ReportingTransport:C,ErrorReportingService:H,LoggingService:W,RateLimiter:q,ErrorCodes:N,WSDKErrorSeverity:I},this.attachLauncher(c,g),"Successfully initialized: "+d):(A&&(a().Rokt.flushOnShoppableAdsReadyMessageQueue?.(this),M(et,K(h),{onLoad:()=>{this._isThankYouElementLoaded=!0,this._thankYouElementOnLoadCallback&&this._thankYouElementOnLoadCallback()},onError:f=>{console.error("Error loading Rokt Thank You Element script:",f)}})),this.isLauncherReadyToAttach()?this.attachLauncher(c,g,R):(M(tt,U(h,v),{onLoad:()=>{this.isLauncherReadyToAttach()?this.attachLauncher(c,g,R):console.error("Rokt object is not available after script load.")},onError:f=>{console.error("Error loading Rokt launcher script:",f)}}),this.captureTiming(p.PERFORMANCE_MARKS.RoktScriptAppended)),"Successfully initialized: "+d)}process(t){if(!this.isKitReady())return"Kit not ready for forwarder: "+d;if(typeof a().Rokt?.setLocalSessionAttribute=="function"&&(k(this.placementEventAttributeMappingLookup)||this.applyPlacementEventAttributeMapping(t),!k(this.placementEventMappingLookup))){const e=j(t.EventDataType,t.EventCategory,t.EventName??"");this.placementEventMappingLookup[String(e)]&&a().Rokt.setLocalSessionAttribute?.(this.placementEventMappingLookup[String(e)],!0)}return"Successfully sent to forwarder: "+d}setExtensionData(t){if(!this.isKitReady()){console.error("Rokt Kit: Not initialized");return}window.Rokt.setExtensionData(t)}setUserAttribute(t,e){return G(t)||(this.userAttributes[t]=e),"Successfully set user attribute for forwarder: "+d}removeUserAttribute(t){return delete this.userAttributes[t],"Successfully removed user attribute for forwarder: "+d}handleIdentityComplete(t,e){return this.userAttributes=w(t.getAllUserAttributes()),"Successfully called "+e+" for forwarder: "+d}onUserIdentified(t){const e=t;return this.filters.filteredUser=e,this._workspaceSearchInFlightPromise=this.search(e),this.handleIdentityComplete(t,"onUserIdentified")}search(t){const e=this._workspaceIdSyncApiKey;if(!e)return this.userIdentifiedInWorkspace=!1,this._workspaceLastSearchedIdentitiesKey=void 0,Promise.resolve();const i=a().Identity?.search;if(typeof i!="function")return this.userIdentifiedInWorkspace=!1,this._workspaceLastSearchedIdentitiesKey=void 0,Promise.resolve();const r=t.getUserIdentities?t.getUserIdentities().userIdentities:null,s={};if(r)for(const u of Object.keys(r)){const l=r[u];m(l)&&l.length>0&&(s[u]=l)}const o=Object.keys(s);if(o.length===0)return this.userIdentifiedInWorkspace=!1,this._workspaceLastSearchedIdentitiesKey=void 0,Promise.resolve();const c=o.sort().map(u=>`${u}=${s[u]}`).join("&");return c===this._workspaceLastSearchedIdentitiesKey?this._workspaceSearchInFlightPromise||Promise.resolve():(this.userIdentifiedInWorkspace=!1,this._workspaceLastSearchedIdentitiesKey=c,new Promise(u=>{try{i(e,s,l=>{l?.httpCode===200&&(this.userIdentifiedInWorkspace=!0),u()})}catch(l){console.error("Rokt Kit: Workspace IDSync search failed",l),this._workspaceLastSearchedIdentitiesKey=void 0,u()}}))}onLoginComplete(t,e){return this.handleIdentityComplete(t,"onLoginComplete")}onLogoutComplete(t,e){return this.userIdentifiedInWorkspace=!1,this._workspaceSearchInFlightPromise=null,this._workspaceLastSearchedIdentitiesKey=void 0,this.handleIdentityComplete(t,"onLogoutComplete")}onModifyComplete(t,e){return this.handleIdentityComplete(t,"onModifyComplete")}selectPlacements(t){if(this._workspaceSearchInFlightPromise){const e=this._workspaceSearchInFlightPromise;return Promise.race([e,new Promise(i=>setTimeout(i,nt))]).then(()=>this._dispatchPlacements(t))}return this._dispatchPlacements(t)}_dispatchPlacements(t){const e=t&&t.attributes||{},r={...w(this.userAttributes),...e},s=this.filters||{},o=s.userAttributeFilters||[],c=s.filteredUser||null,u=c?c.getMPID():null;let l;s?s.filterUserAttributes?l=s.filterUserAttributes(r,o):l=r:(console.warn("Rokt Kit: No filters available, using user attributes"),l=r),this.userAttributes=w(l);const h=this._onboardingExpProvider==="Optimizely"?this.fetchOptimizely():{},v=this.returnUserIdentities(c),R=this.returnLocalSessionAttributes(),A={...v,...l,...h,...R,...this.userIdentifiedInWorkspace?{[it]:!0}:{},mpid:u},g={...t,attributes:A},_=this.launcher.selectPlacements(g),y=()=>this.logSelectPlacementsEvent(A);return Promise.resolve(_).then(S=>S?.context?.sessionId?.then(f=>this.setRoktSessionId(f))).catch(()=>{}).finally(y),_}hashAttributes(t){return this.isKitReady()?this.launcher.hashAttributes(t):(console.error("Rokt Kit: Not initialized"),null)}use(t){return this.isKitReady()?!t||!m(t)?Promise.reject(new Error("Rokt Kit: Invalid extension name")):this.launcher.use(t):(console.error("Rokt Kit: Not initialized"),Promise.reject(new Error("Rokt Kit: Not initialized")))}onShoppableAdsReady(t){this._isThankYouElementLoaded?t():this._thankYouElementOnLoadCallback=t}};p._allowedOriginHashes=[-553112570,549508659],p.PERFORMANCE_MARKS={RoktScriptAppended:"mp:RoktScriptAppended"},p.EMAIL_SHA256_KEY="emailsha256";let E=p;function pt(){return b}function gt(n){if(!n){window.console.log("You must pass a config object to register the kit "+d);return}if(!T(n)){window.console.log("'config' must be an object. You passed in a "+typeof n);return}T(n.kits)?n.kits[d]={constructor:E}:(n.kits={},n.kits[d]={constructor:E}),window.console.log("Successfully registered "+d+" to your mParticle configuration")}typeof window<"u"&&window.mParticle&&a().addForwarder&&a().addForwarder({name:d,constructor:E,getId:pt});exports.register=gt; +"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const me=["active_time_on_site_ms","billingaddress1","billingaddress2","billingcity","billingstate","billingzipcode","cartitems","ccbin","confirmationref","conversiontype","country","couponcode","currency","language","paymentserviceprovider","paymentserviceproviderattribute","paymenttype","shippingaddress1","shippingcity","shippingcountry","shippingmethod","shippingstate","shippingzipcode","totalprice"],Ee=new Set(me);function re(i){return Ee.has(i.toLowerCase())}function w(i){const e={},t=i||{},n=Object.keys(t);for(let r=0;r{const r=t.activeTimeOnSite,s=r!==void 0&&Number.isFinite(r),c=e[n+1]?.activeTimeOnSite,u=c!==void 0&&Number.isFinite(c),l=s&&u?c-r:void 0;return{pageUrl:t.pageUrl,sourceMessageId:t.sourceMessageId,timestamp:t.timestamp,...t.pageTitle!==void 0?{pageTitle:t.pageTitle}:{},...t.canonicalUrl!==void 0?{canonicalUrl:t.canonicalUrl}:{},...s?{activeTimeOnSite:r}:{},...l!==void 0&&l>=0?{activeTimeOnPage:l}:{}}})}function Ae(i){if(D(_,P)!==void 0)return;const e=new URLSearchParams(window.location.search),t={};for(const r of Ie){const s=e.get(r);s&&(t[r]=s)}if(Object.keys(t).length===0)return;const n=Object.keys(t).join(", ");if(!oe(_,P,t)){const r=C()?"quota":"ls_unavailable";i?.log({message:`Rokt Kit: Failed to persist UTM params [reason: ${r}]`,code:"UTM_CAPTURE_FAILED"});return}i?.log({message:`Rokt Kit: Captured UTM params [${n}]`,code:"UTM_CAPTURE_SUCCESS"})}function ke(){const i=D(_,P);return E(i)?i:null}function z(){ae(_,P)}function Re(){const e=document.querySelector('link[rel="canonical"]')?.href;if(e)return K(e)}function ve(){return{context:null,lifecycle:"idle",recreateInFlight:null}}function we(i,e){i.context={accountId:e.accountId,launcherOptions:{...e.launcherOptions},legacyRoktExtensions:[...e.legacyRoktExtensions]}}function be(i){i.lifecycle="attached"}function Te(i){i.lifecycle!=="idle"&&(i.lifecycle="terminated")}function Le(i){i.lifecycle="terminated"}function Pe(i){i.context=null,i.lifecycle="idle",i.recreateInFlight=null}function Oe(i,e,t){if(i.recreateInFlight)return i.recreateInFlight;if(i.lifecycle!=="terminated"||!i.context||!e)return;i.lifecycle="recreating";const n=i.context;return i.recreateInFlight=t(n).finally(()=>{i.recreateInFlight=null}),i.recreateInFlight}const d="Rokt",T=181,Ne="selectPlacements",Ue="apps.roktecommerce.com",Ce=.1,Me="ThankYouPageJourney",Ke="rokt-launcher",Fe="rokt-thank-you-element",De="userIdentifiedInWorkspace",xe=3,Ye=2,je="page_events",Ge="page_view_attributes",We="mparticle_session_id",He="mparticle_device_id",q=500,Y={UNKNOWN_ERROR:"UNKNOWN_ERROR",UNHANDLED_EXCEPTION:"UNHANDLED_EXCEPTION",IDENTITY_REQUEST:"IDENTITY_REQUEST",LOG_DELIVERY_FAILURE:"LOG_DELIVERY_FAILURE"},S={ERROR:"ERROR",INFO:"INFO",WARNING:"WARNING"},Ve="apps.rokt-api.com",ze="/v1/log",qe="/v1/errors",$e=10;function a(){return window.mParticle}function $(i,e){const n=[O(i),"/wsdk/integrations/launcher.js"].join("");return!e||e.length===0?n:n+"?extensions="+e.join(",")}function J(i){return[O(i),"/rokt-elements/rokt-element-thank-you.js"].join("")}function O(i){const e=typeof i<"u"?i:Ve;return e.includes("://")?e.replace(/\/+$/,""):["https://",e].join("")}function ue(i,e,t){if(i)return i.startsWith("http://")||i.startsWith("https://")?i:"https://"+i;const r=e?.includes("://")&&!/^https?:\/\//i.test(e)?void 0:e;return O(r)+t}function B(i,e,t){if(document.getElementById(i))return;const n=document.head||document.body,r=document.createElement("script");r.id=i,r.type="text/javascript",r.src=e,r.async=!0,r.crossOrigin="anonymous",r.fetchPriority="high",t?.onLoad&&(r.onload=t.onLoad),t?.onError&&(r.onerror=t.onError),n.appendChild(r)}function L(i){if(!i)return[];try{return JSON.parse(i.replace(/"/g,'"'))}catch{console.error("Settings string contains invalid JSON")}return[]}function Q(i){const e=i?L(i):[],t=[],n=[];let r=!1;for(let s=0;s=Ce)return;const r=window.__rokt_li_guid__;if(!r||i&&i.includes("://")&&!/^https:\/\//i.test(i))return;const s=window.location.href.split("?")[0].split("#")[0],o="version="+encodeURIComponent(e??"")+"&launcherInstanceGuid="+encodeURIComponent(r)+"&pageUrl="+encodeURIComponent(s),c=i?O(i):"https://apps.rokt.com";M(c+"/v1/wsdk-init/index.html?"+o),M("https://"+Ue+"/v1/wsdk-init/index.html?"+o+"&isControl=true")}function Qe(){return typeof window<"u"&&!!window.location?.search?.toLowerCase().includes("mp_enable_logging=true")}function Xe(){return typeof window<"u"?window.location?.href:void 0}function Ze(){return typeof window<"u"?window.navigator?.userAgent:void 0}class he{constructor(){this._logCount={}}incrementAndCheck(e){const n=(this._logCount[e]||0)+1;return this._logCount[e]=n,n>$e}}class j{constructor(e,t,n,r,s){this._reporter="mp-wsdk";const o=e.isLoggingEnabled;this._integrationName=t||"",this._launcherInstanceGuid=n,this._accountId=r||null,this._rateLimiter=s||new he,this._isEnabled=Qe()||o}send(e,t,n,r,s,o){if(!(!this._isEnabled||this._rateLimiter.incrementAndCheck(t)))try{const c={additionalInformation:{message:n,version:this._integrationName},severity:t,code:r||Y.UNKNOWN_ERROR,url:Xe(),deviceInfo:Ze(),stackTrace:s,reporter:this._reporter,integration:this._integrationName},u={Accept:"text/plain;charset=UTF-8","Content-Type":"application/json","rokt-launcher-version":this._integrationName,"rokt-wsdk-version":"joint"};this._launcherInstanceGuid&&(u["rokt-launcher-instance-guid"]=this._launcherInstanceGuid),this._accountId&&(u["rokt-account-id"]=this._accountId),fetch(e,{method:"POST",headers:u,body:JSON.stringify(c)}).then(l=>{if(!l.ok){const p=new Error("HTTP "+l.status+" from log endpoint");throw p.statusCode=l.status,p}}).catch(l=>{console.error("ReportingTransport: Failed to send log",l),o&&o(l)})}catch(c){console.error("ReportingTransport: Failed to send log",c),o&&o(c)}}}class ie{constructor(e,t,n,r,s){this._transport=new j(e,t,n,r,s),this._errorUrl=ue(e?.errorUrl,e?.integrationDomain,qe)}report(e){if(!e)return;const t=e.severity||S.ERROR;this._transport.send(this._errorUrl,t,e.message,e.code,e.stackTrace)}}class ne{constructor(e,t,n,r,s,o){this._transport=new j(e,n,r,s,o),this._loggingUrl=ue(e?.loggingUrl,e?.integrationDomain,ze),this._errorReportingService=t}log(e){e&&this._transport.send(this._loggingUrl,S.INFO,e.message,e.code,void 0,t=>{if(this._errorReportingService){const n=typeof t.statusCode=="number";this._errorReportingService.report({message:"LoggingService: Failed to send log: "+t.message,code:Y.LOG_DELIVERY_FAILURE,severity:n?S.ERROR:S.WARNING})}})}}function et(i){const e=K(window.location.href),t=i.EventAttributes?.title||document.title,n=Re(),r=i.ActiveTimeOnSite;return{pageUrl:e,sourceMessageId:i.SourceMessageId,timestamp:i.Timestamp,...t?{pageTitle:t}:{},...n!==void 0?{canonicalUrl:n}:{},...Number.isFinite(r)?{activeTimeOnSite:r}:{}}}const f=class f{constructor(){this.name=d,this.id=T,this.moduleId=T,this.isInitialized=!1,this.launcher=null,this.filters={},this.userAttributes={},this.userIdentifiedInWorkspace=!1,this.testHelpers=null,this.placementEventMappingLookup={},this.placementEventAttributeMappingLookup={},this.integrationName=null,this.errorReportingService=null,this.loggingService=null,this._thankYouElementOnLoadCallback=null,this._isThankYouElementLoaded=!1,this._workspaceSearchInFlightPromise=null,this._launcherAttachState=ve()}getEventAttributeValue(e,t){const n=e&&e.EventAttributes;return!n||typeof n[t]>"u"?null:n[t]}doesEventAttributeConditionMatch(e,t){if(!e||!m(e.operator))return!1;const n=e.operator.toLowerCase(),r=e.attributeValue;return n==="exists"?t!==null:t==null?!1:n==="equals"?String(t)===String(r):n==="contains"?String(t).indexOf(String(r))!==-1:!1}doesEventMatchRule(e,t){if(!t||!m(t.eventAttributeKey))return!1;const n=t.conditions;if(!Array.isArray(n))return!1;const r=this.getEventAttributeValue(e,t.eventAttributeKey);if(n.length===0)return r!==null;for(let s=0;s{await Je([...n],o),this.initRoktLauncher(o)}).catch(o=>{Le(this._launcherAttachState),console.error("Error creating Rokt launcher:",o)})}recreateLauncherIfTerminated(){return Oe(this._launcherAttachState,this.isLauncherReadyToAttach(),e=>this.attachLauncher(e.accountId,e.launcherOptions,e.legacyRoktExtensions))}initRoktLauncher(e){window.Rokt&&(window.Rokt.currentLauncher=e),this.launcher=e,be(this._launcherAttachState);const t=a().Rokt?.filters;t?(this.filters=t,t.filteredUser?this._workspaceSearchInFlightPromise=this.search(t.filteredUser):console.warn("Rokt Kit: No filtered user has been set.")):console.warn("Rokt Kit: No filters have been set."),this.isInitialized=!0,te(this.domain,this.integrationName),a().Rokt.attachKit(this)}fetchOptimizely(){const e=a()._getActiveForwarders().filter(t=>t.name==="Optimizely");try{if(e.length>0&&window.optimizely){const t=window.optimizely.get("state");return!t||!t.getActiveExperimentIds?{}:t.getActiveExperimentIds().reduce((s,o)=>(s["rokt.custom.optimizely.experiment."+o+".variationId"]=t.getVariationMap()[o].id,s),{})}}catch(t){console.error("Error fetching Optimizely attributes:",t)}return{}}isKitReady(){return!!(this.isInitialized&&this.launcher)}isTargetingDisabled(){return a().Rokt?.launcherOptions?.noTargeting===!0}isPartnerInLocalLauncherTestGroup(){return!!(a().config&&a().config.isLocalLauncherEnabled&&this.isAssignedToSampleGroup())}isAssignedToSampleGroup(){return Math.random()>.5}captureTiming(e){window&&a()&&a().captureTiming&&e&&a().captureTiming(e)}init(e,t,n,r,s){const o=e,c=o.accountId;this.userAttributes=w(s),this._onboardingExpProvider=o.onboardingExpProvider;const u=L(o.placementEventMapping);this.placementEventMappingLookup=X(u);const l=L(o.placementEventAttributeMapping);this.placementEventAttributeMappingLookup=Z(l),o.hashedEmailUserIdentityType&&(this._mappedEmailSha256Key=o.hashedEmailUserIdentityType.toLowerCase()),this._workspaceIdSyncApiKey=m(o.workspaceIdSyncApiKey)?o.workspaceIdSyncApiKey:void 0;const p=a().Rokt?.domain,{roktExtensionsQueryParams:N,legacyRoktExtensions:R,loadThankYouElement:v}=Q(o.roktExtensions),g={...a().Rokt?.launcherOptions||{}};this.integrationName=Be(g.integrationName),g.integrationName=this.integrationName,this.domain=p;const A={loggingUrl:o.loggingUrl,errorUrl:o.errorUrl,integrationDomain:p,isLoggingEnabled:a().config?.isLoggingEnabled===!0},I=new ie(A,this.integrationName,window.__rokt_li_guid__,o.accountId),k=new ne(A,I,this.integrationName,window.__rokt_li_guid__,o.accountId);if(this.errorReportingService=I,this.loggingService=k,this.isTargetingDisabled())try{V(),z()}catch(h){this.errorReportingService?.report({message:"Rokt Kit: Failed to clear page views when targeting is disabled",code:"PAGE_VIEW_CAPTURE_FAILED",severity:S.INFO,stackTrace:h instanceof Error?h.stack:void 0})}return a()._registerErrorReportingService&&a()._registerErrorReportingService(I),a()._registerLoggingService&&a()._registerLoggingService(k),n?(this.testHelpers={generateLauncherScript:$,generateThankYouElementScript:J,extractRoktExtensionConfig:Q,hashEventMessage:ee,parseSettingsString:L,generateMappedEventLookup:X,generateMappedEventAttributeLookup:Z,sendAdBlockMeasurementSignals:te,createAutoRemovedIframe:M,djb2:de,setAllowedOriginHashes:h=>{f._allowedOriginHashes=h},ReportingTransport:j,ErrorReportingService:ie,LoggingService:ne,RateLimiter:he,ErrorCodes:Y,WSDKErrorSeverity:S,resetLauncherAttachState:()=>Pe(this._launcherAttachState)},this.attachLauncher(c,g),"Successfully initialized: "+d):(v&&(a().Rokt.flushOnShoppableAdsReadyMessageQueue?.(this),B(Fe,J(p),{onLoad:()=>{this._isThankYouElementLoaded=!0,this._thankYouElementOnLoadCallback&&this._thankYouElementOnLoadCallback()},onError:h=>{console.error("Error loading Rokt Thank You Element script:",h)}})),this.isLauncherReadyToAttach()?this.attachLauncher(c,g,R):(B(Ke,$(p,N),{onLoad:()=>{this.isLauncherReadyToAttach()?this.attachLauncher(c,g,R):console.error("Rokt object is not available after script load.")},onError:h=>{console.error("Error loading Rokt launcher script:",h)}}),this.captureTiming(f.PERFORMANCE_MARKS.RoktScriptAppended)),"Successfully initialized: "+d)}process(e){if(this.isTargetingDisabled()||(e.EventDataType===xe&&(Ae(this.loggingService),this.capturePageView(e)),e.EventDataType===Ye&&(V(),z())),!this.isKitReady())return"Kit not ready for forwarder: "+d;if(b(a().Rokt?.setLocalSessionAttribute)&&(U(this.placementEventAttributeMappingLookup)||this.applyPlacementEventAttributeMapping(e),!U(this.placementEventMappingLookup))){const t=ee(e.EventDataType,e.EventCategory,e.EventName??"");this.placementEventMappingLookup[String(t)]&&a().Rokt.setLocalSessionAttribute?.(this.placementEventMappingLookup[String(t)],!0)}return"Successfully sent to forwarder: "+d}setExtensionData(e){if(!this.isKitReady()){console.error("Rokt Kit: Not initialized");return}window.Rokt.setExtensionData(e)}setUserAttribute(e,t){return re(e)||(this.userAttributes[e]=t),"Successfully set user attribute for forwarder: "+d}removeUserAttribute(e){return delete this.userAttributes[e],"Successfully removed user attribute for forwarder: "+d}handleIdentityComplete(e,t){return this.userAttributes=w(e.getAllUserAttributes()),"Successfully called "+t+" for forwarder: "+d}onUserIdentified(e){const t=e;return this.filters.filteredUser=t,this._workspaceSearchInFlightPromise=this.search(t),this.handleIdentityComplete(e,"onUserIdentified")}search(e){const t=this._workspaceIdSyncApiKey;if(!t)return this.userIdentifiedInWorkspace=!1,this._workspaceLastSearchedIdentitiesKey=void 0,Promise.resolve();const n=a().Identity?.search;if(typeof n!="function")return this.userIdentifiedInWorkspace=!1,this._workspaceLastSearchedIdentitiesKey=void 0,Promise.resolve();const r=e.getUserIdentities?e.getUserIdentities().userIdentities:null,s={};if(r)for(const u of Object.keys(r)){const l=r[u];m(l)&&l.length>0&&(s[u]=l)}const o=Object.keys(s);if(o.length===0)return this.userIdentifiedInWorkspace=!1,this._workspaceLastSearchedIdentitiesKey=void 0,Promise.resolve();const c=o.sort().map(u=>`${u}=${s[u]}`).join("&");return c===this._workspaceLastSearchedIdentitiesKey?this._workspaceSearchInFlightPromise||Promise.resolve():(this.userIdentifiedInWorkspace=!1,this._workspaceLastSearchedIdentitiesKey=c,new Promise(u=>{try{n(t,s,l=>{l?.httpCode===200&&(this.userIdentifiedInWorkspace=!0),u()})}catch(l){console.error("Rokt Kit: Workspace IDSync search failed",l),this._workspaceLastSearchedIdentitiesKey=void 0,u()}}))}onLoginComplete(e,t){return this.handleIdentityComplete(e,"onLoginComplete")}onLogoutComplete(e,t){return this.userIdentifiedInWorkspace=!1,this._workspaceSearchInFlightPromise=null,this._workspaceLastSearchedIdentitiesKey=void 0,this.handleIdentityComplete(e,"onLogoutComplete")}onModifyComplete(e,t){return this.handleIdentityComplete(e,"onModifyComplete")}selectPlacements(e){const t=this.recreateLauncherIfTerminated();if(t){const n=this._workspaceSearchInFlightPromise,r=n?Promise.race([n,new Promise(s=>setTimeout(s,q))]):Promise.resolve();return Promise.all([t,r]).then(()=>this._dispatchPlacements(e))}if(this._workspaceSearchInFlightPromise){const n=this._workspaceSearchInFlightPromise;return Promise.race([n,new Promise(r=>setTimeout(r,q))]).then(()=>this._dispatchPlacements(e))}return this._dispatchPlacements(e)}_dispatchPlacements(e){const t=e&&e.attributes||{},r={...w(this.userAttributes),...t},s=this.filters||{},o=s.userAttributeFilters||[],c=s.filteredUser||null,u=c?c.getMPID():null;let l;s?s.filterUserAttributes?l=s.filterUserAttributes(r,o):l=r:(console.warn("Rokt Kit: No filters available, using user attributes"),l=r),this.userAttributes=w(l);const p=this._onboardingExpProvider==="Optimizely"?this.fetchOptimizely():{},N=this.returnUserIdentities(c),R=this.returnLocalSessionAttributes(),v=ye(H()),g=ke(),A=this.readMpSessionId(),I=this.readMpDeviceId(),k={...N,...l,...p,...R,...v.length?{[je]:JSON.stringify(v)}:{},...g?{[Ge]:g}:{},...this.userIdentifiedInWorkspace?{[De]:!0}:{},...A?{[We]:A}:{},...I?{[He]:I}:{},mpid:u},h={...e,attributes:k},G=this.launcher.selectPlacements(h),pe=()=>this.logSelectPlacementsEvent(k);return Promise.resolve(G).then(ge=>ge?.context?.sessionId?.then(fe=>this.setRoktSessionId(fe))).catch(()=>{}).finally(pe),G}hashAttributes(e){return this.isKitReady()?this.launcher.hashAttributes(e):(console.error("Rokt Kit: Not initialized"),null)}use(e){return this.isKitReady()?!e||!m(e)?Promise.reject(new Error("Rokt Kit: Invalid extension name")):this.launcher.use(e):(console.error("Rokt Kit: Not initialized"),Promise.reject(new Error("Rokt Kit: Not initialized")))}terminate(){return this.isKitReady()?(Te(this._launcherAttachState),this.launcher.terminate()):(console.error("Rokt Kit: Not initialized"),Promise.resolve())}onShoppableAdsReady(e){this._isThankYouElementLoaded?e():this._thankYouElementOnLoadCallback=e}};f._allowedOriginHashes=[-553112570,549508659],f.PERFORMANCE_MARKS={RoktScriptAppended:"mp:RoktScriptAppended"},f.EMAIL_SHA256_KEY="emailsha256";let y=f;function tt(){return T}function it(i){if(!i){window.console.log("You must pass a config object to register the kit "+d);return}if(!E(i)){window.console.log("'config' must be an object. You passed in a "+typeof i);return}E(i.kits)?i.kits[d]={constructor:y}:(i.kits={},i.kits[d]={constructor:y}),window.console.log("Successfully registered "+d+" to your mParticle configuration")}typeof window<"u"&&window.mParticle&&a().addForwarder&&a().addForwarder({name:d,constructor:y,getId:tt});exports.register=it; //# sourceMappingURL=Rokt-Kit.common.js.map diff --git a/kits/rokt/dist/Rokt-Kit.common.js.map b/kits/rokt/dist/Rokt-Kit.common.js.map index 04eaf0f9e..7f69b4e75 100644 --- a/kits/rokt/dist/Rokt-Kit.common.js.map +++ b/kits/rokt/dist/Rokt-Kit.common.js.map @@ -1 +1 @@ -{"version":3,"file":"Rokt-Kit.common.js","sources":["../src/selectPlacementsAttributePersistence.ts","../src/Rokt-Kit.ts"],"sourcesContent":["const SELECT_PLACEMENTS_ATTRIBUTE_PERSISTENCE_DENY_LIST = [\n 'billingaddress1',\n 'billingaddress2',\n 'billingcity',\n 'billingstate',\n 'billingzipcode',\n 'cartitems',\n 'ccbin',\n 'confirmationref',\n 'conversiontype',\n 'country',\n 'couponcode',\n 'currency',\n 'language',\n 'paymentserviceprovider',\n 'paymentserviceproviderattribute',\n 'paymenttype',\n 'shippingaddress1',\n 'shippingcity',\n 'shippingcountry',\n 'shippingmethod',\n 'shippingstate',\n 'shippingzipcode',\n 'totalprice',\n];\nconst SELECT_PLACEMENTS_ATTRIBUTE_PERSISTENCE_DENY_SET = new Set(SELECT_PLACEMENTS_ATTRIBUTE_PERSISTENCE_DENY_LIST);\n\nexport function isSelectPlacementsAttributePersistenceDenied(key: string): boolean {\n return SELECT_PLACEMENTS_ATTRIBUTE_PERSISTENCE_DENY_SET.has(key.toLowerCase());\n}\n\nexport function removeSelectPlacementsAttributePersistenceDeniedAttributes(\n attributes: Record | null | undefined,\n): Record {\n const filteredAttributes: Record = {};\n const sourceAttributes = attributes || {};\n const attributeKeys = Object.keys(sourceAttributes);\n\n for (let i = 0; i < attributeKeys.length; i++) {\n const key = attributeKeys[i];\n if (!isSelectPlacementsAttributePersistenceDenied(key)) {\n filteredAttributes[key] = sourceAttributes[key];\n }\n }\n\n return filteredAttributes;\n}\n","// Copyright 2025 mParticle, Inc.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n// ============================================================\n// Types\n// ============================================================\n\nimport { KitInterface, IMParticleUser, SDKEvent } from '@mparticle/web-sdk/internal';\nimport type { IUserIdentities } from '@mparticle/web-sdk';\n\nimport {\n isSelectPlacementsAttributePersistenceDenied,\n removeSelectPlacementsAttributePersistenceDeniedAttributes,\n} from './selectPlacementsAttributePersistence';\n\ninterface RoktKitSettings {\n accountId: string;\n roktExtensions?: string;\n placementEventMapping?: string;\n placementEventAttributeMapping?: string;\n hashedEmailUserIdentityType?: string;\n onboardingExpProvider?: string;\n loggingUrl?: string;\n errorUrl?: string;\n workspaceIdSyncApiKey?: string;\n}\n\ninterface EventAttributeCondition {\n operator: string;\n attributeValue: string;\n}\n\ninterface PlacementEventRule {\n eventAttributeKey: string;\n conditions: EventAttributeCondition[];\n}\n\ninterface EventAttributeMapping {\n value: string;\n map: string;\n conditions?: EventAttributeCondition[];\n}\n\ninterface PlacementEventMappingEntry {\n jsmap: string;\n value: string;\n}\n\ninterface RoktExtensionEntry {\n value: string;\n}\n\ninterface RoktSelection {\n context?: {\n sessionId?: Promise;\n };\n then?: (callback: (sel: RoktSelection) => void) => Promise;\n catch?: (callback: () => void) => void;\n}\n\ninterface RoktLauncher {\n selectPlacements(options: Record): RoktSelection | Promise;\n hashAttributes(attributes: Record): Promise>;\n use(extensionName: string): Promise;\n}\n\ninterface RoktGlobal {\n createLauncher(options: Record): Promise;\n createLocalLauncher(options: Record): RoktLauncher;\n currentLauncher?: RoktLauncher;\n setExtensionData(data: Record): void;\n}\n\n// FilteredUser is the IMParticleUser shape we receive after kit filtering.\n// `getMPID` and `getUserIdentities` are inherited from the SDK's `User` base type.\ntype FilteredUser = IMParticleUser;\n\n// TODO: Replace with `IIdentitySearchResult` from `@mparticle/web-sdk` once\n// a version that exports it is published (currently on a feature branch in\n// mParticle/mparticle-web-sdk PR #1255). The shape below is intentionally\n// structurally identical so the swap is a one-line import change.\ninterface WorkspaceIdSyncResult {\n httpCode: number;\n body?: {\n context?: string | null;\n mpid?: string;\n matched_identities?: Record;\n is_ephemeral?: boolean;\n is_logged_in?: boolean;\n };\n}\n\n// TODO: Replace with `IdentitySearchCallback`-compatible reference from\n// `@mparticle/web-sdk` once published (mirrors `SDKIdentityApi.search`).\ntype WorkspaceIdSyncSearcher = (\n apiKey: string,\n knownIdentities: IUserIdentities,\n callback: (result: WorkspaceIdSyncResult) => void,\n) => void;\n\ninterface KitFilters {\n userAttributeFilters?: string[];\n filterUserAttributes?: (attributes: Record, filters?: string[]) => Record;\n filteredUser?: FilteredUser | null;\n}\n\ninterface RoktManager {\n attachKit(kit: RoktKit): void | Promise;\n flushOnShoppableAdsReadyMessageQueue?(kit: RoktKit): void;\n filters?: KitFilters;\n domain?: string;\n launcherOptions?: Record;\n getLocalSessionAttributes?(): Record;\n setLocalSessionAttribute?(key: string, value: unknown): void;\n}\n\ninterface MParticleInstance {\n setIntegrationAttribute(moduleId: number, attrs: Record): void;\n}\n\ninterface OptimizelyState {\n getActiveExperimentIds(): string[];\n getVariationMap(): Record;\n}\n\ninterface OptimizelyGlobal {\n get(key: 'state'): OptimizelyState;\n}\n\n// Our view of the mParticle global with Rokt-specific extensions.\n// We access window.mParticle via an explicit cast (see `mp()` helper below)\n// rather than augmenting Window to avoid conflicts with @mparticle/web-sdk declarations.\ninterface MParticleExtended {\n Rokt: RoktManager;\n addForwarder(config: ForwarderRegistration): void;\n getVersion(): string;\n generateHash(value: string): string | number;\n logEvent(name: string, type: number, attrs?: Record): void;\n EventType: { Other: number };\n getInstance(): MParticleInstance;\n sessionManager?: { getSession(): string };\n _getActiveForwarders(): Array<{ name: string }>;\n config?: { isLocalLauncherEnabled?: boolean; isLoggingEnabled?: boolean };\n captureTiming?(metricName: string): void;\n forwarder?: RoktKit;\n loggedEvents?: Array>;\n _registerErrorReportingService?(service: ErrorReportingService): void;\n _registerLoggingService?(service: LoggingService): void;\n Identity?: { search?: WorkspaceIdSyncSearcher };\n}\n\ninterface TestHelpers {\n generateLauncherScript: (domain: string | undefined, extensions: string[]) => string;\n generateThankYouElementScript: (domain: string | undefined) => string;\n extractRoktExtensionConfig: (settingsString?: string) => RoktExtensionConfig;\n hashEventMessage: (messageType: number, eventType: number, eventName: string) => string | number;\n parseSettingsString: (settingsString?: string) => T[];\n generateMappedEventLookup: (placementEventMapping: PlacementEventMappingEntry[]) => Record;\n generateMappedEventAttributeLookup: (mapping: EventAttributeMapping[]) => Record;\n sendAdBlockMeasurementSignals: (domain: string | undefined, version: string | null) => void;\n createAutoRemovedIframe: (src: string) => void;\n djb2: (str: string) => number;\n setAllowedOriginHashes: (hashes: number[]) => void;\n ReportingTransport: typeof ReportingTransport;\n ErrorReportingService: typeof ErrorReportingService;\n LoggingService: typeof LoggingService;\n RateLimiter: typeof RateLimiter;\n ErrorCodes: typeof ErrorCodes;\n WSDKErrorSeverity: typeof WSDKErrorSeverity;\n}\n\ninterface ForwarderRegistration {\n name: string;\n constructor: new () => RoktKit;\n getId: () => number;\n}\n\ninterface ReportingConfig {\n loggingUrl?: string;\n errorUrl?: string;\n integrationDomain?: string;\n isLoggingEnabled: boolean;\n}\n\ninterface ErrorReport {\n message: string;\n code?: string;\n severity?: string;\n stackTrace?: string;\n}\n\n// A log-delivery failure. statusCode is set when the request reached the server\n// and returned a non-2xx status (server-side); it is absent for network-level\n// failures such as ad-blockers, offline, or CORS rejections (client-side).\ninterface DeliveryError extends Error {\n statusCode?: number;\n}\n\ninterface LogEntry {\n message: string;\n code?: string;\n}\n\ninterface RoktExtensionConfig {\n roktExtensionsQueryParams: string[];\n legacyRoktExtensions: string[];\n loadThankYouElement: boolean;\n}\n\ndeclare global {\n interface Window {\n Rokt?: RoktGlobal;\n __rokt_li_guid__?: string;\n optimizely?: OptimizelyGlobal;\n // mParticle is declared as any to avoid conflicts with @mparticle/web-sdk type declarations.\n // We use the typed mp() accessor for all internal accesses.\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n mParticle: any;\n }\n}\n\n// ============================================================\n// Module-level constants\n// ============================================================\n\nconst name = 'Rokt';\nconst moduleId = 181;\nconst EVENT_NAME_SELECT_PLACEMENTS = 'selectPlacements';\nconst ADBLOCK_CONTROL_DOMAIN = 'apps.roktecommerce.com';\nconst INIT_LOG_SAMPLING_RATE = 0.1;\nconst ROKT_THANK_YOU_JOURNEY_EXTENSION = 'ThankYouPageJourney';\nconst ROKT_INTEGRATION_SCRIPT_ID = 'rokt-launcher';\nconst ROKT_THANK_YOU_ELEMENT_SCRIPT_ID = 'rokt-thank-you-element';\nconst USER_IDENTIFIED_IN_WORKSPACE_KEY = 'userIdentifiedInWorkspace';\n\n// Bound on how long selectPlacements will wait for an in-flight Workspace\n// IDSync search before proceeding without the userIdentifiedInWorkspace flag.\n// Long enough to cover the typical /v1/search round-trip (~50ms); short enough that a\n// stalled search never blocks placement rendering on a thank-you page.\nconst WORKSPACE_SEARCH_SELECT_TIMEOUT_MS = 500;\n\n// ============================================================\n// Reporting service constants\n// ============================================================\n\nconst ErrorCodes = {\n UNKNOWN_ERROR: 'UNKNOWN_ERROR',\n UNHANDLED_EXCEPTION: 'UNHANDLED_EXCEPTION',\n IDENTITY_REQUEST: 'IDENTITY_REQUEST',\n LOG_DELIVERY_FAILURE: 'LOG_DELIVERY_FAILURE',\n} as const;\n\nconst WSDKErrorSeverity = {\n ERROR: 'ERROR',\n INFO: 'INFO',\n WARNING: 'WARNING',\n} as const;\n\nconst DEFAULT_ROKT_DOMAIN = 'apps.rokt-api.com';\nconst LOGGING_ENDPOINT = '/v1/log';\nconst ERROR_ENDPOINT = '/v1/errors';\nconst RATE_LIMIT_PER_SEVERITY = 10;\n\n// ============================================================\n// Helper: typed accessor for window.mParticle\n// We use an explicit cast here to avoid conflicts with @mparticle/web-sdk\n// type declarations while still providing full type safety for our usages.\n// ============================================================\n\nfunction mp(): MParticleExtended {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n return (window as any).mParticle as MParticleExtended;\n}\n\n// ============================================================\n// Module-level utility functions\n// ============================================================\n\nfunction generateLauncherScript(domain: string | undefined, extensions: string[]): string {\n const launcherPath = '/wsdk/integrations/launcher.js';\n const baseUrl = [generateBaseUrl(domain), launcherPath].join('');\n\n if (!extensions || extensions.length === 0) {\n return baseUrl;\n }\n return baseUrl + '?extensions=' + extensions.join(',');\n}\n\nfunction generateThankYouElementScript(domain: string | undefined) {\n const thankYouElementPath = '/rokt-elements/rokt-element-thank-you.js';\n return [generateBaseUrl(domain), thankYouElementPath].join('');\n}\n\nfunction generateBaseUrl(domain: string | undefined) {\n const resolvedDomain = typeof domain !== 'undefined' ? domain : DEFAULT_ROKT_DOMAIN;\n const protocol = 'https://';\n\n return [protocol, resolvedDomain].join('');\n}\n\nfunction generateReportingUrl(configuredUrl: string | undefined, domain: string | undefined, endpoint: string): string {\n if (configuredUrl) {\n if (configuredUrl.startsWith('http://') || configuredUrl.startsWith('https://')) {\n return configuredUrl;\n }\n return 'https://' + configuredUrl;\n }\n\n return generateBaseUrl(domain) + endpoint;\n}\n\nfunction loadRoktScript(\n scriptId: string,\n source: string,\n handlers?: { onLoad?: () => void; onError?: (e: Event | string) => void },\n): void {\n if (document.getElementById(scriptId)) return; // resolves the preexisting script issue\n\n const target = document.head || document.body;\n const script = document.createElement('script');\n script.id = scriptId;\n script.type = 'text/javascript';\n script.src = source;\n script.async = true;\n script.crossOrigin = 'anonymous';\n (script as HTMLScriptElement & { fetchPriority: string }).fetchPriority = 'high';\n if (handlers?.onLoad) script.onload = handlers.onLoad;\n if (handlers?.onError) script.onerror = handlers.onError;\n target.appendChild(script);\n}\n\nfunction isObject(val: unknown): val is Record {\n return val != null && typeof val === 'object' && Array.isArray(val) === false;\n}\n\nfunction parseSettingsString(settingsString?: string): T[] {\n if (!settingsString) {\n return [];\n }\n try {\n return JSON.parse(settingsString.replace(/"/g, '\"')) as T[];\n } catch (_error) {\n console.error('Settings string contains invalid JSON');\n }\n return [];\n}\n\nfunction extractRoktExtensionConfig(settingsString?: string): RoktExtensionConfig {\n const settings = settingsString ? parseSettingsString(settingsString) : [];\n const roktExtensionsQueryParams: string[] = [];\n const legacyRoktExtensions: string[] = [];\n let loadThankYouElement = false;\n\n for (let i = 0; i < settings.length; i++) {\n const extensionName = settings[i].value;\n if (extensionName === 'thank-you-journey') {\n loadThankYouElement = true;\n legacyRoktExtensions.push(ROKT_THANK_YOU_JOURNEY_EXTENSION);\n } else {\n roktExtensionsQueryParams.push(extensionName);\n }\n }\n\n return {\n roktExtensionsQueryParams,\n legacyRoktExtensions,\n loadThankYouElement,\n };\n}\n\nasync function registerLegacyExtensions(legacyExtensions: string[], launcher: RoktLauncher | null) {\n const extensions: Promise[] = [];\n if (launcher) {\n for (const extension of legacyExtensions) {\n extensions.push(launcher.use(extension));\n }\n }\n\n return Promise.all(extensions);\n}\n\nfunction generateMappedEventLookup(placementEventMapping: PlacementEventMappingEntry[]): Record {\n if (!placementEventMapping) {\n return {};\n }\n\n const mappedEvents: Record = {};\n for (let i = 0; i < placementEventMapping.length; i++) {\n const mapping = placementEventMapping[i];\n mappedEvents[mapping.jsmap] = mapping.value;\n }\n return mappedEvents;\n}\n\nfunction generateMappedEventAttributeLookup(\n placementEventAttributeMapping: EventAttributeMapping[],\n): Record {\n const mappedAttributeKeys: Record = {};\n if (!Array.isArray(placementEventAttributeMapping)) {\n return mappedAttributeKeys;\n }\n for (let i = 0; i < placementEventAttributeMapping.length; i++) {\n const mapping = placementEventAttributeMapping[i];\n if (!mapping || !isString(mapping.value) || !isString(mapping.map)) {\n continue;\n }\n\n const mappedAttributeKey = mapping.value;\n const eventAttributeKey = mapping.map;\n\n if (!mappedAttributeKeys[mappedAttributeKey]) {\n mappedAttributeKeys[mappedAttributeKey] = [];\n }\n\n mappedAttributeKeys[mappedAttributeKey].push({\n eventAttributeKey: eventAttributeKey,\n conditions: Array.isArray(mapping.conditions) ? mapping.conditions : [],\n });\n }\n return mappedAttributeKeys;\n}\n\nfunction hashEventMessage(messageType: number, eventType: number, eventName: string): string | number {\n return mp().generateHash([messageType, eventType, eventName].join(''));\n}\n\nfunction isEmpty(value: unknown): boolean {\n if (value == null) return true;\n if (typeof value === 'object') {\n return Object.keys(value as object).length === 0;\n }\n if (Array.isArray(value)) {\n return (value as unknown[]).length === 0;\n }\n return false;\n}\n\nfunction isString(value: unknown): value is string {\n return typeof value === 'string';\n}\n\nfunction generateIntegrationName(customIntegrationName?: string): string {\n const coreSdkVersion = mp().getVersion();\n const kitVersion = process.env.PACKAGE_VERSION;\n let integrationName = 'mParticle_' + 'wsdkv_' + coreSdkVersion + '_kitv_' + kitVersion;\n\n if (customIntegrationName) {\n integrationName += '_' + customIntegrationName;\n }\n return integrationName;\n}\n\nfunction djb2(str: string): number {\n let hash = 5381;\n for (let i = 0; i < str.length; i++) {\n hash = (hash << 5) + hash + str.charCodeAt(i);\n hash = hash & hash;\n }\n return hash;\n}\n\nfunction createAutoRemovedIframe(src: string): void {\n const iframe = document.createElement('iframe');\n iframe.style.display = 'none';\n iframe.setAttribute('sandbox', 'allow-scripts allow-same-origin');\n iframe.src = src;\n iframe.onload = function () {\n iframe.onload = null;\n if (iframe.parentNode) {\n iframe.parentNode.removeChild(iframe);\n }\n };\n const target = document.body || document.head;\n if (target) {\n target.appendChild(iframe);\n }\n}\n\nfunction sendAdBlockMeasurementSignals(domain: string | undefined, version: string | null): void {\n const originHash = djb2(window.location.origin);\n const allowedOriginHashes = RoktKit._allowedOriginHashes;\n if (allowedOriginHashes.indexOf(originHash) === -1) {\n return;\n }\n\n if (Math.random() >= INIT_LOG_SAMPLING_RATE) {\n return;\n }\n\n const guid = window.__rokt_li_guid__;\n if (!guid) {\n return;\n }\n\n const pageUrl = window.location.href.split('?')[0].split('#')[0];\n const params =\n 'version=' +\n encodeURIComponent(version ?? '') +\n '&launcherInstanceGuid=' +\n encodeURIComponent(guid) +\n '&pageUrl=' +\n encodeURIComponent(pageUrl);\n\n const existingDomain = domain || 'apps.rokt.com';\n createAutoRemovedIframe('https://' + existingDomain + '/v1/wsdk-init/index.html?' + params);\n\n createAutoRemovedIframe(\n 'https://' + ADBLOCK_CONTROL_DOMAIN + '/v1/wsdk-init/index.html?' + params + '&isControl=true',\n );\n}\n\n// ============================================================\n// Reporting helpers\n// ============================================================\n\nfunction _isDebugModeEnabled(): boolean {\n return typeof window !== 'undefined' && !!window.location?.search?.toLowerCase().includes('mp_enable_logging=true');\n}\n\nfunction _getReportingUrl(): string | undefined {\n return typeof window !== 'undefined' ? window.location?.href : undefined;\n}\n\nfunction _getUserAgent(): string | undefined {\n return typeof window !== 'undefined' ? window.navigator?.userAgent : undefined;\n}\n\nclass RateLimiter {\n private _logCount: Record = {};\n\n incrementAndCheck(severity: string): boolean {\n const count = this._logCount[severity] || 0;\n const newCount = count + 1;\n this._logCount[severity] = newCount;\n return newCount > RATE_LIMIT_PER_SEVERITY;\n }\n}\n\nclass ReportingTransport {\n private _isEnabled: boolean;\n private _integrationName: string;\n private _launcherInstanceGuid: string | undefined;\n private _accountId: string | null;\n private _rateLimiter: RateLimiter;\n private readonly _reporter = 'mp-wsdk';\n\n constructor(\n config: ReportingConfig,\n integrationName: string | null | undefined,\n launcherInstanceGuid: string | undefined,\n accountId: string | null | undefined,\n rateLimiter?: RateLimiter,\n ) {\n const isLoggingEnabled = config.isLoggingEnabled;\n this._integrationName = integrationName || '';\n this._launcherInstanceGuid = launcherInstanceGuid;\n this._accountId = accountId || null;\n this._rateLimiter = rateLimiter || new RateLimiter();\n this._isEnabled = _isDebugModeEnabled() || isLoggingEnabled;\n }\n\n send(\n url: string,\n severity: string,\n msg: string,\n code?: string,\n stackTrace?: string,\n onError?: (error: DeliveryError) => void,\n ): void {\n if (!this._isEnabled || this._rateLimiter.incrementAndCheck(severity)) {\n return;\n }\n\n try {\n const logRequest = {\n additionalInformation: {\n message: msg,\n version: this._integrationName,\n },\n severity,\n code: code || ErrorCodes.UNKNOWN_ERROR,\n url: _getReportingUrl(),\n deviceInfo: _getUserAgent(),\n stackTrace,\n reporter: this._reporter,\n integration: this._integrationName,\n };\n\n const headers: Record = {\n Accept: 'text/plain;charset=UTF-8',\n 'Content-Type': 'application/json',\n 'rokt-launcher-version': this._integrationName,\n 'rokt-wsdk-version': 'joint',\n };\n\n if (this._launcherInstanceGuid) {\n headers['rokt-launcher-instance-guid'] = this._launcherInstanceGuid;\n }\n if (this._accountId) {\n headers['rokt-account-id'] = this._accountId;\n }\n\n fetch(url, {\n method: 'POST',\n headers,\n body: JSON.stringify(logRequest),\n })\n .then((response: Response) => {\n // fetch only rejects on network failures; an HTTP 5xx resolves with\n // ok === false. Surface server-side failures so they are not swallowed.\n if (!response.ok) {\n const serverError: DeliveryError = new Error('HTTP ' + response.status + ' from log endpoint');\n serverError.statusCode = response.status;\n throw serverError;\n }\n })\n .catch((error: DeliveryError) => {\n console.error('ReportingTransport: Failed to send log', error);\n if (onError) onError(error);\n });\n } catch (error) {\n console.error('ReportingTransport: Failed to send log', error);\n if (onError) onError(error as DeliveryError);\n }\n }\n}\n\nclass ErrorReportingService {\n private _transport: ReportingTransport;\n private _errorUrl: string;\n\n constructor(\n config: ReportingConfig,\n integrationName: string | null | undefined,\n launcherInstanceGuid?: string,\n accountId?: string | null,\n rateLimiter?: RateLimiter,\n ) {\n this._transport = new ReportingTransport(config, integrationName, launcherInstanceGuid, accountId, rateLimiter);\n this._errorUrl = generateReportingUrl(config?.errorUrl, config?.integrationDomain, ERROR_ENDPOINT);\n }\n\n report(error: ErrorReport | null | undefined): void {\n if (!error) return;\n const severity = error.severity || WSDKErrorSeverity.ERROR;\n this._transport.send(this._errorUrl, severity, error.message, error.code, error.stackTrace);\n }\n}\n\nclass LoggingService {\n private _transport: ReportingTransport;\n private _loggingUrl: string;\n private _errorReportingService: { report: (e: ErrorReport) => void };\n\n constructor(\n config: ReportingConfig,\n errorReportingService: { report: (e: ErrorReport) => void },\n integrationName: string | null | undefined,\n launcherInstanceGuid?: string,\n accountId?: string | null,\n rateLimiter?: RateLimiter,\n ) {\n this._transport = new ReportingTransport(config, integrationName, launcherInstanceGuid, accountId, rateLimiter);\n this._loggingUrl = generateReportingUrl(config?.loggingUrl, config?.integrationDomain, LOGGING_ENDPOINT);\n this._errorReportingService = errorReportingService;\n }\n\n log(entry: LogEntry | null | undefined): void {\n if (!entry) return;\n this._transport.send(\n this._loggingUrl,\n WSDKErrorSeverity.INFO,\n entry.message,\n entry.code,\n undefined,\n (error: DeliveryError) => {\n if (this._errorReportingService) {\n // A failed log POST is not itself an SDK error. Network-level failures\n // (ad-blockers, offline, CORS) are client-side noise and reported as a\n // WARNING; only a server-side non-2xx response stays at ERROR severity.\n const isServerSide = typeof error.statusCode === 'number';\n this._errorReportingService.report({\n message: 'LoggingService: Failed to send log: ' + error.message,\n code: ErrorCodes.LOG_DELIVERY_FAILURE,\n severity: isServerSide ? WSDKErrorSeverity.ERROR : WSDKErrorSeverity.WARNING,\n });\n }\n },\n );\n }\n}\n\n// ============================================================\n// RoktKit class\n// ============================================================\n\nclass RoktKit implements KitInterface {\n // Static field for allowed origin hashes (mutable by testHelpers)\n public static _allowedOriginHashes: number[] = [-553112570, 549508659];\n\n private static readonly PERFORMANCE_MARKS = {\n RoktScriptAppended: 'mp:RoktScriptAppended',\n };\n\n private static readonly EMAIL_SHA256_KEY = 'emailsha256';\n\n // Public fields (accessed by tests and the mParticle framework)\n public name = name;\n public id = moduleId;\n public moduleId = moduleId;\n public isInitialized = false;\n public launcher: RoktLauncher | null = null;\n public filters: KitFilters = {};\n public userAttributes: Record = {};\n // Flag set by the Workspace IDSync flow on a 200 response. Stored on the\n // kit instance and merged into placement attributes inside selectPlacements.\n public userIdentifiedInWorkspace = false;\n public testHelpers: TestHelpers | null = null;\n public placementEventMappingLookup: Record = {};\n public placementEventAttributeMappingLookup: Record = {};\n public integrationName: string | null = null;\n public domain?: string;\n public errorReportingService: ErrorReportingService | null = null;\n public loggingService: LoggingService | null = null;\n\n // Private fields\n private _mappedEmailSha256Key?: string;\n private _onboardingExpProvider?: string;\n private _thankYouElementOnLoadCallback: (() => void) | null = null;\n private _isThankYouElementLoaded = false;\n private _workspaceIdSyncApiKey?: string;\n\n // Held during a search dispatch so the next selectPlacements call;\n // can wait for the HTTP response before reading userIdentifiedInWorkspace;\n // — otherwise the first placement call ships without the flag.\n private _workspaceSearchInFlightPromise: Promise | null = null;\n // Stable serialization of the identifier set sent in the most recent\n // successful search dispatch. If a subsequent identification arrives with\n // an identical set, we skip the network call (the flag is still correct\n // from the prior search). Keyed over the full IUserIdentities map — not\n // just email — so partners passing hashed email through `other`/`other2-10`\n // or any other identifier benefit from the same dedupe. Cleared on logout\n // so a re-login re-evaluates fresh.\n private _workspaceLastSearchedIdentitiesKey?: string;\n\n // ---- Private helpers ----\n\n private getEventAttributeValue(event: SDKEvent, eventAttributeKey: string): unknown {\n const attributes = event && event.EventAttributes;\n if (!attributes) {\n return null;\n }\n\n if (typeof attributes[eventAttributeKey] === 'undefined') {\n return null;\n }\n\n return attributes[eventAttributeKey];\n }\n\n private doesEventAttributeConditionMatch(condition: EventAttributeCondition, actualValue: unknown): boolean {\n if (!condition || !isString(condition.operator)) {\n return false;\n }\n\n const operator = condition.operator.toLowerCase();\n const expectedValue = condition.attributeValue;\n\n if (operator === 'exists') {\n return actualValue !== null;\n }\n\n if (actualValue == null) {\n return false;\n }\n\n if (operator === 'equals') {\n return String(actualValue) === String(expectedValue);\n }\n\n if (operator === 'contains') {\n return String(actualValue).indexOf(String(expectedValue)) !== -1;\n }\n\n return false;\n }\n\n private doesEventMatchRule(event: SDKEvent, rule: PlacementEventRule): boolean {\n if (!rule || !isString(rule.eventAttributeKey)) {\n return false;\n }\n\n const conditions = rule.conditions;\n if (!Array.isArray(conditions)) {\n return false;\n }\n\n const actualValue = this.getEventAttributeValue(event, rule.eventAttributeKey);\n\n if (conditions.length === 0) {\n return actualValue !== null;\n }\n for (let i = 0; i < conditions.length; i++) {\n if (!this.doesEventAttributeConditionMatch(conditions[i], actualValue)) {\n return false;\n }\n }\n\n return true;\n }\n\n private applyPlacementEventAttributeMapping(event: SDKEvent): void {\n const mappedAttributeKeys = Object.keys(this.placementEventAttributeMappingLookup);\n for (let i = 0; i < mappedAttributeKeys.length; i++) {\n const mappedAttributeKey = mappedAttributeKeys[i];\n const rulesForMappedAttributeKey = this.placementEventAttributeMappingLookup[mappedAttributeKey];\n if (isEmpty(rulesForMappedAttributeKey)) {\n continue;\n }\n\n // Require ALL rules for the same key to match (AND).\n let allMatch = true;\n for (let j = 0; j < rulesForMappedAttributeKey.length; j++) {\n if (!this.doesEventMatchRule(event, rulesForMappedAttributeKey[j])) {\n allMatch = false;\n break;\n }\n }\n if (!allMatch) {\n continue;\n }\n\n mp().Rokt.setLocalSessionAttribute?.(mappedAttributeKey, true);\n }\n }\n\n private isLauncherReadyToAttach(): boolean {\n return !!window.Rokt && typeof window.Rokt.createLauncher === 'function';\n }\n\n /**\n * Returns the user identities from the filtered user, if any.\n */\n private returnUserIdentities(filteredUser: FilteredUser | null | undefined): Record {\n if (!filteredUser || !filteredUser.getUserIdentities) {\n return {};\n }\n\n const userIdentities: IUserIdentities = filteredUser.getUserIdentities().userIdentities;\n\n return this.replaceOtherIdentityWithEmailsha256(userIdentities);\n }\n\n private returnLocalSessionAttributes(): Record {\n if (!mp().Rokt || typeof mp().Rokt.getLocalSessionAttributes !== 'function') {\n return {};\n }\n if (isEmpty(this.placementEventMappingLookup) && isEmpty(this.placementEventAttributeMappingLookup)) {\n return {};\n }\n return mp().Rokt.getLocalSessionAttributes!();\n }\n\n private replaceOtherIdentityWithEmailsha256(userIdentities: IUserIdentities): Record {\n const newUserIdentities: Record = { ...(userIdentities || {}) };\n const key = this._mappedEmailSha256Key;\n if (key && userIdentities[key as keyof IUserIdentities]) {\n newUserIdentities[RoktKit.EMAIL_SHA256_KEY] = userIdentities[key as keyof IUserIdentities] as string;\n }\n if (key) {\n delete newUserIdentities[key];\n }\n\n return newUserIdentities;\n }\n\n private logSelectPlacementsEvent(attributes: unknown): void {\n if (!window.mParticle || typeof mp().logEvent !== 'function') {\n return;\n }\n\n if (!isObject(attributes)) {\n return;\n }\n\n const EVENT_TYPE_OTHER = mp().EventType.Other;\n\n mp().logEvent(EVENT_NAME_SELECT_PLACEMENTS, EVENT_TYPE_OTHER, attributes as Record);\n }\n\n private setRoktSessionId(sessionId: string): void {\n if (!sessionId || typeof sessionId !== 'string') {\n return;\n }\n try {\n const mpInstance = mp().getInstance();\n if (mpInstance && typeof mpInstance.setIntegrationAttribute === 'function') {\n mpInstance.setIntegrationAttribute(moduleId, {\n roktSessionId: sessionId,\n });\n }\n } catch (_e) {\n // Best effort — never let this break the partner page\n }\n }\n\n private attachLauncher(\n accountId: string,\n launcherOptions: Record,\n legacyRoktExtensions: string[] = [],\n ): void {\n const mpSessionId =\n mp() && mp().sessionManager && typeof mp().sessionManager!.getSession === 'function'\n ? mp().sessionManager!.getSession()\n : undefined;\n\n const options: Record = {\n accountId,\n ...(launcherOptions || {}),\n ...(mpSessionId ? { mpSessionId } : {}),\n };\n\n let launcherPromise: Promise;\n if (this.isPartnerInLocalLauncherTestGroup()) {\n launcherPromise = Promise.resolve(window.Rokt!.createLocalLauncher(options));\n } else {\n launcherPromise = window.Rokt!.createLauncher(options);\n }\n\n launcherPromise\n .then(async (launcher) => {\n await registerLegacyExtensions(legacyRoktExtensions, launcher);\n this.initRoktLauncher(launcher);\n })\n .catch((err: unknown) => {\n console.error('Error creating Rokt launcher:', err);\n });\n }\n\n private initRoktLauncher(launcher: RoktLauncher): void {\n // Assign the launcher to a global variable for later access\n if (window.Rokt) {\n window.Rokt.currentLauncher = launcher;\n }\n // Locally cache the launcher and filters\n this.launcher = launcher;\n\n const roktFilters = mp().Rokt?.filters;\n\n if (!roktFilters) {\n console.warn('Rokt Kit: No filters have been set.');\n } else {\n this.filters = roktFilters;\n if (!roktFilters.filteredUser) {\n console.warn('Rokt Kit: No filtered user has been set.');\n } else {\n this._workspaceSearchInFlightPromise = this.search(roktFilters.filteredUser);\n }\n }\n\n // Kit must be initialized before attaching to the Rokt manager\n this.isInitialized = true;\n\n sendAdBlockMeasurementSignals(this.domain, this.integrationName);\n\n // Attaches the kit to the Rokt manager\n mp().Rokt.attachKit(this);\n }\n\n private fetchOptimizely(): Record {\n const forwarders = mp()\n ._getActiveForwarders()\n .filter((forwarder) => forwarder.name === 'Optimizely');\n\n try {\n if (forwarders.length > 0 && window.optimizely) {\n const optimizelyState = window.optimizely.get('state');\n if (!optimizelyState || !optimizelyState.getActiveExperimentIds) {\n return {};\n }\n const activeExperimentIds = optimizelyState.getActiveExperimentIds();\n const activeExperiments = activeExperimentIds.reduce((acc: Record, expId: string) => {\n acc['rokt.custom.optimizely.experiment.' + expId + '.variationId'] =\n optimizelyState.getVariationMap()[expId].id;\n return acc;\n }, {});\n return activeExperiments;\n }\n } catch (error) {\n console.error('Error fetching Optimizely attributes:', error);\n }\n return {};\n }\n\n private isKitReady(): boolean {\n return !!(this.isInitialized && this.launcher);\n }\n\n private isPartnerInLocalLauncherTestGroup(): boolean {\n return !!(mp().config && mp().config!.isLocalLauncherEnabled && this.isAssignedToSampleGroup());\n }\n\n private isAssignedToSampleGroup(): boolean {\n const LOCAL_LAUNCHER_TEST_GROUP_THRESHOLD = 0.5;\n return Math.random() > LOCAL_LAUNCHER_TEST_GROUP_THRESHOLD;\n }\n\n private captureTiming(metricName: string): void {\n if (window && mp() && mp().captureTiming && metricName) {\n mp().captureTiming!(metricName);\n }\n }\n\n // ---- Public methods (mParticle Kit Callbacks) ----\n\n /**\n * Initializes the Rokt forwarder with settings from the mParticle server.\n */\n public init(\n settings: Record,\n _service: unknown,\n testMode: boolean,\n _trackerId: unknown,\n filteredUserAttributes?: Record,\n ): string {\n const kitSettings = settings as unknown as RoktKitSettings;\n const accountId = kitSettings.accountId;\n this.userAttributes = removeSelectPlacementsAttributePersistenceDeniedAttributes(filteredUserAttributes);\n this._onboardingExpProvider = kitSettings.onboardingExpProvider;\n\n const placementEventMapping = parseSettingsString(kitSettings.placementEventMapping);\n this.placementEventMappingLookup = generateMappedEventLookup(placementEventMapping);\n\n const placementEventAttributeMapping = parseSettingsString(\n kitSettings.placementEventAttributeMapping,\n );\n this.placementEventAttributeMappingLookup = generateMappedEventAttributeLookup(placementEventAttributeMapping);\n\n // Set dynamic OTHER_IDENTITY based on server settings\n if (kitSettings.hashedEmailUserIdentityType) {\n this._mappedEmailSha256Key = kitSettings.hashedEmailUserIdentityType.toLowerCase();\n }\n\n this._workspaceIdSyncApiKey = isString(kitSettings.workspaceIdSyncApiKey)\n ? kitSettings.workspaceIdSyncApiKey\n : undefined;\n\n const domain = mp().Rokt?.domain;\n const { roktExtensionsQueryParams, legacyRoktExtensions, loadThankYouElement } = extractRoktExtensionConfig(\n kitSettings.roktExtensions,\n );\n const launcherOptions: Record = {\n ...((mp().Rokt?.launcherOptions as Record) || {}),\n };\n this.integrationName = generateIntegrationName(launcherOptions.integrationName as string | undefined);\n launcherOptions.integrationName = this.integrationName;\n\n this.domain = domain;\n\n const reportingConfig: ReportingConfig = {\n loggingUrl: kitSettings.loggingUrl,\n errorUrl: kitSettings.errorUrl,\n integrationDomain: domain,\n isLoggingEnabled: mp().config?.isLoggingEnabled === true,\n };\n const errorReportingService = new ErrorReportingService(\n reportingConfig,\n this.integrationName,\n window.__rokt_li_guid__,\n kitSettings.accountId,\n );\n const loggingService = new LoggingService(\n reportingConfig,\n errorReportingService,\n this.integrationName,\n window.__rokt_li_guid__,\n kitSettings.accountId,\n );\n\n this.errorReportingService = errorReportingService;\n this.loggingService = loggingService;\n\n if (mp()._registerErrorReportingService) {\n mp()._registerErrorReportingService!(errorReportingService);\n }\n if (mp()._registerLoggingService) {\n mp()._registerLoggingService!(loggingService);\n }\n\n if (testMode) {\n this.testHelpers = {\n generateLauncherScript: generateLauncherScript,\n generateThankYouElementScript: generateThankYouElementScript,\n extractRoktExtensionConfig: extractRoktExtensionConfig,\n hashEventMessage: hashEventMessage,\n parseSettingsString: parseSettingsString,\n generateMappedEventLookup: generateMappedEventLookup,\n generateMappedEventAttributeLookup: generateMappedEventAttributeLookup,\n sendAdBlockMeasurementSignals: sendAdBlockMeasurementSignals,\n createAutoRemovedIframe: createAutoRemovedIframe,\n djb2: djb2,\n setAllowedOriginHashes: (hashes: number[]) => {\n RoktKit._allowedOriginHashes = hashes;\n },\n ReportingTransport: ReportingTransport,\n ErrorReportingService: ErrorReportingService,\n LoggingService: LoggingService,\n RateLimiter: RateLimiter,\n ErrorCodes: ErrorCodes,\n WSDKErrorSeverity: WSDKErrorSeverity,\n };\n this.attachLauncher(accountId, launcherOptions);\n return 'Successfully initialized: ' + name;\n }\n\n if (loadThankYouElement) {\n mp().Rokt.flushOnShoppableAdsReadyMessageQueue?.(this);\n loadRoktScript(ROKT_THANK_YOU_ELEMENT_SCRIPT_ID, generateThankYouElementScript(domain), {\n onLoad: () => {\n this._isThankYouElementLoaded = true;\n if (this._thankYouElementOnLoadCallback) {\n this._thankYouElementOnLoadCallback();\n }\n },\n onError: (error) => {\n console.error('Error loading Rokt Thank You Element script:', error);\n },\n });\n }\n\n if (this.isLauncherReadyToAttach()) {\n this.attachLauncher(accountId, launcherOptions, legacyRoktExtensions);\n } else {\n loadRoktScript(ROKT_INTEGRATION_SCRIPT_ID, generateLauncherScript(domain, roktExtensionsQueryParams), {\n onLoad: () => {\n if (this.isLauncherReadyToAttach()) {\n this.attachLauncher(accountId, launcherOptions, legacyRoktExtensions);\n } else {\n console.error('Rokt object is not available after script load.');\n }\n },\n onError: (error) => {\n console.error('Error loading Rokt launcher script:', error);\n },\n });\n\n this.captureTiming(RoktKit.PERFORMANCE_MARKS.RoktScriptAppended);\n }\n\n return 'Successfully initialized: ' + name;\n }\n\n public process(event: SDKEvent): string {\n if (!this.isKitReady()) {\n return 'Kit not ready for forwarder: ' + name;\n }\n if (typeof mp().Rokt?.setLocalSessionAttribute === 'function') {\n if (!isEmpty(this.placementEventAttributeMappingLookup)) {\n this.applyPlacementEventAttributeMapping(event);\n }\n\n if (!isEmpty(this.placementEventMappingLookup)) {\n const hashedEvent = hashEventMessage(event.EventDataType, event.EventCategory, event.EventName ?? '');\n if (this.placementEventMappingLookup[String(hashedEvent)]) {\n mp().Rokt.setLocalSessionAttribute?.(this.placementEventMappingLookup[String(hashedEvent)], true);\n }\n }\n }\n\n return 'Successfully sent to forwarder: ' + name;\n }\n\n public setExtensionData(partnerExtensionData: Record): void {\n if (!this.isKitReady()) {\n console.error('Rokt Kit: Not initialized');\n return;\n }\n\n window.Rokt!.setExtensionData(partnerExtensionData);\n }\n\n public setUserAttribute(key: string, value: unknown): string {\n if (!isSelectPlacementsAttributePersistenceDenied(key)) {\n this.userAttributes[key] = value;\n }\n return 'Successfully set user attribute for forwarder: ' + name;\n }\n\n public removeUserAttribute(key: string): string {\n delete this.userAttributes[key];\n return 'Successfully removed user attribute for forwarder: ' + name;\n }\n\n private handleIdentityComplete(user: IMParticleUser, callbackName: string): string {\n this.userAttributes = removeSelectPlacementsAttributePersistenceDeniedAttributes(user.getAllUserAttributes());\n return 'Successfully called ' + callbackName + ' for forwarder: ' + name;\n }\n\n public onUserIdentified(user: IMParticleUser): string {\n const filteredUser = user as FilteredUser;\n this.filters.filteredUser = filteredUser;\n this._workspaceSearchInFlightPromise = this.search(filteredUser);\n return this.handleIdentityComplete(user, 'onUserIdentified');\n }\n\n private search(filteredUser: FilteredUser): Promise {\n const apiKey = this._workspaceIdSyncApiKey;\n if (!apiKey) {\n this.userIdentifiedInWorkspace = false;\n this._workspaceLastSearchedIdentitiesKey = undefined;\n return Promise.resolve();\n }\n const search = mp().Identity?.search;\n if (typeof search !== 'function') {\n this.userIdentifiedInWorkspace = false;\n this._workspaceLastSearchedIdentitiesKey = undefined;\n return Promise.resolve();\n }\n\n const userIdentities: IUserIdentities | null = filteredUser.getUserIdentities\n ? filteredUser.getUserIdentities().userIdentities\n : null;\n\n // Forward every non-empty string identifier the user has — email,\n // customerid, other/other2-10 (commonly used for hashed email),\n // mobile_number, facebook, etc. The host SDK's Identity.search accepts\n // the full IUserIdentities surface and the server validates it.\n const knownIdentities: Record = {};\n if (userIdentities) {\n for (const key of Object.keys(userIdentities) as Array) {\n const value = userIdentities[key];\n if (isString(value) && value.length > 0) {\n knownIdentities[key] = value;\n }\n }\n }\n\n const identityKeys = Object.keys(knownIdentities);\n if (identityKeys.length === 0) {\n this.userIdentifiedInWorkspace = false;\n this._workspaceLastSearchedIdentitiesKey = undefined;\n return Promise.resolve();\n }\n\n // Stable cache key: sort keys so insertion-order differences don't\n // cause false misses. The values are partner-supplied strings; no\n // hashing needed — equality on this serialization is sufficient.\n const identitiesKey = identityKeys\n .sort()\n .map((k) => `${k}=${knownIdentities[k]}`)\n .join('&');\n\n // Same identifier set as the last successful dispatch → skip the\n // network call. The current flag value still reflects the correct\n // match status.\n if (identitiesKey === this._workspaceLastSearchedIdentitiesKey) {\n return this._workspaceSearchInFlightPromise || Promise.resolve();\n }\n\n // New / different identifier set → reset and re-search. Cache the key\n // up front so a second concurrent invocation with the same set also\n // dedupes.\n this.userIdentifiedInWorkspace = false;\n this._workspaceLastSearchedIdentitiesKey = identitiesKey;\n\n return new Promise((resolve) => {\n try {\n search(apiKey, knownIdentities as IUserIdentities, (result: WorkspaceIdSyncResult) => {\n if (result?.httpCode === 200) {\n this.userIdentifiedInWorkspace = true;\n }\n resolve();\n });\n } catch (err) {\n console.error('Rokt Kit: Workspace IDSync search failed', err);\n // Dispatch failed — clear the cache so the same identifier set\n // can retry on the next identification rather than being stuck\n // behind a poisoned entry that short-circuits future searches.\n this._workspaceLastSearchedIdentitiesKey = undefined;\n resolve();\n }\n });\n }\n\n public onLoginComplete(user: IMParticleUser, _filteredIdentityRequest: unknown): string {\n return this.handleIdentityComplete(user, 'onLoginComplete');\n }\n\n public onLogoutComplete(user: IMParticleUser, _filteredIdentityRequest: unknown): string {\n // Anonymous sessions must not carry the previous user's match forward.\n // Clear the flag explicitly here. Also clear the identities cache so a\n // re-login (possibly with the same identifiers) dispatches a fresh\n // search rather than reusing a stale answer.\n this.userIdentifiedInWorkspace = false;\n this._workspaceSearchInFlightPromise = null;\n this._workspaceLastSearchedIdentitiesKey = undefined;\n return this.handleIdentityComplete(user, 'onLogoutComplete');\n }\n\n public onModifyComplete(user: IMParticleUser, _filteredIdentityRequest: unknown): string {\n return this.handleIdentityComplete(user, 'onModifyComplete');\n }\n\n /**\n * Selects placements for Rokt Web SDK with merged attributes, filters, and experimentation options.\n *\n * If a Workspace IDSync search is in flight from a recent onUserIdentified\n * call, this method waits up to `WORKSPACE_SEARCH_SELECT_TIMEOUT_MS` for it\n * to settle so the first placement call can include the\n * `userIdentifiedInWorkspace` flag without racing the network response.\n * The timeout protects against a stalled or slow search blocking placement\n * rendering — if it fires, selectPlacements proceeds without the flag.\n *\n * Implementation note: this method stays non-async deliberately. First,\n * the public return type is `RoktSelection | Promise |\n * undefined` — a superset of the `RoktSelection | Promise`\n * shape declared for `RoktLauncher.selectPlacements` above (line ~70).\n * Marking this `async` would narrow it to `Promise` and silently change the contract for callers that read\n * the result synchronously. Second, `RoktSelection` has an optional\n * `then?` member, so TS treats it as ambiguously promise-like and\n * rejects it as the awaited return of an async function (TS1058) —\n * working around that would require a cast or wrapping every return in\n * `Promise.resolve(...)`. The inner work runs in `_dispatchPlacements`;\n * this wrapper just gates it on the in-flight search via `Promise.race`.\n */\n public selectPlacements(options: Record): RoktSelection | Promise | undefined {\n if (this._workspaceSearchInFlightPromise) {\n const inFlight = this._workspaceSearchInFlightPromise;\n return Promise.race([\n inFlight,\n new Promise((resolve) => setTimeout(resolve, WORKSPACE_SEARCH_SELECT_TIMEOUT_MS)),\n ]).then(() => this._dispatchPlacements(options)) as Promise;\n }\n return this._dispatchPlacements(options);\n }\n\n private _dispatchPlacements(options: Record): RoktSelection | Promise | undefined {\n const attributes = ((options && (options.attributes as Record)) || {}) as Record;\n const cachedUserAttributes = removeSelectPlacementsAttributePersistenceDeniedAttributes(this.userAttributes);\n const placementAttributes: Record = { ...cachedUserAttributes, ...attributes };\n\n const filters = this.filters || {};\n const userAttributeFilters = (filters.userAttributeFilters as string[]) || [];\n const filteredUser = filters.filteredUser || null;\n const mpid = filteredUser ? filteredUser.getMPID() : null;\n\n let filteredAttributes: Record;\n\n if (!filters) {\n console.warn('Rokt Kit: No filters available, using user attributes');\n filteredAttributes = placementAttributes;\n } else if (filters.filterUserAttributes) {\n filteredAttributes = filters.filterUserAttributes(placementAttributes, userAttributeFilters);\n } else {\n filteredAttributes = placementAttributes;\n }\n\n this.userAttributes = removeSelectPlacementsAttributePersistenceDeniedAttributes(filteredAttributes);\n\n const optimizelyAttributes = this._onboardingExpProvider === 'Optimizely' ? this.fetchOptimizely() : {};\n\n const filteredUserIdentities = this.returnUserIdentities(filteredUser);\n\n const localSessionAttributes = this.returnLocalSessionAttributes();\n\n const selectPlacementsAttributes: Record = {\n ...(filteredUserIdentities as Record),\n ...filteredAttributes,\n ...optimizelyAttributes,\n ...localSessionAttributes,\n ...(this.userIdentifiedInWorkspace ? { [USER_IDENTIFIED_IN_WORKSPACE_KEY]: true } : {}),\n mpid,\n };\n\n const selectPlacementsOptions: Record = { ...options, attributes: selectPlacementsAttributes };\n\n const selection = this.launcher!.selectPlacements(selectPlacementsOptions);\n\n // After selection resolves, sync the Rokt session ID back to mParticle, then log\n const logSelection = () => this.logSelectPlacementsEvent(selectPlacementsAttributes);\n\n void Promise.resolve(selection)\n .then((sel) => sel?.context?.sessionId?.then((sessionId) => this.setRoktSessionId(sessionId)))\n .catch(() => undefined)\n .finally(logSelection);\n\n return selection;\n }\n\n /**\n * Passes attributes to the Rokt Web SDK for client-side hashing.\n */\n public hashAttributes(attributes: Record): Promise> | null {\n if (!this.isKitReady()) {\n console.error('Rokt Kit: Not initialized');\n return null;\n }\n return this.launcher!.hashAttributes(attributes);\n }\n\n /**\n * Enables optional Integration Launcher extensions before selecting placements.\n *\n * @deprecated This functionality has been internalized and will be removed in a future release.\n */\n public use(extensionName: string): Promise {\n if (!this.isKitReady()) {\n console.error('Rokt Kit: Not initialized');\n return Promise.reject(new Error('Rokt Kit: Not initialized'));\n }\n if (!extensionName || !isString(extensionName)) {\n return Promise.reject(new Error('Rokt Kit: Invalid extension name'));\n }\n return this.launcher!.use(extensionName);\n }\n\n /**\n * Registers a callback to be invoked once rokt-thank-you-element.js becomes available.\n */\n public onShoppableAdsReady(callback: () => void) {\n if (this._isThankYouElementLoaded) {\n callback();\n } else {\n this._thankYouElementOnLoadCallback = callback;\n }\n }\n}\n\n// ============================================================\n// Kit registration\n// ============================================================\n\nfunction getId(): number {\n return moduleId;\n}\n\nfunction register(config: { kits?: Record }): void {\n if (!config) {\n window.console.log('You must pass a config object to register the kit ' + name);\n return;\n }\n if (!isObject(config)) {\n window.console.log(\"'config' must be an object. You passed in a \" + typeof config);\n return;\n }\n\n if (isObject(config.kits)) {\n (config.kits as Record)[name] = {\n constructor: RoktKit,\n };\n } else {\n config.kits = {};\n config.kits[name] = {\n constructor: RoktKit,\n };\n }\n window.console.log('Successfully registered ' + name + ' to your mParticle configuration');\n}\n\nif (typeof window !== 'undefined' && window.mParticle && mp().addForwarder) {\n mp().addForwarder({\n name: name,\n constructor: RoktKit,\n getId: getId,\n });\n}\n\nexport { register };\n"],"names":["SELECT_PLACEMENTS_ATTRIBUTE_PERSISTENCE_DENY_LIST","SELECT_PLACEMENTS_ATTRIBUTE_PERSISTENCE_DENY_SET","isSelectPlacementsAttributePersistenceDenied","key","removeSelectPlacementsAttributePersistenceDeniedAttributes","attributes","filteredAttributes","sourceAttributes","attributeKeys","i","name","moduleId","EVENT_NAME_SELECT_PLACEMENTS","ADBLOCK_CONTROL_DOMAIN","INIT_LOG_SAMPLING_RATE","ROKT_THANK_YOU_JOURNEY_EXTENSION","ROKT_INTEGRATION_SCRIPT_ID","ROKT_THANK_YOU_ELEMENT_SCRIPT_ID","USER_IDENTIFIED_IN_WORKSPACE_KEY","WORKSPACE_SEARCH_SELECT_TIMEOUT_MS","ErrorCodes","WSDKErrorSeverity","DEFAULT_ROKT_DOMAIN","LOGGING_ENDPOINT","ERROR_ENDPOINT","RATE_LIMIT_PER_SEVERITY","mp","generateLauncherScript","domain","extensions","baseUrl","generateBaseUrl","generateThankYouElementScript","generateReportingUrl","configuredUrl","endpoint","loadRoktScript","scriptId","source","handlers","target","script","isObject","val","parseSettingsString","settingsString","extractRoktExtensionConfig","settings","roktExtensionsQueryParams","legacyRoktExtensions","loadThankYouElement","extensionName","registerLegacyExtensions","legacyExtensions","launcher","extension","generateMappedEventLookup","placementEventMapping","mappedEvents","mapping","generateMappedEventAttributeLookup","placementEventAttributeMapping","mappedAttributeKeys","isString","mappedAttributeKey","eventAttributeKey","hashEventMessage","messageType","eventType","eventName","isEmpty","value","generateIntegrationName","customIntegrationName","integrationName","djb2","str","hash","createAutoRemovedIframe","src","iframe","sendAdBlockMeasurementSignals","version","originHash","RoktKit","guid","pageUrl","params","_isDebugModeEnabled","_getReportingUrl","_getUserAgent","RateLimiter","severity","newCount","ReportingTransport","config","launcherInstanceGuid","accountId","rateLimiter","isLoggingEnabled","url","msg","code","stackTrace","onError","logRequest","headers","response","serverError","error","ErrorReportingService","LoggingService","errorReportingService","entry","isServerSide","_RoktKit","event","condition","actualValue","operator","expectedValue","rule","conditions","rulesForMappedAttributeKey","allMatch","j","filteredUser","userIdentities","newUserIdentities","EVENT_TYPE_OTHER","sessionId","mpInstance","launcherOptions","mpSessionId","options","launcherPromise","err","roktFilters","forwarders","forwarder","optimizelyState","acc","expId","metricName","_service","testMode","_trackerId","filteredUserAttributes","kitSettings","reportingConfig","loggingService","hashes","hashedEvent","partnerExtensionData","user","callbackName","apiKey","search","knownIdentities","identityKeys","identitiesKey","k","resolve","result","_filteredIdentityRequest","inFlight","placementAttributes","filters","userAttributeFilters","mpid","optimizelyAttributes","filteredUserIdentities","localSessionAttributes","selectPlacementsAttributes","selectPlacementsOptions","selection","logSelection","sel","callback","getId","register"],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"Rokt-Kit.common.js","sources":["../src/selectPlacementsAttributePersistence.ts","../src/utils.ts","../src/storage.ts","../src/pageViewStorage.ts","../src/launcherAttachState.ts","../src/Rokt-Kit.ts"],"sourcesContent":["const SELECT_PLACEMENTS_ATTRIBUTE_PERSISTENCE_DENY_LIST = [\n 'active_time_on_site_ms',\n 'billingaddress1',\n 'billingaddress2',\n 'billingcity',\n 'billingstate',\n 'billingzipcode',\n 'cartitems',\n 'ccbin',\n 'confirmationref',\n 'conversiontype',\n 'country',\n 'couponcode',\n 'currency',\n 'language',\n 'paymentserviceprovider',\n 'paymentserviceproviderattribute',\n 'paymenttype',\n 'shippingaddress1',\n 'shippingcity',\n 'shippingcountry',\n 'shippingmethod',\n 'shippingstate',\n 'shippingzipcode',\n 'totalprice',\n];\nconst SELECT_PLACEMENTS_ATTRIBUTE_PERSISTENCE_DENY_SET = new Set(SELECT_PLACEMENTS_ATTRIBUTE_PERSISTENCE_DENY_LIST);\n\nexport function isSelectPlacementsAttributePersistenceDenied(key: string): boolean {\n return SELECT_PLACEMENTS_ATTRIBUTE_PERSISTENCE_DENY_SET.has(key.toLowerCase());\n}\n\nexport function removeSelectPlacementsAttributePersistenceDeniedAttributes(\n attributes: Record | null | undefined,\n): Record {\n const filteredAttributes: Record = {};\n const sourceAttributes = attributes || {};\n const attributeKeys = Object.keys(sourceAttributes);\n\n for (let i = 0; i < attributeKeys.length; i++) {\n const key = attributeKeys[i];\n if (!isSelectPlacementsAttributePersistenceDenied(key)) {\n filteredAttributes[key] = sourceAttributes[key];\n }\n }\n\n return filteredAttributes;\n}\n","export function isObject(value: unknown): value is Record {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nexport function isString(value: unknown): value is string {\n return typeof value === 'string';\n}\n\nexport function isFunction(value: unknown): value is (...args: Array) => unknown {\n return typeof value === 'function';\n}\n\nexport function isEmpty(value: unknown): boolean {\n if (value == null) return true;\n if (typeof value === 'object') {\n return Object.keys(value as object).length === 0;\n }\n return false;\n}\n\n// Strips the query string from a URL before it is persisted and sent to Rokt,\n// since query params commonly carry PII (emails, tokens, order refs).\n// Returns the input unchanged if it can't be parsed as a URL.\nexport function sanitizeUrl(href: string): string {\n try {\n const url = new URL(href);\n url.search = '';\n return url.toString();\n } catch {\n return href;\n }\n}\n","import { isObject } from './utils';\n\nconst LS_PROBE_KEY = '__rokt_ls_probe__';\n\nexport function isLocalStorageAvailable(): boolean {\n try {\n window.localStorage.setItem(LS_PROBE_KEY, '1');\n window.localStorage.removeItem(LS_PROBE_KEY);\n return true;\n } catch {\n return false;\n }\n}\n\nexport function readJSON(key: string): unknown {\n try {\n const stored = window.localStorage.getItem(key);\n return stored === null ? null : JSON.parse(stored);\n } catch {\n return null;\n }\n}\n\nexport function writeJSON(key: string, value: unknown): boolean {\n try {\n window.localStorage.setItem(key, JSON.stringify(value));\n return true;\n } catch {\n return false;\n }\n}\n\nexport function removeKey(key: string): void {\n try {\n window.localStorage.removeItem(key);\n } catch {\n /* empty */\n }\n}\n\nexport function readNamespacedField(namespaceKey: string, field: string): unknown {\n const blob = readJSON(namespaceKey);\n return isObject(blob) ? blob[field] : undefined;\n}\n\nexport function writeNamespacedField(namespaceKey: string, field: string, value: unknown): boolean {\n const blob = readJSON(namespaceKey);\n const next = isObject(blob) ? { ...blob } : {};\n next[field] = value;\n return writeJSON(namespaceKey, next);\n}\n\nexport function removeNamespacedField(namespaceKey: string, field: string): void {\n const blob = readJSON(namespaceKey);\n if (!isObject(blob) || !(field in blob)) {\n return;\n }\n const next = { ...blob };\n delete next[field];\n if (Object.keys(next).length === 0) {\n removeKey(namespaceKey);\n } else {\n writeJSON(namespaceKey, next);\n }\n}\n","import type { LoggingService } from './Rokt-Kit';\nimport { readNamespacedField, writeNamespacedField, removeNamespacedField, isLocalStorageAvailable } from './storage';\nimport { sanitizeUrl, isObject } from './utils';\n\nconst LS_NAMESPACE_KEY = 'mp-rokt-kit';\nconst LS_PAGE_VIEWS_FIELD = 'pageViews';\nconst LS_UTM_PARAMS_FIELD = 'utmParams';\nexport const PAGE_VIEWS_MAX_COUNT = 25;\n\nconst UTM_KEYS = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content'] as const;\ntype UtmKey = (typeof UTM_KEYS)[number];\nexport type UtmParams = Partial>;\n\nexport interface PageEvent {\n pageUrl: string;\n sourceMessageId: string;\n timestamp: number;\n pageTitle?: string;\n canonicalUrl?: string;\n activeTimeOnSite?: number;\n activeTimeOnPage?: number;\n}\n\nfunction capPageViews(views: PageEvent[]): PageEvent[] {\n return views.slice(-PAGE_VIEWS_MAX_COUNT);\n}\n\nexport function loadPageViews(): PageEvent[] {\n const stored = readNamespacedField(LS_NAMESPACE_KEY, LS_PAGE_VIEWS_FIELD);\n return Array.isArray(stored) ? (stored as PageEvent[]) : [];\n}\n\nexport function writePageViews(pageViews: PageEvent[]): number {\n const views = capPageViews(pageViews);\n for (let i = 0; i < views.length; i++) {\n const toWrite = views.slice(i);\n if (writeNamespacedField(LS_NAMESPACE_KEY, LS_PAGE_VIEWS_FIELD, toWrite)) {\n return toWrite.length;\n }\n }\n return 0;\n}\n\nexport function clearPageViews(): void {\n removeNamespacedField(LS_NAMESPACE_KEY, LS_PAGE_VIEWS_FIELD);\n}\n\nexport function buildPageEvents(pageViews: PageEvent[]): PageEvent[] {\n const views = capPageViews(pageViews);\n return views.map((pageView, index) => {\n const activeTimeOnSite = pageView.activeTimeOnSite;\n const hasActiveTime = activeTimeOnSite !== undefined && Number.isFinite(activeTimeOnSite);\n\n const next = views[index + 1];\n const nextActiveTimeOnSite = next?.activeTimeOnSite;\n const hasNextActiveTimeOnSite = nextActiveTimeOnSite !== undefined && Number.isFinite(nextActiveTimeOnSite);\n\n const diff = hasActiveTime && hasNextActiveTimeOnSite ? nextActiveTimeOnSite - activeTimeOnSite : undefined;\n\n return {\n pageUrl: pageView.pageUrl,\n sourceMessageId: pageView.sourceMessageId,\n timestamp: pageView.timestamp,\n ...(pageView.pageTitle !== undefined ? { pageTitle: pageView.pageTitle } : {}),\n ...(pageView.canonicalUrl !== undefined ? { canonicalUrl: pageView.canonicalUrl } : {}),\n ...(hasActiveTime ? { activeTimeOnSite } : {}),\n ...(diff !== undefined && diff >= 0 ? { activeTimeOnPage: diff } : {}),\n };\n });\n}\n\nexport function captureUtmParams(loggingService: LoggingService | null): void {\n if (readNamespacedField(LS_NAMESPACE_KEY, LS_UTM_PARAMS_FIELD) !== undefined) {\n return;\n }\n const search = new URLSearchParams(window.location.search);\n const params: UtmParams = {};\n for (const key of UTM_KEYS) {\n const value = search.get(key);\n if (value) params[key] = value;\n }\n if (Object.keys(params).length === 0) {\n return;\n }\n const captured = Object.keys(params).join(', ');\n if (!writeNamespacedField(LS_NAMESPACE_KEY, LS_UTM_PARAMS_FIELD, params)) {\n const reason = isLocalStorageAvailable() ? 'quota' : 'ls_unavailable';\n loggingService?.log({\n message: `Rokt Kit: Failed to persist UTM params [reason: ${reason}]`,\n code: 'UTM_CAPTURE_FAILED',\n });\n return;\n }\n loggingService?.log({\n message: `Rokt Kit: Captured UTM params [${captured}]`,\n code: 'UTM_CAPTURE_SUCCESS',\n });\n}\n\nexport function loadUtmParams(): UtmParams | null {\n const stored = readNamespacedField(LS_NAMESPACE_KEY, LS_UTM_PARAMS_FIELD);\n return isObject(stored) ? (stored as UtmParams) : null;\n}\n\nexport function clearUtmParams(): void {\n removeNamespacedField(LS_NAMESPACE_KEY, LS_UTM_PARAMS_FIELD);\n}\n\nexport function readCanonicalUrl(): string | undefined {\n const link = document.querySelector('link[rel=\"canonical\"]');\n const href = link?.href;\n if (!href) {\n return undefined;\n }\n return sanitizeUrl(href);\n}\n","export type RoktLauncherOptions = Record;\n\nexport interface LauncherAttachContext {\n accountId: string;\n launcherOptions: RoktLauncherOptions;\n legacyRoktExtensions: readonly string[];\n}\n\nexport type LauncherLifecycle = 'idle' | 'attached' | 'terminated' | 'recreating';\n\nexport interface LauncherAttachState {\n context: LauncherAttachContext | null;\n lifecycle: LauncherLifecycle;\n recreateInFlight: Promise | null;\n}\n\nexport type AttachLauncher = (context: LauncherAttachContext) => Promise;\n\nexport function createLauncherAttachState(): LauncherAttachState {\n return {\n context: null,\n lifecycle: 'idle',\n recreateInFlight: null,\n };\n}\n\nexport function rememberAttachContext(state: LauncherAttachState, context: LauncherAttachContext): void {\n state.context = {\n accountId: context.accountId,\n launcherOptions: { ...context.launcherOptions },\n legacyRoktExtensions: [...context.legacyRoktExtensions],\n };\n}\n\nexport function markLauncherAttached(state: LauncherAttachState): void {\n state.lifecycle = 'attached';\n}\n\nexport function markLauncherTerminated(state: LauncherAttachState): void {\n if (state.lifecycle === 'idle') {\n return;\n }\n state.lifecycle = 'terminated';\n}\n\nexport function markLauncherAttachFailed(state: LauncherAttachState): void {\n state.lifecycle = 'terminated';\n}\n\nexport function resetLauncherAttachState(state: LauncherAttachState): void {\n state.context = null;\n state.lifecycle = 'idle';\n state.recreateInFlight = null;\n}\n\nexport function recreateIfTerminated(\n state: LauncherAttachState,\n canAttach: boolean,\n attach: AttachLauncher,\n): Promise | undefined {\n if (state.recreateInFlight) {\n return state.recreateInFlight;\n }\n if (state.lifecycle !== 'terminated' || !state.context || !canAttach) {\n return undefined;\n }\n\n state.lifecycle = 'recreating';\n const context = state.context;\n state.recreateInFlight = attach(context).finally(() => {\n state.recreateInFlight = null;\n });\n return state.recreateInFlight;\n}\n","// Copyright 2025 mParticle, Inc.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n// ============================================================\n// Types\n// ============================================================\n\nimport { KitInterface, IMParticleUser, SDKEvent } from '@mparticle/web-sdk/internal';\nimport type { IUserIdentities } from '@mparticle/web-sdk';\n\nimport {\n isSelectPlacementsAttributePersistenceDenied,\n removeSelectPlacementsAttributePersistenceDeniedAttributes,\n} from './selectPlacementsAttributePersistence';\n\nimport {\n PageEvent,\n PAGE_VIEWS_MAX_COUNT,\n buildPageEvents,\n loadPageViews,\n writePageViews,\n clearPageViews,\n readCanonicalUrl,\n captureUtmParams,\n loadUtmParams,\n clearUtmParams,\n} from './pageViewStorage';\nimport { isLocalStorageAvailable } from './storage';\n\nimport { isObject, isString, isEmpty, isFunction, sanitizeUrl } from './utils';\nimport {\n createLauncherAttachState,\n markLauncherAttached,\n markLauncherAttachFailed,\n markLauncherTerminated,\n rememberAttachContext,\n recreateIfTerminated,\n resetLauncherAttachState,\n type LauncherAttachState,\n type RoktLauncherOptions,\n} from './launcherAttachState';\n\ninterface RoktKitSettings {\n accountId: string;\n roktExtensions?: string;\n placementEventMapping?: string;\n placementEventAttributeMapping?: string;\n hashedEmailUserIdentityType?: string;\n onboardingExpProvider?: string;\n loggingUrl?: string;\n errorUrl?: string;\n workspaceIdSyncApiKey?: string;\n}\n\ninterface EventAttributeCondition {\n operator: string;\n attributeValue: string;\n}\n\ninterface PlacementEventRule {\n eventAttributeKey: string;\n conditions: EventAttributeCondition[];\n}\n\ninterface EventAttributeMapping {\n value: string;\n map: string;\n conditions?: EventAttributeCondition[];\n}\n\ninterface PlacementEventMappingEntry {\n jsmap: string;\n value: string;\n}\n\ninterface RoktExtensionEntry {\n value: string;\n}\n\ninterface RoktSelection {\n context?: {\n sessionId?: Promise;\n };\n then?: (callback: (sel: RoktSelection) => void) => Promise;\n catch?: (callback: () => void) => void;\n}\n\ninterface RoktLauncher {\n selectPlacements(options: Record): RoktSelection | Promise;\n hashAttributes(attributes: Record): Promise>;\n use(extensionName: string): Promise;\n terminate(): Promise;\n}\n\ninterface RoktGlobal {\n createLauncher(options: RoktLauncherOptions): Promise;\n createLocalLauncher(options: RoktLauncherOptions): RoktLauncher;\n currentLauncher?: RoktLauncher;\n setExtensionData(data: Record): void;\n}\n\n// FilteredUser is the IMParticleUser shape we receive after kit filtering.\n// `getMPID` and `getUserIdentities` are inherited from the SDK's `User` base type.\ntype FilteredUser = IMParticleUser;\n\n// TODO: Replace with `IIdentitySearchResult` from `@mparticle/web-sdk` once\n// a version that exports it is published (currently on a feature branch in\n// mParticle/mparticle-web-sdk PR #1255). The shape below is intentionally\n// structurally identical so the swap is a one-line import change.\ninterface WorkspaceIdSyncResult {\n httpCode: number;\n body?: {\n context?: string | null;\n mpid?: string;\n matched_identities?: Record;\n is_ephemeral?: boolean;\n is_logged_in?: boolean;\n };\n}\n\n// TODO: Replace with `IdentitySearchCallback`-compatible reference from\n// `@mparticle/web-sdk` once published (mirrors `SDKIdentityApi.search`).\ntype WorkspaceIdSyncSearcher = (\n apiKey: string,\n knownIdentities: IUserIdentities,\n callback: (result: WorkspaceIdSyncResult) => void,\n) => void;\n\ninterface KitFilters {\n userAttributeFilters?: string[];\n filterUserAttributes?: (attributes: Record, filters?: string[]) => Record;\n filteredUser?: FilteredUser | null;\n}\n\ninterface RoktManager {\n attachKit(kit: RoktKit): void | Promise;\n flushOnShoppableAdsReadyMessageQueue?(kit: RoktKit): void;\n filters?: KitFilters;\n domain?: string;\n launcherOptions?: Record;\n getLocalSessionAttributes?(): Record;\n setLocalSessionAttribute?(key: string, value: unknown): void;\n}\n\ninterface MParticleInstance {\n setIntegrationAttribute(moduleId: number, attrs: Record): void;\n}\n\ninterface OptimizelyState {\n getActiveExperimentIds(): string[];\n getVariationMap(): Record;\n}\n\ninterface OptimizelyGlobal {\n get(key: 'state'): OptimizelyState;\n}\n\n// Our view of the mParticle global with Rokt-specific extensions.\n// We access window.mParticle via an explicit cast (see `mp()` helper below)\n// rather than augmenting Window to avoid conflicts with @mparticle/web-sdk declarations.\ninterface MParticleExtended {\n Rokt: RoktManager;\n addForwarder(config: ForwarderRegistration): void;\n getVersion(): string;\n generateHash(value: string): string | number;\n logEvent(name: string, type: number, attrs?: Record): void;\n EventType: { Other: number };\n getInstance(): MParticleInstance;\n getDeviceId?(): string;\n sessionManager?: { getSession?(): string; getSessionId?(): string };\n _getActiveForwarders(): Array<{ name: string }>;\n config?: { isLocalLauncherEnabled?: boolean; isLoggingEnabled?: boolean };\n captureTiming?(metricName: string): void;\n forwarder?: RoktKit;\n loggedEvents?: Array>;\n _registerErrorReportingService?(service: ErrorReportingService): void;\n _registerLoggingService?(service: LoggingService): void;\n Identity?: { search?: WorkspaceIdSyncSearcher };\n}\n\ninterface TestHelpers {\n generateLauncherScript: (domain: string | undefined, extensions: string[]) => string;\n generateThankYouElementScript: (domain: string | undefined) => string;\n extractRoktExtensionConfig: (settingsString?: string) => RoktExtensionConfig;\n hashEventMessage: (messageType: number, eventType: number, eventName: string) => string | number;\n parseSettingsString: (settingsString?: string) => T[];\n generateMappedEventLookup: (placementEventMapping: PlacementEventMappingEntry[]) => Record;\n generateMappedEventAttributeLookup: (mapping: EventAttributeMapping[]) => Record;\n sendAdBlockMeasurementSignals: (domain: string | undefined, version: string | null) => void;\n createAutoRemovedIframe: (src: string) => void;\n djb2: (str: string) => number;\n setAllowedOriginHashes: (hashes: number[]) => void;\n ReportingTransport: typeof ReportingTransport;\n ErrorReportingService: typeof ErrorReportingService;\n LoggingService: typeof LoggingService;\n RateLimiter: typeof RateLimiter;\n ErrorCodes: typeof ErrorCodes;\n WSDKErrorSeverity: typeof WSDKErrorSeverity;\n resetLauncherAttachState: () => void;\n}\n\ninterface ForwarderRegistration {\n name: string;\n constructor: new () => RoktKit;\n getId: () => number;\n}\n\ninterface ReportingConfig {\n loggingUrl?: string;\n errorUrl?: string;\n integrationDomain?: string;\n isLoggingEnabled: boolean;\n}\n\ninterface ErrorReport {\n message: string;\n code?: string;\n severity?: string;\n stackTrace?: string;\n}\n\n// A log-delivery failure. statusCode is set when the request reached the server\n// and returned a non-2xx status (server-side); it is absent for network-level\n// failures such as ad-blockers, offline, or CORS rejections (client-side).\ninterface DeliveryError extends Error {\n statusCode?: number;\n}\n\ninterface LogEntry {\n message: string;\n code?: string;\n}\n\ninterface RoktExtensionConfig {\n roktExtensionsQueryParams: string[];\n legacyRoktExtensions: string[];\n loadThankYouElement: boolean;\n}\n\ndeclare global {\n interface Window {\n Rokt?: RoktGlobal;\n __rokt_li_guid__?: string;\n optimizely?: OptimizelyGlobal;\n // mParticle is declared as any to avoid conflicts with @mparticle/web-sdk type declarations.\n // We use the typed mp() accessor for all internal accesses.\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n mParticle: any;\n }\n}\n\n// ============================================================\n// Module-level constants\n// ============================================================\n\nconst name = 'Rokt';\nconst moduleId = 181;\nconst EVENT_NAME_SELECT_PLACEMENTS = 'selectPlacements';\nconst ADBLOCK_CONTROL_DOMAIN = 'apps.roktecommerce.com';\nconst INIT_LOG_SAMPLING_RATE = 0.1;\nconst ROKT_THANK_YOU_JOURNEY_EXTENSION = 'ThankYouPageJourney';\nconst ROKT_INTEGRATION_SCRIPT_ID = 'rokt-launcher';\nconst ROKT_THANK_YOU_ELEMENT_SCRIPT_ID = 'rokt-thank-you-element';\nconst USER_IDENTIFIED_IN_WORKSPACE_KEY = 'userIdentifiedInWorkspace';\n\nconst MESSAGE_TYPE_PAGE_VIEW = 3; // mParticle MessageType.PageView\nconst MESSAGE_TYPE_SESSION_END = 2; // mParticle MessageType.SessionEnd\nconst PAGE_EVENTS_KEY = 'page_events';\nconst PAGE_VIEW_ATTRIBUTES_KEY = 'page_view_attributes';\nconst MPARTICLE_SESSION_ID_KEY = 'mparticle_session_id';\nconst MPARTICLE_DEVICE_ID_KEY = 'mparticle_device_id';\n\n// Bound on how long selectPlacements will wait for an in-flight Workspace\n// IDSync search before proceeding without the userIdentifiedInWorkspace flag.\n// Long enough to cover the typical /v1/search round-trip (~50ms); short enough that a\n// stalled search never blocks placement rendering on a thank-you page.\nconst WORKSPACE_SEARCH_SELECT_TIMEOUT_MS = 500;\n\n// ============================================================\n// Reporting service constants\n// ============================================================\n\nconst ErrorCodes = {\n UNKNOWN_ERROR: 'UNKNOWN_ERROR',\n UNHANDLED_EXCEPTION: 'UNHANDLED_EXCEPTION',\n IDENTITY_REQUEST: 'IDENTITY_REQUEST',\n LOG_DELIVERY_FAILURE: 'LOG_DELIVERY_FAILURE',\n} as const;\n\nconst WSDKErrorSeverity = {\n ERROR: 'ERROR',\n INFO: 'INFO',\n WARNING: 'WARNING',\n} as const;\n\nconst DEFAULT_ROKT_DOMAIN = 'apps.rokt-api.com';\nconst LOGGING_ENDPOINT = '/v1/log';\nconst ERROR_ENDPOINT = '/v1/errors';\nconst RATE_LIMIT_PER_SEVERITY = 10;\n\n// ============================================================\n// Helper: typed accessor for window.mParticle\n// We use an explicit cast here to avoid conflicts with @mparticle/web-sdk\n// type declarations while still providing full type safety for our usages.\n// ============================================================\n\nfunction mp(): MParticleExtended {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n return (window as any).mParticle as MParticleExtended;\n}\n\n// ============================================================\n// Module-level utility functions\n// ============================================================\n\nfunction generateLauncherScript(domain: string | undefined, extensions: string[]): string {\n const launcherPath = '/wsdk/integrations/launcher.js';\n const baseUrl = [generateBaseUrl(domain), launcherPath].join('');\n\n if (!extensions || extensions.length === 0) {\n return baseUrl;\n }\n return baseUrl + '?extensions=' + extensions.join(',');\n}\n\nfunction generateThankYouElementScript(domain: string | undefined) {\n const thankYouElementPath = '/rokt-elements/rokt-element-thank-you.js';\n return [generateBaseUrl(domain), thankYouElementPath].join('');\n}\n\nfunction generateBaseUrl(domain: string | undefined) {\n const resolvedDomain = typeof domain !== 'undefined' ? domain : DEFAULT_ROKT_DOMAIN;\n\n if (resolvedDomain.includes('://')) {\n return resolvedDomain.replace(/\\/+$/, '');\n }\n\n const protocol = 'https://';\n\n return [protocol, resolvedDomain].join('');\n}\n\nfunction generateReportingUrl(configuredUrl: string | undefined, domain: string | undefined, endpoint: string): string {\n if (configuredUrl) {\n if (configuredUrl.startsWith('http://') || configuredUrl.startsWith('https://')) {\n return configuredUrl;\n }\n return 'https://' + configuredUrl;\n }\n\n const hasNonHttpScheme = domain?.includes('://') && !/^https?:\\/\\//i.test(domain);\n const reportingDomain = hasNonHttpScheme ? undefined : domain;\n\n return generateBaseUrl(reportingDomain) + endpoint;\n}\n\nfunction loadRoktScript(\n scriptId: string,\n source: string,\n handlers?: { onLoad?: () => void; onError?: (e: Event | string) => void },\n): void {\n if (document.getElementById(scriptId)) return; // resolves the preexisting script issue\n\n const target = document.head || document.body;\n const script = document.createElement('script');\n script.id = scriptId;\n script.type = 'text/javascript';\n script.src = source;\n script.async = true;\n script.crossOrigin = 'anonymous';\n (script as HTMLScriptElement & { fetchPriority: string }).fetchPriority = 'high';\n if (handlers?.onLoad) script.onload = handlers.onLoad;\n if (handlers?.onError) script.onerror = handlers.onError;\n target.appendChild(script);\n}\n\nfunction parseSettingsString(settingsString?: string): T[] {\n if (!settingsString) {\n return [];\n }\n try {\n return JSON.parse(settingsString.replace(/"/g, '\"')) as T[];\n } catch (_error) {\n console.error('Settings string contains invalid JSON');\n }\n return [];\n}\n\nfunction extractRoktExtensionConfig(settingsString?: string): RoktExtensionConfig {\n const settings = settingsString ? parseSettingsString(settingsString) : [];\n const roktExtensionsQueryParams: string[] = [];\n const legacyRoktExtensions: string[] = [];\n let loadThankYouElement = false;\n\n for (let i = 0; i < settings.length; i++) {\n const extensionName = settings[i].value;\n if (extensionName === 'thank-you-journey') {\n loadThankYouElement = true;\n legacyRoktExtensions.push(ROKT_THANK_YOU_JOURNEY_EXTENSION);\n } else {\n roktExtensionsQueryParams.push(extensionName);\n }\n }\n\n return {\n roktExtensionsQueryParams,\n legacyRoktExtensions,\n loadThankYouElement,\n };\n}\n\nasync function registerLegacyExtensions(legacyExtensions: string[], launcher: RoktLauncher | null) {\n const extensions: Promise[] = [];\n if (launcher) {\n for (const extension of legacyExtensions) {\n extensions.push(launcher.use(extension));\n }\n }\n\n return Promise.all(extensions);\n}\n\nfunction generateMappedEventLookup(placementEventMapping: PlacementEventMappingEntry[]): Record {\n if (!placementEventMapping) {\n return {};\n }\n\n const mappedEvents: Record = {};\n for (let i = 0; i < placementEventMapping.length; i++) {\n const mapping = placementEventMapping[i];\n mappedEvents[mapping.jsmap] = mapping.value;\n }\n return mappedEvents;\n}\n\nfunction generateMappedEventAttributeLookup(\n placementEventAttributeMapping: EventAttributeMapping[],\n): Record {\n const mappedAttributeKeys: Record = {};\n if (!Array.isArray(placementEventAttributeMapping)) {\n return mappedAttributeKeys;\n }\n for (let i = 0; i < placementEventAttributeMapping.length; i++) {\n const mapping = placementEventAttributeMapping[i];\n if (!mapping || !isString(mapping.value) || !isString(mapping.map)) {\n continue;\n }\n\n const mappedAttributeKey = mapping.value;\n const eventAttributeKey = mapping.map;\n\n if (!mappedAttributeKeys[mappedAttributeKey]) {\n mappedAttributeKeys[mappedAttributeKey] = [];\n }\n\n mappedAttributeKeys[mappedAttributeKey].push({\n eventAttributeKey: eventAttributeKey,\n conditions: Array.isArray(mapping.conditions) ? mapping.conditions : [],\n });\n }\n return mappedAttributeKeys;\n}\n\nfunction hashEventMessage(messageType: number, eventType: number, eventName: string): string | number {\n return mp().generateHash([messageType, eventType, eventName].join(''));\n}\n\nfunction generateIntegrationName(customIntegrationName?: string): string {\n const coreSdkVersion = mp().getVersion();\n const kitVersion = process.env.PACKAGE_VERSION;\n let integrationName = 'mParticle_' + 'wsdkv_' + coreSdkVersion + '_kitv_' + kitVersion;\n\n if (customIntegrationName) {\n integrationName += '_' + customIntegrationName;\n }\n return integrationName;\n}\n\nfunction djb2(str: string): number {\n let hash = 5381;\n for (let i = 0; i < str.length; i++) {\n hash = (hash << 5) + hash + str.charCodeAt(i);\n hash = hash & hash;\n }\n return hash;\n}\n\nfunction createAutoRemovedIframe(src: string): void {\n const iframe = document.createElement('iframe');\n iframe.style.display = 'none';\n iframe.setAttribute('sandbox', 'allow-scripts allow-same-origin');\n iframe.src = src;\n iframe.onload = function () {\n iframe.onload = null;\n if (iframe.parentNode) {\n iframe.parentNode.removeChild(iframe);\n }\n };\n const target = document.body || document.head;\n if (target) {\n target.appendChild(iframe);\n }\n}\n\nfunction sendAdBlockMeasurementSignals(domain: string | undefined, version: string | null): void {\n const originHash = djb2(window.location.origin);\n const allowedOriginHashes = RoktKit._allowedOriginHashes;\n if (allowedOriginHashes.indexOf(originHash) === -1) {\n return;\n }\n\n if (Math.random() >= INIT_LOG_SAMPLING_RATE) {\n return;\n }\n\n const guid = window.__rokt_li_guid__;\n if (!guid) {\n return;\n }\n\n if (domain && domain.includes('://') && !/^https:\\/\\//i.test(domain)) {\n return;\n }\n\n const pageUrl = window.location.href.split('?')[0].split('#')[0];\n const params =\n 'version=' +\n encodeURIComponent(version ?? '') +\n '&launcherInstanceGuid=' +\n encodeURIComponent(guid) +\n '&pageUrl=' +\n encodeURIComponent(pageUrl);\n\n const existingBaseUrl = domain ? generateBaseUrl(domain) : 'https://apps.rokt.com';\n createAutoRemovedIframe(existingBaseUrl + '/v1/wsdk-init/index.html?' + params);\n\n createAutoRemovedIframe(\n 'https://' + ADBLOCK_CONTROL_DOMAIN + '/v1/wsdk-init/index.html?' + params + '&isControl=true',\n );\n}\n\n// ============================================================\n// Reporting helpers\n// ============================================================\n\nfunction _isDebugModeEnabled(): boolean {\n return typeof window !== 'undefined' && !!window.location?.search?.toLowerCase().includes('mp_enable_logging=true');\n}\n\nfunction _getReportingUrl(): string | undefined {\n return typeof window !== 'undefined' ? window.location?.href : undefined;\n}\n\nfunction _getUserAgent(): string | undefined {\n return typeof window !== 'undefined' ? window.navigator?.userAgent : undefined;\n}\n\nclass RateLimiter {\n private _logCount: Record = {};\n\n incrementAndCheck(severity: string): boolean {\n const count = this._logCount[severity] || 0;\n const newCount = count + 1;\n this._logCount[severity] = newCount;\n return newCount > RATE_LIMIT_PER_SEVERITY;\n }\n}\n\nclass ReportingTransport {\n private _isEnabled: boolean;\n private _integrationName: string;\n private _launcherInstanceGuid: string | undefined;\n private _accountId: string | null;\n private _rateLimiter: RateLimiter;\n private readonly _reporter = 'mp-wsdk';\n\n constructor(\n config: ReportingConfig,\n integrationName: string | null | undefined,\n launcherInstanceGuid: string | undefined,\n accountId: string | null | undefined,\n rateLimiter?: RateLimiter,\n ) {\n const isLoggingEnabled = config.isLoggingEnabled;\n this._integrationName = integrationName || '';\n this._launcherInstanceGuid = launcherInstanceGuid;\n this._accountId = accountId || null;\n this._rateLimiter = rateLimiter || new RateLimiter();\n this._isEnabled = _isDebugModeEnabled() || isLoggingEnabled;\n }\n\n send(\n url: string,\n severity: string,\n msg: string,\n code?: string,\n stackTrace?: string,\n onError?: (error: DeliveryError) => void,\n ): void {\n if (!this._isEnabled || this._rateLimiter.incrementAndCheck(severity)) {\n return;\n }\n\n try {\n const logRequest = {\n additionalInformation: {\n message: msg,\n version: this._integrationName,\n },\n severity,\n code: code || ErrorCodes.UNKNOWN_ERROR,\n url: _getReportingUrl(),\n deviceInfo: _getUserAgent(),\n stackTrace,\n reporter: this._reporter,\n integration: this._integrationName,\n };\n\n const headers: Record = {\n Accept: 'text/plain;charset=UTF-8',\n 'Content-Type': 'application/json',\n 'rokt-launcher-version': this._integrationName,\n 'rokt-wsdk-version': 'joint',\n };\n\n if (this._launcherInstanceGuid) {\n headers['rokt-launcher-instance-guid'] = this._launcherInstanceGuid;\n }\n if (this._accountId) {\n headers['rokt-account-id'] = this._accountId;\n }\n\n fetch(url, {\n method: 'POST',\n headers,\n body: JSON.stringify(logRequest),\n })\n .then((response: Response) => {\n // fetch only rejects on network failures; an HTTP 5xx resolves with\n // ok === false. Surface server-side failures so they are not swallowed.\n if (!response.ok) {\n const serverError: DeliveryError = new Error('HTTP ' + response.status + ' from log endpoint');\n serverError.statusCode = response.status;\n throw serverError;\n }\n })\n .catch((error: DeliveryError) => {\n console.error('ReportingTransport: Failed to send log', error);\n if (onError) onError(error);\n });\n } catch (error) {\n console.error('ReportingTransport: Failed to send log', error);\n if (onError) onError(error as DeliveryError);\n }\n }\n}\n\nclass ErrorReportingService {\n private _transport: ReportingTransport;\n private _errorUrl: string;\n\n constructor(\n config: ReportingConfig,\n integrationName: string | null | undefined,\n launcherInstanceGuid?: string,\n accountId?: string | null,\n rateLimiter?: RateLimiter,\n ) {\n this._transport = new ReportingTransport(config, integrationName, launcherInstanceGuid, accountId, rateLimiter);\n this._errorUrl = generateReportingUrl(config?.errorUrl, config?.integrationDomain, ERROR_ENDPOINT);\n }\n\n report(error: ErrorReport | null | undefined): void {\n if (!error) return;\n const severity = error.severity || WSDKErrorSeverity.ERROR;\n this._transport.send(this._errorUrl, severity, error.message, error.code, error.stackTrace);\n }\n}\n\nclass LoggingService {\n private _transport: ReportingTransport;\n private _loggingUrl: string;\n private _errorReportingService: { report: (e: ErrorReport) => void };\n\n constructor(\n config: ReportingConfig,\n errorReportingService: { report: (e: ErrorReport) => void },\n integrationName: string | null | undefined,\n launcherInstanceGuid?: string,\n accountId?: string | null,\n rateLimiter?: RateLimiter,\n ) {\n this._transport = new ReportingTransport(config, integrationName, launcherInstanceGuid, accountId, rateLimiter);\n this._loggingUrl = generateReportingUrl(config?.loggingUrl, config?.integrationDomain, LOGGING_ENDPOINT);\n this._errorReportingService = errorReportingService;\n }\n\n log(entry: LogEntry | null | undefined): void {\n if (!entry) return;\n this._transport.send(\n this._loggingUrl,\n WSDKErrorSeverity.INFO,\n entry.message,\n entry.code,\n undefined,\n (error: DeliveryError) => {\n if (this._errorReportingService) {\n // A failed log POST is not itself an SDK error. Network-level failures\n // (ad-blockers, offline, CORS) are client-side noise and reported as a\n // WARNING; only a server-side non-2xx response stays at ERROR severity.\n const isServerSide = typeof error.statusCode === 'number';\n this._errorReportingService.report({\n message: 'LoggingService: Failed to send log: ' + error.message,\n code: ErrorCodes.LOG_DELIVERY_FAILURE,\n severity: isServerSide ? WSDKErrorSeverity.ERROR : WSDKErrorSeverity.WARNING,\n });\n }\n },\n );\n }\n}\n\nfunction buildPageEvent(event: SDKEvent): PageEvent {\n const pageUrl = sanitizeUrl(window.location.href);\n const pageTitle = event.EventAttributes?.title || document.title;\n const canonicalUrl = readCanonicalUrl();\n const activeTimeOnSite = event.ActiveTimeOnSite;\n\n return {\n pageUrl,\n sourceMessageId: event.SourceMessageId,\n timestamp: event.Timestamp,\n ...(pageTitle ? { pageTitle } : {}),\n ...(canonicalUrl !== undefined ? { canonicalUrl } : {}),\n ...(Number.isFinite(activeTimeOnSite) ? { activeTimeOnSite } : {}),\n };\n}\n\n// ============================================================\n// RoktKit class\n// ============================================================\n\nclass RoktKit implements KitInterface {\n // Static field for allowed origin hashes (mutable by testHelpers)\n public static _allowedOriginHashes: number[] = [-553112570, 549508659];\n\n private static readonly PERFORMANCE_MARKS = {\n RoktScriptAppended: 'mp:RoktScriptAppended',\n };\n\n private static readonly EMAIL_SHA256_KEY = 'emailsha256';\n\n // Public fields (accessed by tests and the mParticle framework)\n public name = name;\n public id = moduleId;\n public moduleId = moduleId;\n public isInitialized = false;\n public launcher: RoktLauncher | null = null;\n public filters: KitFilters = {};\n public userAttributes: Record = {};\n // Flag set by the Workspace IDSync flow on a 200 response. Stored on the\n // kit instance and merged into placement attributes inside selectPlacements.\n public userIdentifiedInWorkspace = false;\n public testHelpers: TestHelpers | null = null;\n public placementEventMappingLookup: Record = {};\n public placementEventAttributeMappingLookup: Record = {};\n public integrationName: string | null = null;\n public domain?: string;\n public errorReportingService: ErrorReportingService | null = null;\n public loggingService: LoggingService | null = null;\n\n // Private fields\n private _mappedEmailSha256Key?: string;\n private _onboardingExpProvider?: string;\n private _thankYouElementOnLoadCallback: (() => void) | null = null;\n private _isThankYouElementLoaded = false;\n private _workspaceIdSyncApiKey?: string;\n\n // Held during a search dispatch so the next selectPlacements call;\n // can wait for the HTTP response before reading userIdentifiedInWorkspace;\n // — otherwise the first placement call ships without the flag.\n private _workspaceSearchInFlightPromise: Promise | null = null;\n // Stable serialization of the identifier set sent in the most recent\n // successful search dispatch. If a subsequent identification arrives with\n // an identical set, we skip the network call (the flag is still correct\n // from the prior search). Keyed over the full IUserIdentities map — not\n // just email — so partners passing hashed email through `other`/`other2-10`\n // or any other identifier benefit from the same dedupe. Cleared on logout\n // so a re-login re-evaluates fresh.\n private _workspaceLastSearchedIdentitiesKey?: string;\n\n private _launcherAttachState: LauncherAttachState = createLauncherAttachState();\n\n // ---- Private helpers ----\n\n private getEventAttributeValue(event: SDKEvent, eventAttributeKey: string): unknown {\n const attributes = event && event.EventAttributes;\n if (!attributes) {\n return null;\n }\n\n if (typeof attributes[eventAttributeKey] === 'undefined') {\n return null;\n }\n\n return attributes[eventAttributeKey];\n }\n\n private doesEventAttributeConditionMatch(condition: EventAttributeCondition, actualValue: unknown): boolean {\n if (!condition || !isString(condition.operator)) {\n return false;\n }\n\n const operator = condition.operator.toLowerCase();\n const expectedValue = condition.attributeValue;\n\n if (operator === 'exists') {\n return actualValue !== null;\n }\n\n if (actualValue == null) {\n return false;\n }\n\n if (operator === 'equals') {\n return String(actualValue) === String(expectedValue);\n }\n\n if (operator === 'contains') {\n return String(actualValue).indexOf(String(expectedValue)) !== -1;\n }\n\n return false;\n }\n\n private doesEventMatchRule(event: SDKEvent, rule: PlacementEventRule): boolean {\n if (!rule || !isString(rule.eventAttributeKey)) {\n return false;\n }\n\n const conditions = rule.conditions;\n if (!Array.isArray(conditions)) {\n return false;\n }\n\n const actualValue = this.getEventAttributeValue(event, rule.eventAttributeKey);\n\n if (conditions.length === 0) {\n return actualValue !== null;\n }\n for (let i = 0; i < conditions.length; i++) {\n if (!this.doesEventAttributeConditionMatch(conditions[i], actualValue)) {\n return false;\n }\n }\n\n return true;\n }\n\n private applyPlacementEventAttributeMapping(event: SDKEvent): void {\n const mappedAttributeKeys = Object.keys(this.placementEventAttributeMappingLookup);\n for (let i = 0; i < mappedAttributeKeys.length; i++) {\n const mappedAttributeKey = mappedAttributeKeys[i];\n const rulesForMappedAttributeKey = this.placementEventAttributeMappingLookup[mappedAttributeKey];\n if (isEmpty(rulesForMappedAttributeKey)) {\n continue;\n }\n\n // Require ALL rules for the same key to match (AND).\n let allMatch = true;\n for (let j = 0; j < rulesForMappedAttributeKey.length; j++) {\n if (!this.doesEventMatchRule(event, rulesForMappedAttributeKey[j])) {\n allMatch = false;\n break;\n }\n }\n if (!allMatch) {\n continue;\n }\n\n mp().Rokt.setLocalSessionAttribute?.(mappedAttributeKey, true);\n }\n }\n\n private capturePageView(event: SDKEvent): void {\n let pageUrl: string | undefined;\n\n try {\n pageUrl = sanitizeUrl(window.location.href);\n\n const pageViews = loadPageViews();\n const pageView = buildPageEvent(event);\n pageViews.push(pageView);\n\n const requested = Math.min(pageViews.length, PAGE_VIEWS_MAX_COUNT);\n const stored = writePageViews(pageViews);\n if (stored === 0) {\n const reason = isLocalStorageAvailable() ? 'quota' : 'ls_unavailable';\n this.loggingService?.log({\n message: `Rokt Kit: Failed to persist page view for ${pageUrl} [reason: ${reason}]`,\n code: 'PAGE_VIEW_CAPTURE_FAILED',\n });\n } else if (stored < requested) {\n this.loggingService?.log({\n message: `Rokt Kit: Page view storage reduced from ${requested} to ${stored} record(s) under quota pressure [reason: quota_eviction]`,\n code: 'PAGE_VIEW_QUOTA_EVICTION',\n });\n }\n } catch (err) {\n const reason = isLocalStorageAvailable() ? 'exception' : 'ls_unavailable';\n const errMessage = err instanceof Error ? err.message : String(err);\n this.loggingService?.log({\n message: `Rokt Kit: Failed to capture page view for ${pageUrl}: ${errMessage} [reason: ${reason}]`,\n code: 'PAGE_VIEW_CAPTURE_FAILED',\n });\n }\n }\n\n private isLauncherReadyToAttach(): boolean {\n return !!window.Rokt && isFunction(window.Rokt.createLauncher);\n }\n\n /**\n * Returns the user identities from the filtered user, if any.\n */\n private returnUserIdentities(filteredUser: FilteredUser | null | undefined): Record {\n if (!filteredUser || !filteredUser.getUserIdentities) {\n return {};\n }\n\n const userIdentities: IUserIdentities = filteredUser.getUserIdentities().userIdentities;\n\n return this.replaceOtherIdentityWithEmailsha256(userIdentities);\n }\n\n private returnLocalSessionAttributes(): Record {\n if (!mp().Rokt || typeof mp().Rokt.getLocalSessionAttributes !== 'function') {\n return {};\n }\n return mp().Rokt.getLocalSessionAttributes!();\n }\n\n private replaceOtherIdentityWithEmailsha256(userIdentities: IUserIdentities): Record {\n const newUserIdentities: Record = { ...(userIdentities || {}) };\n const key = this._mappedEmailSha256Key;\n if (key && userIdentities[key as keyof IUserIdentities]) {\n newUserIdentities[RoktKit.EMAIL_SHA256_KEY] = userIdentities[key as keyof IUserIdentities] as string;\n }\n if (key) {\n delete newUserIdentities[key];\n }\n\n return newUserIdentities;\n }\n\n private logSelectPlacementsEvent(attributes: unknown): void {\n if (!window.mParticle || typeof mp().logEvent !== 'function') {\n return;\n }\n\n if (!isObject(attributes)) {\n return;\n }\n\n const EVENT_TYPE_OTHER = mp().EventType.Other;\n\n mp().logEvent(EVENT_NAME_SELECT_PLACEMENTS, EVENT_TYPE_OTHER, attributes as Record);\n }\n\n private setRoktSessionId(sessionId: string): void {\n if (!sessionId || typeof sessionId !== 'string') {\n return;\n }\n try {\n const mpInstance = mp().getInstance();\n if (mpInstance && isFunction(mpInstance.setIntegrationAttribute)) {\n mpInstance.setIntegrationAttribute(moduleId, {\n roktSessionId: sessionId,\n });\n }\n } catch (_e) {\n // Best effort — never let this break the partner page\n }\n }\n\n private readMpSessionId(): string | undefined {\n // The public mParticle.sessionManager facade exposes only getSession(), which already returns\n // the session id. getSessionId() lives on the internal _SessionManager and has never been\n // re-exported, so prefer it if a future core adds it and fall back to getSession() until then.\n const sessionManager = mp()?.sessionManager;\n const readSessionId = sessionManager?.getSessionId ?? sessionManager?.getSession;\n if (!isFunction(readSessionId)) {\n return undefined;\n }\n\n return readSessionId.call(sessionManager) || undefined;\n }\n\n private readMpDeviceId(): string | undefined {\n // The device application stamp (`das`) outlives the session id: core clears the session on\n // timeout, cross-tab rotation and endSession(), but never the device id, which lives in\n // localStorage/cookie for cookieExpiration days (365 by default) and survives login/logout.\n // Read it per call anyway — a partner can reassign it at any time via setDeviceId().\n return mp()?.getDeviceId?.() || undefined;\n }\n\n private attachLauncher(\n accountId: string,\n launcherOptions: RoktLauncherOptions,\n legacyRoktExtensions: readonly string[] = [],\n ): Promise {\n rememberAttachContext(this._launcherAttachState, {\n accountId,\n launcherOptions: launcherOptions || {},\n legacyRoktExtensions,\n });\n\n const options: RoktLauncherOptions = {\n accountId,\n ...(launcherOptions || {}),\n };\n\n let launcherPromise: Promise;\n if (this.isPartnerInLocalLauncherTestGroup()) {\n launcherPromise = Promise.resolve(window.Rokt!.createLocalLauncher(options));\n } else {\n launcherPromise = window.Rokt!.createLauncher(options);\n }\n\n return launcherPromise\n .then(async (launcher) => {\n await registerLegacyExtensions([...legacyRoktExtensions], launcher);\n this.initRoktLauncher(launcher);\n })\n .catch((err: unknown) => {\n markLauncherAttachFailed(this._launcherAttachState);\n console.error('Error creating Rokt launcher:', err);\n });\n }\n\n private recreateLauncherIfTerminated(): Promise | undefined {\n return recreateIfTerminated(this._launcherAttachState, this.isLauncherReadyToAttach(), (context) =>\n this.attachLauncher(context.accountId, context.launcherOptions, context.legacyRoktExtensions),\n );\n }\n\n private initRoktLauncher(launcher: RoktLauncher): void {\n // Assign the launcher to a global variable for later access\n if (window.Rokt) {\n window.Rokt.currentLauncher = launcher;\n }\n // Locally cache the launcher and filters\n this.launcher = launcher;\n markLauncherAttached(this._launcherAttachState);\n\n const roktFilters = mp().Rokt?.filters;\n\n if (!roktFilters) {\n console.warn('Rokt Kit: No filters have been set.');\n } else {\n this.filters = roktFilters;\n if (!roktFilters.filteredUser) {\n console.warn('Rokt Kit: No filtered user has been set.');\n } else {\n this._workspaceSearchInFlightPromise = this.search(roktFilters.filteredUser);\n }\n }\n\n // Kit must be initialized before attaching to the Rokt manager\n this.isInitialized = true;\n\n sendAdBlockMeasurementSignals(this.domain, this.integrationName);\n\n // Attaches the kit to the Rokt manager\n mp().Rokt.attachKit(this);\n }\n\n private fetchOptimizely(): Record {\n const forwarders = mp()\n ._getActiveForwarders()\n .filter((forwarder) => forwarder.name === 'Optimizely');\n\n try {\n if (forwarders.length > 0 && window.optimizely) {\n const optimizelyState = window.optimizely.get('state');\n if (!optimizelyState || !optimizelyState.getActiveExperimentIds) {\n return {};\n }\n const activeExperimentIds = optimizelyState.getActiveExperimentIds();\n const activeExperiments = activeExperimentIds.reduce((acc: Record, expId: string) => {\n acc['rokt.custom.optimizely.experiment.' + expId + '.variationId'] =\n optimizelyState.getVariationMap()[expId].id;\n return acc;\n }, {});\n return activeExperiments;\n }\n } catch (error) {\n console.error('Error fetching Optimizely attributes:', error);\n }\n return {};\n }\n\n private isKitReady(): boolean {\n return !!(this.isInitialized && this.launcher);\n }\n\n // When the partner has opted out of targeting (noTargeting launcher option),\n // the kit must not collect behavioral targeting signals such as page views.\n private isTargetingDisabled(): boolean {\n return (mp().Rokt?.launcherOptions as Record | undefined)?.noTargeting === true;\n }\n\n private isPartnerInLocalLauncherTestGroup(): boolean {\n return !!(mp().config && mp().config!.isLocalLauncherEnabled && this.isAssignedToSampleGroup());\n }\n\n private isAssignedToSampleGroup(): boolean {\n const LOCAL_LAUNCHER_TEST_GROUP_THRESHOLD = 0.5;\n return Math.random() > LOCAL_LAUNCHER_TEST_GROUP_THRESHOLD;\n }\n\n private captureTiming(metricName: string): void {\n if (window && mp() && mp().captureTiming && metricName) {\n mp().captureTiming!(metricName);\n }\n }\n\n // ---- Public methods (mParticle Kit Callbacks) ----\n\n /**\n * Initializes the Rokt forwarder with settings from the mParticle server.\n */\n public init(\n settings: Record,\n _service: unknown,\n testMode: boolean,\n _trackerId: unknown,\n filteredUserAttributes?: Record,\n ): string {\n const kitSettings = settings as unknown as RoktKitSettings;\n const accountId = kitSettings.accountId;\n this.userAttributes = removeSelectPlacementsAttributePersistenceDeniedAttributes(filteredUserAttributes);\n this._onboardingExpProvider = kitSettings.onboardingExpProvider;\n\n const placementEventMapping = parseSettingsString(kitSettings.placementEventMapping);\n this.placementEventMappingLookup = generateMappedEventLookup(placementEventMapping);\n\n const placementEventAttributeMapping = parseSettingsString(\n kitSettings.placementEventAttributeMapping,\n );\n this.placementEventAttributeMappingLookup = generateMappedEventAttributeLookup(placementEventAttributeMapping);\n\n // Set dynamic OTHER_IDENTITY based on server settings\n if (kitSettings.hashedEmailUserIdentityType) {\n this._mappedEmailSha256Key = kitSettings.hashedEmailUserIdentityType.toLowerCase();\n }\n\n this._workspaceIdSyncApiKey = isString(kitSettings.workspaceIdSyncApiKey)\n ? kitSettings.workspaceIdSyncApiKey\n : undefined;\n\n const domain = mp().Rokt?.domain;\n const { roktExtensionsQueryParams, legacyRoktExtensions, loadThankYouElement } = extractRoktExtensionConfig(\n kitSettings.roktExtensions,\n );\n const launcherOptions: Record = {\n ...((mp().Rokt?.launcherOptions as Record) || {}),\n };\n this.integrationName = generateIntegrationName(launcherOptions.integrationName as string | undefined);\n launcherOptions.integrationName = this.integrationName;\n\n this.domain = domain;\n\n const reportingConfig: ReportingConfig = {\n loggingUrl: kitSettings.loggingUrl,\n errorUrl: kitSettings.errorUrl,\n integrationDomain: domain,\n isLoggingEnabled: mp().config?.isLoggingEnabled === true,\n };\n const errorReportingService = new ErrorReportingService(\n reportingConfig,\n this.integrationName,\n window.__rokt_li_guid__,\n kitSettings.accountId,\n );\n const loggingService = new LoggingService(\n reportingConfig,\n errorReportingService,\n this.integrationName,\n window.__rokt_li_guid__,\n kitSettings.accountId,\n );\n\n this.errorReportingService = errorReportingService;\n this.loggingService = loggingService;\n\n if (this.isTargetingDisabled()) {\n try {\n clearPageViews();\n clearUtmParams();\n } catch (err) {\n this.errorReportingService?.report({\n message: 'Rokt Kit: Failed to clear page views when targeting is disabled',\n code: 'PAGE_VIEW_CAPTURE_FAILED',\n severity: WSDKErrorSeverity.INFO,\n stackTrace: err instanceof Error ? err.stack : undefined,\n });\n }\n }\n\n if (mp()._registerErrorReportingService) {\n mp()._registerErrorReportingService!(errorReportingService);\n }\n if (mp()._registerLoggingService) {\n mp()._registerLoggingService!(loggingService);\n }\n\n if (testMode) {\n this.testHelpers = {\n generateLauncherScript: generateLauncherScript,\n generateThankYouElementScript: generateThankYouElementScript,\n extractRoktExtensionConfig: extractRoktExtensionConfig,\n hashEventMessage: hashEventMessage,\n parseSettingsString: parseSettingsString,\n generateMappedEventLookup: generateMappedEventLookup,\n generateMappedEventAttributeLookup: generateMappedEventAttributeLookup,\n sendAdBlockMeasurementSignals: sendAdBlockMeasurementSignals,\n createAutoRemovedIframe: createAutoRemovedIframe,\n djb2: djb2,\n setAllowedOriginHashes: (hashes: number[]) => {\n RoktKit._allowedOriginHashes = hashes;\n },\n ReportingTransport: ReportingTransport,\n ErrorReportingService: ErrorReportingService,\n LoggingService: LoggingService,\n RateLimiter: RateLimiter,\n ErrorCodes: ErrorCodes,\n WSDKErrorSeverity: WSDKErrorSeverity,\n resetLauncherAttachState: () => resetLauncherAttachState(this._launcherAttachState),\n };\n this.attachLauncher(accountId, launcherOptions);\n return 'Successfully initialized: ' + name;\n }\n\n if (loadThankYouElement) {\n mp().Rokt.flushOnShoppableAdsReadyMessageQueue?.(this);\n loadRoktScript(ROKT_THANK_YOU_ELEMENT_SCRIPT_ID, generateThankYouElementScript(domain), {\n onLoad: () => {\n this._isThankYouElementLoaded = true;\n if (this._thankYouElementOnLoadCallback) {\n this._thankYouElementOnLoadCallback();\n }\n },\n onError: (error) => {\n console.error('Error loading Rokt Thank You Element script:', error);\n },\n });\n }\n\n if (this.isLauncherReadyToAttach()) {\n this.attachLauncher(accountId, launcherOptions, legacyRoktExtensions);\n } else {\n loadRoktScript(ROKT_INTEGRATION_SCRIPT_ID, generateLauncherScript(domain, roktExtensionsQueryParams), {\n onLoad: () => {\n if (this.isLauncherReadyToAttach()) {\n this.attachLauncher(accountId, launcherOptions, legacyRoktExtensions);\n } else {\n console.error('Rokt object is not available after script load.');\n }\n },\n onError: (error) => {\n console.error('Error loading Rokt launcher script:', error);\n },\n });\n\n this.captureTiming(RoktKit.PERFORMANCE_MARKS.RoktScriptAppended);\n }\n\n return 'Successfully initialized: ' + name;\n }\n\n public process(event: SDKEvent): string {\n if (!this.isTargetingDisabled()) {\n if (event.EventDataType === MESSAGE_TYPE_PAGE_VIEW) {\n captureUtmParams(this.loggingService);\n this.capturePageView(event);\n }\n\n if (event.EventDataType === MESSAGE_TYPE_SESSION_END) {\n clearPageViews();\n clearUtmParams();\n }\n }\n\n // The forwarding work below (LSA mapping) depends on the launcher, so guard\n // it here and surface the not-ready signal to the core SDK.\n if (!this.isKitReady()) {\n return 'Kit not ready for forwarder: ' + name;\n }\n\n if (isFunction(mp().Rokt?.setLocalSessionAttribute)) {\n if (!isEmpty(this.placementEventAttributeMappingLookup)) {\n this.applyPlacementEventAttributeMapping(event);\n }\n\n if (!isEmpty(this.placementEventMappingLookup)) {\n const hashedEvent = hashEventMessage(event.EventDataType, event.EventCategory, event.EventName ?? '');\n if (this.placementEventMappingLookup[String(hashedEvent)]) {\n mp().Rokt.setLocalSessionAttribute?.(this.placementEventMappingLookup[String(hashedEvent)], true);\n }\n }\n }\n\n return 'Successfully sent to forwarder: ' + name;\n }\n\n public setExtensionData(partnerExtensionData: Record): void {\n if (!this.isKitReady()) {\n console.error('Rokt Kit: Not initialized');\n return;\n }\n\n window.Rokt!.setExtensionData(partnerExtensionData);\n }\n\n public setUserAttribute(key: string, value: unknown): string {\n if (!isSelectPlacementsAttributePersistenceDenied(key)) {\n this.userAttributes[key] = value;\n }\n return 'Successfully set user attribute for forwarder: ' + name;\n }\n\n public removeUserAttribute(key: string): string {\n delete this.userAttributes[key];\n return 'Successfully removed user attribute for forwarder: ' + name;\n }\n\n private handleIdentityComplete(user: IMParticleUser, callbackName: string): string {\n this.userAttributes = removeSelectPlacementsAttributePersistenceDeniedAttributes(user.getAllUserAttributes());\n return 'Successfully called ' + callbackName + ' for forwarder: ' + name;\n }\n\n public onUserIdentified(user: IMParticleUser): string {\n const filteredUser = user as FilteredUser;\n this.filters.filteredUser = filteredUser;\n this._workspaceSearchInFlightPromise = this.search(filteredUser);\n return this.handleIdentityComplete(user, 'onUserIdentified');\n }\n\n private search(filteredUser: FilteredUser): Promise {\n const apiKey = this._workspaceIdSyncApiKey;\n if (!apiKey) {\n this.userIdentifiedInWorkspace = false;\n this._workspaceLastSearchedIdentitiesKey = undefined;\n return Promise.resolve();\n }\n const search = mp().Identity?.search;\n if (typeof search !== 'function') {\n this.userIdentifiedInWorkspace = false;\n this._workspaceLastSearchedIdentitiesKey = undefined;\n return Promise.resolve();\n }\n\n const userIdentities: IUserIdentities | null = filteredUser.getUserIdentities\n ? filteredUser.getUserIdentities().userIdentities\n : null;\n\n // Forward every non-empty string identifier the user has — email,\n // customerid, other/other2-10 (commonly used for hashed email),\n // mobile_number, facebook, etc. The host SDK's Identity.search accepts\n // the full IUserIdentities surface and the server validates it.\n const knownIdentities: Record = {};\n if (userIdentities) {\n for (const key of Object.keys(userIdentities) as Array) {\n const value = userIdentities[key];\n if (isString(value) && value.length > 0) {\n knownIdentities[key] = value;\n }\n }\n }\n\n const identityKeys = Object.keys(knownIdentities);\n if (identityKeys.length === 0) {\n this.userIdentifiedInWorkspace = false;\n this._workspaceLastSearchedIdentitiesKey = undefined;\n return Promise.resolve();\n }\n\n // Stable cache key: sort keys so insertion-order differences don't\n // cause false misses. The values are partner-supplied strings; no\n // hashing needed — equality on this serialization is sufficient.\n const identitiesKey = identityKeys\n .sort()\n .map((k) => `${k}=${knownIdentities[k]}`)\n .join('&');\n\n // Same identifier set as the last successful dispatch → skip the\n // network call. The current flag value still reflects the correct\n // match status.\n if (identitiesKey === this._workspaceLastSearchedIdentitiesKey) {\n return this._workspaceSearchInFlightPromise || Promise.resolve();\n }\n\n // New / different identifier set → reset and re-search. Cache the key\n // up front so a second concurrent invocation with the same set also\n // dedupes.\n this.userIdentifiedInWorkspace = false;\n this._workspaceLastSearchedIdentitiesKey = identitiesKey;\n\n return new Promise((resolve) => {\n try {\n search(apiKey, knownIdentities as IUserIdentities, (result: WorkspaceIdSyncResult) => {\n if (result?.httpCode === 200) {\n this.userIdentifiedInWorkspace = true;\n }\n resolve();\n });\n } catch (err) {\n console.error('Rokt Kit: Workspace IDSync search failed', err);\n // Dispatch failed — clear the cache so the same identifier set\n // can retry on the next identification rather than being stuck\n // behind a poisoned entry that short-circuits future searches.\n this._workspaceLastSearchedIdentitiesKey = undefined;\n resolve();\n }\n });\n }\n\n public onLoginComplete(user: IMParticleUser, _filteredIdentityRequest: unknown): string {\n return this.handleIdentityComplete(user, 'onLoginComplete');\n }\n\n public onLogoutComplete(user: IMParticleUser, _filteredIdentityRequest: unknown): string {\n // Anonymous sessions must not carry the previous user's match forward.\n // Clear the flag explicitly here. Also clear the identities cache so a\n // re-login (possibly with the same identifiers) dispatches a fresh\n // search rather than reusing a stale answer.\n this.userIdentifiedInWorkspace = false;\n this._workspaceSearchInFlightPromise = null;\n this._workspaceLastSearchedIdentitiesKey = undefined;\n return this.handleIdentityComplete(user, 'onLogoutComplete');\n }\n\n public onModifyComplete(user: IMParticleUser, _filteredIdentityRequest: unknown): string {\n return this.handleIdentityComplete(user, 'onModifyComplete');\n }\n\n /**\n * Selects placements for Rokt Web SDK with merged attributes, filters, and experimentation options.\n *\n * If a Workspace IDSync search is in flight from a recent onUserIdentified\n * call, this method waits up to `WORKSPACE_SEARCH_SELECT_TIMEOUT_MS` for it\n * to settle so the first placement call can include the\n * `userIdentifiedInWorkspace` flag without racing the network response.\n * The timeout protects against a stalled or slow search blocking placement\n * rendering — if it fires, selectPlacements proceeds without the flag.\n *\n * Implementation note: this method stays non-async deliberately. First,\n * the public return type is `RoktSelection | Promise |\n * undefined` — a superset of the `RoktSelection | Promise`\n * shape declared for `RoktLauncher.selectPlacements` above (line ~70).\n * Marking this `async` would narrow it to `Promise` and silently change the contract for callers that read\n * the result synchronously. Second, `RoktSelection` has an optional\n * `then?` member, so TS treats it as ambiguously promise-like and\n * rejects it as the awaited return of an async function (TS1058) —\n * working around that would require a cast or wrapping every return in\n * `Promise.resolve(...)`. The inner work runs in `_dispatchPlacements`;\n * this wrapper just gates it on the in-flight search via `Promise.race`,\n * and on a post-terminate createLauncher when the SPA needs a new instance.\n */\n public selectPlacements(options: Record): RoktSelection | Promise | undefined {\n const recreate = this.recreateLauncherIfTerminated();\n if (recreate) {\n const inFlight = this._workspaceSearchInFlightPromise;\n const waitForSearch = inFlight\n ? Promise.race([\n inFlight,\n new Promise((resolve) => setTimeout(resolve, WORKSPACE_SEARCH_SELECT_TIMEOUT_MS)),\n ])\n : Promise.resolve();\n return Promise.all([recreate, waitForSearch]).then(() =>\n this._dispatchPlacements(options),\n ) as Promise;\n }\n if (this._workspaceSearchInFlightPromise) {\n const inFlight = this._workspaceSearchInFlightPromise;\n return Promise.race([\n inFlight,\n new Promise((resolve) => setTimeout(resolve, WORKSPACE_SEARCH_SELECT_TIMEOUT_MS)),\n ]).then(() => this._dispatchPlacements(options)) as Promise;\n }\n return this._dispatchPlacements(options);\n }\n\n private _dispatchPlacements(options: Record): RoktSelection | Promise | undefined {\n const attributes = ((options && (options.attributes as Record)) || {}) as Record;\n const cachedUserAttributes = removeSelectPlacementsAttributePersistenceDeniedAttributes(this.userAttributes);\n const placementAttributes: Record = { ...cachedUserAttributes, ...attributes };\n\n const filters = this.filters || {};\n const userAttributeFilters = (filters.userAttributeFilters as string[]) || [];\n const filteredUser = filters.filteredUser || null;\n const mpid = filteredUser ? filteredUser.getMPID() : null;\n\n let filteredAttributes: Record;\n\n if (!filters) {\n console.warn('Rokt Kit: No filters available, using user attributes');\n filteredAttributes = placementAttributes;\n } else if (filters.filterUserAttributes) {\n filteredAttributes = filters.filterUserAttributes(placementAttributes, userAttributeFilters);\n } else {\n filteredAttributes = placementAttributes;\n }\n\n this.userAttributes = removeSelectPlacementsAttributePersistenceDeniedAttributes(filteredAttributes);\n\n const optimizelyAttributes = this._onboardingExpProvider === 'Optimizely' ? this.fetchOptimizely() : {};\n\n const filteredUserIdentities = this.returnUserIdentities(filteredUser);\n\n const sessionAttributes = this.returnLocalSessionAttributes();\n const pageEvents = buildPageEvents(loadPageViews());\n const utmParams = loadUtmParams();\n const mpSessionId = this.readMpSessionId();\n const mpDeviceId = this.readMpDeviceId();\n\n const selectPlacementsAttributes: Record = {\n ...(filteredUserIdentities as Record),\n ...filteredAttributes,\n ...optimizelyAttributes,\n ...sessionAttributes,\n ...(pageEvents.length ? { [PAGE_EVENTS_KEY]: JSON.stringify(pageEvents) } : {}),\n ...(utmParams ? { [PAGE_VIEW_ATTRIBUTES_KEY]: utmParams } : {}),\n ...(this.userIdentifiedInWorkspace ? { [USER_IDENTIFIED_IN_WORKSPACE_KEY]: true } : {}),\n ...(mpSessionId ? { [MPARTICLE_SESSION_ID_KEY]: mpSessionId } : {}),\n ...(mpDeviceId ? { [MPARTICLE_DEVICE_ID_KEY]: mpDeviceId } : {}),\n mpid,\n };\n\n const selectPlacementsOptions: Record = { ...options, attributes: selectPlacementsAttributes };\n\n const selection = this.launcher!.selectPlacements(selectPlacementsOptions);\n\n // After selection resolves, sync the Rokt session ID back to mParticle, then log\n const logSelection = () => this.logSelectPlacementsEvent(selectPlacementsAttributes);\n\n void Promise.resolve(selection)\n .then((sel) => sel?.context?.sessionId?.then((sessionId) => this.setRoktSessionId(sessionId)))\n .catch(() => undefined)\n .finally(logSelection);\n\n return selection;\n }\n\n /**\n * Passes attributes to the Rokt Web SDK for client-side hashing.\n */\n public hashAttributes(attributes: Record): Promise> | null {\n if (!this.isKitReady()) {\n console.error('Rokt Kit: Not initialized');\n return null;\n }\n return this.launcher!.hashAttributes(attributes);\n }\n\n /**\n * Enables optional Integration Launcher extensions before selecting placements.\n *\n * @deprecated This functionality has been internalized and will be removed in a future release.\n */\n public use(extensionName: string): Promise {\n if (!this.isKitReady()) {\n console.error('Rokt Kit: Not initialized');\n return Promise.reject(new Error('Rokt Kit: Not initialized'));\n }\n if (!extensionName || !isString(extensionName)) {\n return Promise.reject(new Error('Rokt Kit: Invalid extension name'));\n }\n return this.launcher!.use(extensionName);\n }\n\n /**\n * Tears down the Rokt launcher and the placements it rendered.\n *\n * The kit's launcher reference is left in place so isKitReady() stays true.\n * The Web SDK clears its memoized launcher on terminate, so a later\n * createLauncher (SPA navigation) produces a new instance. The next\n * selectPlacements call re-attaches that instance. Nulling the reference\n * here would flip the kit to not-ready with no drain path for queued calls.\n */\n public terminate(): Promise {\n if (!this.isKitReady()) {\n console.error('Rokt Kit: Not initialized');\n return Promise.resolve();\n }\n markLauncherTerminated(this._launcherAttachState);\n return this.launcher!.terminate();\n }\n\n /**\n * Registers a callback to be invoked once rokt-thank-you-element.js becomes available.\n */\n public onShoppableAdsReady(callback: () => void) {\n if (this._isThankYouElementLoaded) {\n callback();\n } else {\n this._thankYouElementOnLoadCallback = callback;\n }\n }\n}\n\n// ============================================================\n// Kit registration\n// ============================================================\n\nfunction getId(): number {\n return moduleId;\n}\n\nfunction register(config: { kits?: Record }): void {\n if (!config) {\n window.console.log('You must pass a config object to register the kit ' + name);\n return;\n }\n if (!isObject(config)) {\n window.console.log(\"'config' must be an object. You passed in a \" + typeof config);\n return;\n }\n\n if (isObject(config.kits)) {\n (config.kits as Record)[name] = {\n constructor: RoktKit,\n };\n } else {\n config.kits = {};\n config.kits[name] = {\n constructor: RoktKit,\n };\n }\n window.console.log('Successfully registered ' + name + ' to your mParticle configuration');\n}\n\nif (typeof window !== 'undefined' && window.mParticle && mp().addForwarder) {\n mp().addForwarder({\n name: name,\n constructor: RoktKit,\n getId: getId,\n });\n}\n\nexport { register };\nexport type { LoggingService };\n"],"names":["SELECT_PLACEMENTS_ATTRIBUTE_PERSISTENCE_DENY_LIST","SELECT_PLACEMENTS_ATTRIBUTE_PERSISTENCE_DENY_SET","isSelectPlacementsAttributePersistenceDenied","key","removeSelectPlacementsAttributePersistenceDeniedAttributes","attributes","filteredAttributes","sourceAttributes","attributeKeys","i","isObject","value","isString","isFunction","isEmpty","sanitizeUrl","href","url","LS_PROBE_KEY","isLocalStorageAvailable","readJSON","stored","writeJSON","removeKey","readNamespacedField","namespaceKey","field","blob","writeNamespacedField","next","removeNamespacedField","LS_NAMESPACE_KEY","LS_PAGE_VIEWS_FIELD","LS_UTM_PARAMS_FIELD","PAGE_VIEWS_MAX_COUNT","UTM_KEYS","capPageViews","views","loadPageViews","writePageViews","pageViews","toWrite","clearPageViews","buildPageEvents","pageView","index","activeTimeOnSite","hasActiveTime","nextActiveTimeOnSite","hasNextActiveTimeOnSite","diff","captureUtmParams","loggingService","search","params","captured","reason","loadUtmParams","clearUtmParams","readCanonicalUrl","createLauncherAttachState","rememberAttachContext","state","context","markLauncherAttached","markLauncherTerminated","markLauncherAttachFailed","resetLauncherAttachState","recreateIfTerminated","canAttach","attach","name","moduleId","EVENT_NAME_SELECT_PLACEMENTS","ADBLOCK_CONTROL_DOMAIN","INIT_LOG_SAMPLING_RATE","ROKT_THANK_YOU_JOURNEY_EXTENSION","ROKT_INTEGRATION_SCRIPT_ID","ROKT_THANK_YOU_ELEMENT_SCRIPT_ID","USER_IDENTIFIED_IN_WORKSPACE_KEY","MESSAGE_TYPE_PAGE_VIEW","MESSAGE_TYPE_SESSION_END","PAGE_EVENTS_KEY","PAGE_VIEW_ATTRIBUTES_KEY","MPARTICLE_SESSION_ID_KEY","MPARTICLE_DEVICE_ID_KEY","WORKSPACE_SEARCH_SELECT_TIMEOUT_MS","ErrorCodes","WSDKErrorSeverity","DEFAULT_ROKT_DOMAIN","LOGGING_ENDPOINT","ERROR_ENDPOINT","RATE_LIMIT_PER_SEVERITY","mp","generateLauncherScript","domain","extensions","baseUrl","generateBaseUrl","generateThankYouElementScript","resolvedDomain","generateReportingUrl","configuredUrl","endpoint","reportingDomain","loadRoktScript","scriptId","source","handlers","target","script","parseSettingsString","settingsString","extractRoktExtensionConfig","settings","roktExtensionsQueryParams","legacyRoktExtensions","loadThankYouElement","extensionName","registerLegacyExtensions","legacyExtensions","launcher","extension","generateMappedEventLookup","placementEventMapping","mappedEvents","mapping","generateMappedEventAttributeLookup","placementEventAttributeMapping","mappedAttributeKeys","mappedAttributeKey","eventAttributeKey","hashEventMessage","messageType","eventType","eventName","generateIntegrationName","customIntegrationName","integrationName","djb2","str","hash","createAutoRemovedIframe","src","iframe","sendAdBlockMeasurementSignals","version","originHash","RoktKit","guid","pageUrl","existingBaseUrl","_isDebugModeEnabled","_getReportingUrl","_getUserAgent","RateLimiter","severity","newCount","ReportingTransport","config","launcherInstanceGuid","accountId","rateLimiter","isLoggingEnabled","msg","code","stackTrace","onError","logRequest","headers","response","serverError","error","ErrorReportingService","LoggingService","errorReportingService","entry","isServerSide","buildPageEvent","event","pageTitle","canonicalUrl","_RoktKit","condition","actualValue","operator","expectedValue","rule","conditions","rulesForMappedAttributeKey","allMatch","j","requested","err","errMessage","filteredUser","userIdentities","newUserIdentities","EVENT_TYPE_OTHER","sessionId","mpInstance","sessionManager","readSessionId","launcherOptions","options","launcherPromise","roktFilters","forwarders","forwarder","optimizelyState","acc","expId","metricName","_service","testMode","_trackerId","filteredUserAttributes","kitSettings","reportingConfig","hashes","hashedEvent","partnerExtensionData","user","callbackName","apiKey","knownIdentities","identityKeys","identitiesKey","k","resolve","result","_filteredIdentityRequest","recreate","inFlight","waitForSearch","placementAttributes","filters","userAttributeFilters","mpid","optimizelyAttributes","filteredUserIdentities","sessionAttributes","pageEvents","utmParams","mpSessionId","mpDeviceId","selectPlacementsAttributes","selectPlacementsOptions","selection","logSelection","sel","callback","getId","register"],"mappings":"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"} \ No newline at end of file diff --git a/kits/rokt/dist/Rokt-Kit.d.ts b/kits/rokt/dist/Rokt-Kit.d.ts index 2fef482d9..38587898a 100644 --- a/kits/rokt/dist/Rokt-Kit.d.ts +++ b/kits/rokt/dist/Rokt-Kit.d.ts @@ -1,7 +1,41 @@ +declare interface ErrorReport { + message: string; + code?: string; + severity?: string; + stackTrace?: string; +} + +declare interface LogEntry { + message: string; + code?: string; +} + +export declare class LoggingService { + private _transport; + private _loggingUrl; + private _errorReportingService; + constructor(config: ReportingConfig, errorReportingService: { + report: (e: ErrorReport) => void; + }, integrationName: string | null | undefined, launcherInstanceGuid?: string, accountId?: string | null, rateLimiter?: RateLimiter); + log(entry: LogEntry | null | undefined): void; +} + +declare class RateLimiter { + private _logCount; + incrementAndCheck(severity: string): boolean; +} + export declare function register(config: { kits?: Record; }): void; +declare interface ReportingConfig { + loggingUrl?: string; + errorUrl?: string; + integrationDomain?: string; + isLoggingEnabled: boolean; +} + export { } diff --git a/kits/rokt/dist/Rokt-Kit.esm.js b/kits/rokt/dist/Rokt-Kit.esm.js index c040ba5fb..dcc1d0d50 100644 --- a/kits/rokt/dist/Rokt-Kit.esm.js +++ b/kits/rokt/dist/Rokt-Kit.esm.js @@ -1,4 +1,5 @@ -const B = [ +const me = [ + "active_time_on_site_ms", "billingaddress1", "billingaddress2", "billingcity", @@ -22,183 +23,350 @@ const B = [ "shippingstate", "shippingzipcode", "totalprice" -], J = new Set(B); -function G(n) { - return J.has(n.toLowerCase()); +], Ee = new Set(me); +function re(i) { + return Ee.has(i.toLowerCase()); } -function w(n) { - const t = {}, e = n || {}, i = Object.keys(e); - for (let r = 0; r < i.length; r++) { - const s = i[r]; - G(s) || (t[s] = e[s]); +function w(i) { + const e = {}, t = i || {}, n = Object.keys(t); + for (let r = 0; r < n.length; r++) { + const s = n[r]; + re(s) || (e[s] = t[s]); } - return t; + return e; } -const d = "Rokt", b = 181, Q = "selectPlacements", X = "apps.roktecommerce.com", $ = 0.1, Z = "ThankYouPageJourney", tt = "rokt-launcher", et = "rokt-thank-you-element", it = "userIdentifiedInWorkspace", nt = 500, O = { +function E(i) { + return typeof i == "object" && i !== null && !Array.isArray(i); +} +function m(i) { + return typeof i == "string"; +} +function b(i) { + return typeof i == "function"; +} +function U(i) { + return i == null ? !0 : typeof i == "object" ? Object.keys(i).length === 0 : !1; +} +function K(i) { + try { + const e = new URL(i); + return e.search = "", e.toString(); + } catch { + return i; + } +} +const W = "__rokt_ls_probe__"; +function C() { + try { + return window.localStorage.setItem(W, "1"), window.localStorage.removeItem(W), !0; + } catch { + return !1; + } +} +function F(i) { + try { + const e = window.localStorage.getItem(i); + return e === null ? null : JSON.parse(e); + } catch { + return null; + } +} +function se(i, e) { + try { + return window.localStorage.setItem(i, JSON.stringify(e)), !0; + } catch { + return !1; + } +} +function _e(i) { + try { + window.localStorage.removeItem(i); + } catch { + } +} +function D(i, e) { + const t = F(i); + return E(t) ? t[e] : void 0; +} +function oe(i, e, t) { + const n = F(i), r = E(n) ? { ...n } : {}; + return r[e] = t, se(i, r); +} +function ae(i, e) { + const t = F(i); + if (!E(t) || !(e in t)) + return; + const n = { ...t }; + delete n[e], Object.keys(n).length === 0 ? _e(i) : se(i, n); +} +const _ = "mp-rokt-kit", x = "pageViews", P = "utmParams", ce = 25, Ie = ["utm_source", "utm_medium", "utm_campaign", "utm_term", "utm_content"]; +function le(i) { + return i.slice(-ce); +} +function H() { + const i = D(_, x); + return Array.isArray(i) ? i : []; +} +function Se(i) { + const e = le(i); + for (let t = 0; t < e.length; t++) { + const n = e.slice(t); + if (oe(_, x, n)) + return n.length; + } + return 0; +} +function V() { + ae(_, x); +} +function ye(i) { + const e = le(i); + return e.map((t, n) => { + const r = t.activeTimeOnSite, s = r !== void 0 && Number.isFinite(r), c = e[n + 1]?.activeTimeOnSite, u = c !== void 0 && Number.isFinite(c), l = s && u ? c - r : void 0; + return { + pageUrl: t.pageUrl, + sourceMessageId: t.sourceMessageId, + timestamp: t.timestamp, + ...t.pageTitle !== void 0 ? { pageTitle: t.pageTitle } : {}, + ...t.canonicalUrl !== void 0 ? { canonicalUrl: t.canonicalUrl } : {}, + ...s ? { activeTimeOnSite: r } : {}, + ...l !== void 0 && l >= 0 ? { activeTimeOnPage: l } : {} + }; + }); +} +function Ae(i) { + if (D(_, P) !== void 0) + return; + const e = new URLSearchParams(window.location.search), t = {}; + for (const r of Ie) { + const s = e.get(r); + s && (t[r] = s); + } + if (Object.keys(t).length === 0) + return; + const n = Object.keys(t).join(", "); + if (!oe(_, P, t)) { + const r = C() ? "quota" : "ls_unavailable"; + i?.log({ + message: `Rokt Kit: Failed to persist UTM params [reason: ${r}]`, + code: "UTM_CAPTURE_FAILED" + }); + return; + } + i?.log({ + message: `Rokt Kit: Captured UTM params [${n}]`, + code: "UTM_CAPTURE_SUCCESS" + }); +} +function ke() { + const i = D(_, P); + return E(i) ? i : null; +} +function z() { + ae(_, P); +} +function Re() { + const e = document.querySelector('link[rel="canonical"]')?.href; + if (e) + return K(e); +} +function ve() { + return { + context: null, + lifecycle: "idle", + recreateInFlight: null + }; +} +function we(i, e) { + i.context = { + accountId: e.accountId, + launcherOptions: { ...e.launcherOptions }, + legacyRoktExtensions: [...e.legacyRoktExtensions] + }; +} +function be(i) { + i.lifecycle = "attached"; +} +function Te(i) { + i.lifecycle !== "idle" && (i.lifecycle = "terminated"); +} +function Le(i) { + i.lifecycle = "terminated"; +} +function Pe(i) { + i.context = null, i.lifecycle = "idle", i.recreateInFlight = null; +} +function Oe(i, e, t) { + if (i.recreateInFlight) + return i.recreateInFlight; + if (i.lifecycle !== "terminated" || !i.context || !e) + return; + i.lifecycle = "recreating"; + const n = i.context; + return i.recreateInFlight = t(n).finally(() => { + i.recreateInFlight = null; + }), i.recreateInFlight; +} +const d = "Rokt", T = 181, Ne = "selectPlacements", Ue = "apps.roktecommerce.com", Ce = 0.1, Me = "ThankYouPageJourney", Ke = "rokt-launcher", Fe = "rokt-thank-you-element", De = "userIdentifiedInWorkspace", xe = 3, Ye = 2, Ge = "page_events", je = "page_view_attributes", We = "mparticle_session_id", He = "mparticle_device_id", q = 500, Y = { UNKNOWN_ERROR: "UNKNOWN_ERROR", UNHANDLED_EXCEPTION: "UNHANDLED_EXCEPTION", IDENTITY_REQUEST: "IDENTITY_REQUEST", LOG_DELIVERY_FAILURE: "LOG_DELIVERY_FAILURE" -}, I = { +}, S = { ERROR: "ERROR", INFO: "INFO", WARNING: "WARNING" -}, rt = "apps.rokt-api.com", st = "/v1/log", ot = "/v1/errors", at = 10; +}, Ve = "apps.rokt-api.com", ze = "/v1/log", qe = "/v1/errors", $e = 10; function a() { return window.mParticle; } -function U(n, t) { - const i = [P(n), "/wsdk/integrations/launcher.js"].join(""); - return !t || t.length === 0 ? i : i + "?extensions=" + t.join(","); -} -function K(n) { - return [P(n), "/rokt-elements/rokt-element-thank-you.js"].join(""); +function $(i, e) { + const n = [O(i), "/wsdk/integrations/launcher.js"].join(""); + return !e || e.length === 0 ? n : n + "?extensions=" + e.join(","); } -function P(n) { - return ["https://", typeof n < "u" ? n : rt].join(""); +function J(i) { + return [O(i), "/rokt-elements/rokt-element-thank-you.js"].join(""); } -function z(n, t, e) { - return n ? n.startsWith("http://") || n.startsWith("https://") ? n : "https://" + n : P(t) + e; +function O(i) { + const e = typeof i < "u" ? i : Ve; + return e.includes("://") ? e.replace(/\/+$/, "") : ["https://", e].join(""); } -function M(n, t, e) { - if (document.getElementById(n)) return; - const i = document.head || document.body, r = document.createElement("script"); - r.id = n, r.type = "text/javascript", r.src = t, r.async = !0, r.crossOrigin = "anonymous", r.fetchPriority = "high", e?.onLoad && (r.onload = e.onLoad), e?.onError && (r.onerror = e.onError), i.appendChild(r); +function ue(i, e, t) { + if (i) + return i.startsWith("http://") || i.startsWith("https://") ? i : "https://" + i; + const r = e?.includes("://") && !/^https?:\/\//i.test(e) ? void 0 : e; + return O(r) + t; } -function T(n) { - return n != null && typeof n == "object" && Array.isArray(n) === !1; +function B(i, e, t) { + if (document.getElementById(i)) return; + const n = document.head || document.body, r = document.createElement("script"); + r.id = i, r.type = "text/javascript", r.src = e, r.async = !0, r.crossOrigin = "anonymous", r.fetchPriority = "high", t?.onLoad && (r.onload = t.onLoad), t?.onError && (r.onerror = t.onError), n.appendChild(r); } -function L(n) { - if (!n) +function L(i) { + if (!i) return []; try { - return JSON.parse(n.replace(/"/g, '"')); + return JSON.parse(i.replace(/"/g, '"')); } catch { console.error("Settings string contains invalid JSON"); } return []; } -function D(n) { - const t = n ? L(n) : [], e = [], i = []; +function Q(i) { + const e = i ? L(i) : [], t = [], n = []; let r = !1; - for (let s = 0; s < t.length; s++) { - const o = t[s].value; - o === "thank-you-journey" ? (r = !0, i.push(Z)) : e.push(o); + for (let s = 0; s < e.length; s++) { + const o = e[s].value; + o === "thank-you-journey" ? (r = !0, n.push(Me)) : t.push(o); } return { - roktExtensionsQueryParams: e, - legacyRoktExtensions: i, + roktExtensionsQueryParams: t, + legacyRoktExtensions: n, loadThankYouElement: r }; } -async function ct(n, t) { - const e = []; - if (t) - for (const i of n) - e.push(t.use(i)); - return Promise.all(e); +async function Je(i, e) { + const t = []; + if (e) + for (const n of i) + t.push(e.use(n)); + return Promise.all(t); } -function x(n) { - if (!n) +function X(i) { + if (!i) return {}; - const t = {}; - for (let e = 0; e < n.length; e++) { - const i = n[e]; - t[i.jsmap] = i.value; - } - return t; -} -function Y(n) { - const t = {}; - if (!Array.isArray(n)) - return t; - for (let e = 0; e < n.length; e++) { - const i = n[e]; - if (!i || !m(i.value) || !m(i.map)) + const e = {}; + for (let t = 0; t < i.length; t++) { + const n = i[t]; + e[n.jsmap] = n.value; + } + return e; +} +function Z(i) { + const e = {}; + if (!Array.isArray(i)) + return e; + for (let t = 0; t < i.length; t++) { + const n = i[t]; + if (!n || !m(n.value) || !m(n.map)) continue; - const r = i.value, s = i.map; - t[r] || (t[r] = []), t[r].push({ + const r = n.value, s = n.map; + e[r] || (e[r] = []), e[r].push({ eventAttributeKey: s, - conditions: Array.isArray(i.conditions) ? i.conditions : [] + conditions: Array.isArray(n.conditions) ? n.conditions : [] }); } - return t; -} -function F(n, t, e) { - return a().generateHash([n, t, e].join("")); + return e; } -function k(n) { - return n == null ? !0 : typeof n == "object" ? Object.keys(n).length === 0 : Array.isArray(n) ? n.length === 0 : !1; +function ee(i, e, t) { + return a().generateHash([i, e, t].join("")); } -function m(n) { - return typeof n == "string"; +function Be(i) { + let n = "mParticle_wsdkv_" + a().getVersion() + "_kitv_" + "1.36.1"; + return i && (n += "_" + i), n; } -function lt(n) { - let i = "mParticle_wsdkv_" + a().getVersion() + "_kitv_" + "1.28.3"; - return n && (i += "_" + n), i; +function de(i) { + let e = 5381; + for (let t = 0; t < i.length; t++) + e = (e << 5) + e + i.charCodeAt(t), e = e & e; + return e; } -function V(n) { - let t = 5381; - for (let e = 0; e < n.length; e++) - t = (t << 5) + t + n.charCodeAt(e), t = t & t; - return t; -} -function N(n) { - const t = document.createElement("iframe"); - t.style.display = "none", t.setAttribute("sandbox", "allow-scripts allow-same-origin"), t.src = n, t.onload = function() { - t.onload = null, t.parentNode && t.parentNode.removeChild(t); +function M(i) { + const e = document.createElement("iframe"); + e.style.display = "none", e.setAttribute("sandbox", "allow-scripts allow-same-origin"), e.src = i, e.onload = function() { + e.onload = null, e.parentNode && e.parentNode.removeChild(e); }; - const e = document.body || document.head; - e && e.appendChild(t); + const t = document.body || document.head; + t && t.appendChild(e); } -function j(n, t) { - const e = V(window.location.origin); - if (E._allowedOriginHashes.indexOf(e) === -1 || Math.random() >= $) +function te(i, e) { + const t = de(window.location.origin); + if (y._allowedOriginHashes.indexOf(t) === -1 || Math.random() >= Ce) return; const r = window.__rokt_li_guid__; - if (!r) + if (!r || i && i.includes("://") && !/^https:\/\//i.test(i)) return; - const s = window.location.href.split("?")[0].split("#")[0], o = "version=" + encodeURIComponent(t ?? "") + "&launcherInstanceGuid=" + encodeURIComponent(r) + "&pageUrl=" + encodeURIComponent(s); - N("https://" + (n || "apps.rokt.com") + "/v1/wsdk-init/index.html?" + o), N( - "https://" + X + "/v1/wsdk-init/index.html?" + o + "&isControl=true" + const s = window.location.href.split("?")[0].split("#")[0], o = "version=" + encodeURIComponent(e ?? "") + "&launcherInstanceGuid=" + encodeURIComponent(r) + "&pageUrl=" + encodeURIComponent(s), c = i ? O(i) : "https://apps.rokt.com"; + M(c + "/v1/wsdk-init/index.html?" + o), M( + "https://" + Ue + "/v1/wsdk-init/index.html?" + o + "&isControl=true" ); } -function ut() { +function Qe() { return typeof window < "u" && !!window.location?.search?.toLowerCase().includes("mp_enable_logging=true"); } -function dt() { +function Xe() { return typeof window < "u" ? window.location?.href : void 0; } -function ht() { +function Ze() { return typeof window < "u" ? window.navigator?.userAgent : void 0; } -class q { +class he { constructor() { this._logCount = {}; } - incrementAndCheck(t) { - const i = (this._logCount[t] || 0) + 1; - return this._logCount[t] = i, i > at; + incrementAndCheck(e) { + const n = (this._logCount[e] || 0) + 1; + return this._logCount[e] = n, n > $e; } } -class C { - constructor(t, e, i, r, s) { +class G { + constructor(e, t, n, r, s) { this._reporter = "mp-wsdk"; - const o = t.isLoggingEnabled; - this._integrationName = e || "", this._launcherInstanceGuid = i, this._accountId = r || null, this._rateLimiter = s || new q(), this._isEnabled = ut() || o; + const o = e.isLoggingEnabled; + this._integrationName = t || "", this._launcherInstanceGuid = n, this._accountId = r || null, this._rateLimiter = s || new he(), this._isEnabled = Qe() || o; } - send(t, e, i, r, s, o) { - if (!(!this._isEnabled || this._rateLimiter.incrementAndCheck(e))) + send(e, t, n, r, s, o) { + if (!(!this._isEnabled || this._rateLimiter.incrementAndCheck(t))) try { const c = { additionalInformation: { - message: i, + message: n, version: this._integrationName }, - severity: e, - code: r || O.UNKNOWN_ERROR, - url: dt(), - deviceInfo: ht(), + severity: t, + code: r || Y.UNKNOWN_ERROR, + url: Xe(), + deviceInfo: Ze(), stackTrace: s, reporter: this._reporter, integration: this._integrationName @@ -208,14 +376,14 @@ class C { "rokt-launcher-version": this._integrationName, "rokt-wsdk-version": "joint" }; - this._launcherInstanceGuid && (u["rokt-launcher-instance-guid"] = this._launcherInstanceGuid), this._accountId && (u["rokt-account-id"] = this._accountId), fetch(t, { + this._launcherInstanceGuid && (u["rokt-launcher-instance-guid"] = this._launcherInstanceGuid), this._accountId && (u["rokt-account-id"] = this._accountId), fetch(e, { method: "POST", headers: u, body: JSON.stringify(c) }).then((l) => { if (!l.ok) { - const h = new Error("HTTP " + l.status + " from log endpoint"); - throw h.statusCode = l.status, h; + const p = new Error("HTTP " + l.status + " from log endpoint"); + throw p.statusCode = l.status, p; } }).catch((l) => { console.error("ReportingTransport: Failed to send log", l), o && o(l); @@ -225,270 +393,342 @@ class C { } } } -class H { - constructor(t, e, i, r, s) { - this._transport = new C(t, e, i, r, s), this._errorUrl = z(t?.errorUrl, t?.integrationDomain, ot); +class ie { + constructor(e, t, n, r, s) { + this._transport = new G(e, t, n, r, s), this._errorUrl = ue(e?.errorUrl, e?.integrationDomain, qe); } - report(t) { - if (!t) return; - const e = t.severity || I.ERROR; - this._transport.send(this._errorUrl, e, t.message, t.code, t.stackTrace); + report(e) { + if (!e) return; + const t = e.severity || S.ERROR; + this._transport.send(this._errorUrl, t, e.message, e.code, e.stackTrace); } } -class W { - constructor(t, e, i, r, s, o) { - this._transport = new C(t, i, r, s, o), this._loggingUrl = z(t?.loggingUrl, t?.integrationDomain, st), this._errorReportingService = e; +class ne { + constructor(e, t, n, r, s, o) { + this._transport = new G(e, n, r, s, o), this._loggingUrl = ue(e?.loggingUrl, e?.integrationDomain, ze), this._errorReportingService = t; } - log(t) { - t && this._transport.send( + log(e) { + e && this._transport.send( this._loggingUrl, - I.INFO, - t.message, - t.code, + S.INFO, + e.message, + e.code, void 0, - (e) => { + (t) => { if (this._errorReportingService) { - const i = typeof e.statusCode == "number"; + const n = typeof t.statusCode == "number"; this._errorReportingService.report({ - message: "LoggingService: Failed to send log: " + e.message, - code: O.LOG_DELIVERY_FAILURE, - severity: i ? I.ERROR : I.WARNING + message: "LoggingService: Failed to send log: " + t.message, + code: Y.LOG_DELIVERY_FAILURE, + severity: n ? S.ERROR : S.WARNING }); } } ); } } -const p = class p { +function et(i) { + const e = K(window.location.href), t = i.EventAttributes?.title || document.title, n = Re(), r = i.ActiveTimeOnSite; + return { + pageUrl: e, + sourceMessageId: i.SourceMessageId, + timestamp: i.Timestamp, + ...t ? { pageTitle: t } : {}, + ...n !== void 0 ? { canonicalUrl: n } : {}, + ...Number.isFinite(r) ? { activeTimeOnSite: r } : {} + }; +} +const f = class f { constructor() { - this.name = d, this.id = b, this.moduleId = b, this.isInitialized = !1, this.launcher = null, this.filters = {}, this.userAttributes = {}, this.userIdentifiedInWorkspace = !1, this.testHelpers = null, this.placementEventMappingLookup = {}, this.placementEventAttributeMappingLookup = {}, this.integrationName = null, this.errorReportingService = null, this.loggingService = null, this._thankYouElementOnLoadCallback = null, this._isThankYouElementLoaded = !1, this._workspaceSearchInFlightPromise = null; + this.name = d, this.id = T, this.moduleId = T, this.isInitialized = !1, this.launcher = null, this.filters = {}, this.userAttributes = {}, this.userIdentifiedInWorkspace = !1, this.testHelpers = null, this.placementEventMappingLookup = {}, this.placementEventAttributeMappingLookup = {}, this.integrationName = null, this.errorReportingService = null, this.loggingService = null, this._thankYouElementOnLoadCallback = null, this._isThankYouElementLoaded = !1, this._workspaceSearchInFlightPromise = null, this._launcherAttachState = ve(); } // ---- Private helpers ---- - getEventAttributeValue(t, e) { - const i = t && t.EventAttributes; - return !i || typeof i[e] > "u" ? null : i[e]; + getEventAttributeValue(e, t) { + const n = e && e.EventAttributes; + return !n || typeof n[t] > "u" ? null : n[t]; } - doesEventAttributeConditionMatch(t, e) { - if (!t || !m(t.operator)) + doesEventAttributeConditionMatch(e, t) { + if (!e || !m(e.operator)) return !1; - const i = t.operator.toLowerCase(), r = t.attributeValue; - return i === "exists" ? e !== null : e == null ? !1 : i === "equals" ? String(e) === String(r) : i === "contains" ? String(e).indexOf(String(r)) !== -1 : !1; + const n = e.operator.toLowerCase(), r = e.attributeValue; + return n === "exists" ? t !== null : t == null ? !1 : n === "equals" ? String(t) === String(r) : n === "contains" ? String(t).indexOf(String(r)) !== -1 : !1; } - doesEventMatchRule(t, e) { - if (!e || !m(e.eventAttributeKey)) + doesEventMatchRule(e, t) { + if (!t || !m(t.eventAttributeKey)) return !1; - const i = e.conditions; - if (!Array.isArray(i)) + const n = t.conditions; + if (!Array.isArray(n)) return !1; - const r = this.getEventAttributeValue(t, e.eventAttributeKey); - if (i.length === 0) + const r = this.getEventAttributeValue(e, t.eventAttributeKey); + if (n.length === 0) return r !== null; - for (let s = 0; s < i.length; s++) - if (!this.doesEventAttributeConditionMatch(i[s], r)) + for (let s = 0; s < n.length; s++) + if (!this.doesEventAttributeConditionMatch(n[s], r)) return !1; return !0; } - applyPlacementEventAttributeMapping(t) { - const e = Object.keys(this.placementEventAttributeMappingLookup); - for (let i = 0; i < e.length; i++) { - const r = e[i], s = this.placementEventAttributeMappingLookup[r]; - if (k(s)) + applyPlacementEventAttributeMapping(e) { + const t = Object.keys(this.placementEventAttributeMappingLookup); + for (let n = 0; n < t.length; n++) { + const r = t[n], s = this.placementEventAttributeMappingLookup[r]; + if (U(s)) continue; let o = !0; for (let c = 0; c < s.length; c++) - if (!this.doesEventMatchRule(t, s[c])) { + if (!this.doesEventMatchRule(e, s[c])) { o = !1; break; } o && a().Rokt.setLocalSessionAttribute?.(r, !0); } } + capturePageView(e) { + let t; + try { + t = K(window.location.href); + const n = H(), r = et(e); + n.push(r); + const s = Math.min(n.length, ce), o = Se(n); + if (o === 0) { + const c = C() ? "quota" : "ls_unavailable"; + this.loggingService?.log({ + message: `Rokt Kit: Failed to persist page view for ${t} [reason: ${c}]`, + code: "PAGE_VIEW_CAPTURE_FAILED" + }); + } else o < s && this.loggingService?.log({ + message: `Rokt Kit: Page view storage reduced from ${s} to ${o} record(s) under quota pressure [reason: quota_eviction]`, + code: "PAGE_VIEW_QUOTA_EVICTION" + }); + } catch (n) { + const r = C() ? "exception" : "ls_unavailable", s = n instanceof Error ? n.message : String(n); + this.loggingService?.log({ + message: `Rokt Kit: Failed to capture page view for ${t}: ${s} [reason: ${r}]`, + code: "PAGE_VIEW_CAPTURE_FAILED" + }); + } + } isLauncherReadyToAttach() { - return !!window.Rokt && typeof window.Rokt.createLauncher == "function"; + return !!window.Rokt && b(window.Rokt.createLauncher); } /** * Returns the user identities from the filtered user, if any. */ - returnUserIdentities(t) { - if (!t || !t.getUserIdentities) + returnUserIdentities(e) { + if (!e || !e.getUserIdentities) return {}; - const e = t.getUserIdentities().userIdentities; - return this.replaceOtherIdentityWithEmailsha256(e); + const t = e.getUserIdentities().userIdentities; + return this.replaceOtherIdentityWithEmailsha256(t); } returnLocalSessionAttributes() { - return !a().Rokt || typeof a().Rokt.getLocalSessionAttributes != "function" ? {} : k(this.placementEventMappingLookup) && k(this.placementEventAttributeMappingLookup) ? {} : a().Rokt.getLocalSessionAttributes(); + return !a().Rokt || typeof a().Rokt.getLocalSessionAttributes != "function" ? {} : a().Rokt.getLocalSessionAttributes(); } - replaceOtherIdentityWithEmailsha256(t) { - const e = { ...t || {} }, i = this._mappedEmailSha256Key; - return i && t[i] && (e[p.EMAIL_SHA256_KEY] = t[i]), i && delete e[i], e; + replaceOtherIdentityWithEmailsha256(e) { + const t = { ...e || {} }, n = this._mappedEmailSha256Key; + return n && e[n] && (t[f.EMAIL_SHA256_KEY] = e[n]), n && delete t[n], t; } - logSelectPlacementsEvent(t) { - if (!window.mParticle || typeof a().logEvent != "function" || !T(t)) + logSelectPlacementsEvent(e) { + if (!window.mParticle || typeof a().logEvent != "function" || !E(e)) return; - const e = a().EventType.Other; - a().logEvent(Q, e, t); + const t = a().EventType.Other; + a().logEvent(Ne, t, e); } - setRoktSessionId(t) { - if (!(!t || typeof t != "string")) + setRoktSessionId(e) { + if (!(!e || typeof e != "string")) try { - const e = a().getInstance(); - e && typeof e.setIntegrationAttribute == "function" && e.setIntegrationAttribute(b, { - roktSessionId: t + const t = a().getInstance(); + t && b(t.setIntegrationAttribute) && t.setIntegrationAttribute(T, { + roktSessionId: e }); } catch { } } - attachLauncher(t, e, i = []) { - const r = a() && a().sessionManager && typeof a().sessionManager.getSession == "function" ? a().sessionManager.getSession() : void 0, s = { - accountId: t, - ...e || {}, - ...r ? { mpSessionId: r } : {} + readMpSessionId() { + const e = a()?.sessionManager, t = e?.getSessionId ?? e?.getSession; + if (b(t)) + return t.call(e) || void 0; + } + readMpDeviceId() { + return a()?.getDeviceId?.() || void 0; + } + attachLauncher(e, t, n = []) { + we(this._launcherAttachState, { + accountId: e, + launcherOptions: t || {}, + legacyRoktExtensions: n + }); + const r = { + accountId: e, + ...t || {} }; - let o; - this.isPartnerInLocalLauncherTestGroup() ? o = Promise.resolve(window.Rokt.createLocalLauncher(s)) : o = window.Rokt.createLauncher(s), o.then(async (c) => { - await ct(i, c), this.initRoktLauncher(c); - }).catch((c) => { - console.error("Error creating Rokt launcher:", c); + let s; + return this.isPartnerInLocalLauncherTestGroup() ? s = Promise.resolve(window.Rokt.createLocalLauncher(r)) : s = window.Rokt.createLauncher(r), s.then(async (o) => { + await Je([...n], o), this.initRoktLauncher(o); + }).catch((o) => { + Le(this._launcherAttachState), console.error("Error creating Rokt launcher:", o); }); } - initRoktLauncher(t) { - window.Rokt && (window.Rokt.currentLauncher = t), this.launcher = t; - const e = a().Rokt?.filters; - e ? (this.filters = e, e.filteredUser ? this._workspaceSearchInFlightPromise = this.search(e.filteredUser) : console.warn("Rokt Kit: No filtered user has been set.")) : console.warn("Rokt Kit: No filters have been set."), this.isInitialized = !0, j(this.domain, this.integrationName), a().Rokt.attachKit(this); + recreateLauncherIfTerminated() { + return Oe( + this._launcherAttachState, + this.isLauncherReadyToAttach(), + (e) => this.attachLauncher(e.accountId, e.launcherOptions, e.legacyRoktExtensions) + ); + } + initRoktLauncher(e) { + window.Rokt && (window.Rokt.currentLauncher = e), this.launcher = e, be(this._launcherAttachState); + const t = a().Rokt?.filters; + t ? (this.filters = t, t.filteredUser ? this._workspaceSearchInFlightPromise = this.search(t.filteredUser) : console.warn("Rokt Kit: No filtered user has been set.")) : console.warn("Rokt Kit: No filters have been set."), this.isInitialized = !0, te(this.domain, this.integrationName), a().Rokt.attachKit(this); } fetchOptimizely() { - const t = a()._getActiveForwarders().filter((e) => e.name === "Optimizely"); + const e = a()._getActiveForwarders().filter((t) => t.name === "Optimizely"); try { - if (t.length > 0 && window.optimizely) { - const e = window.optimizely.get("state"); - return !e || !e.getActiveExperimentIds ? {} : e.getActiveExperimentIds().reduce((s, o) => (s["rokt.custom.optimizely.experiment." + o + ".variationId"] = e.getVariationMap()[o].id, s), {}); + if (e.length > 0 && window.optimizely) { + const t = window.optimizely.get("state"); + return !t || !t.getActiveExperimentIds ? {} : t.getActiveExperimentIds().reduce((s, o) => (s["rokt.custom.optimizely.experiment." + o + ".variationId"] = t.getVariationMap()[o].id, s), {}); } - } catch (e) { - console.error("Error fetching Optimizely attributes:", e); + } catch (t) { + console.error("Error fetching Optimizely attributes:", t); } return {}; } isKitReady() { return !!(this.isInitialized && this.launcher); } + // When the partner has opted out of targeting (noTargeting launcher option), + // the kit must not collect behavioral targeting signals such as page views. + isTargetingDisabled() { + return a().Rokt?.launcherOptions?.noTargeting === !0; + } isPartnerInLocalLauncherTestGroup() { return !!(a().config && a().config.isLocalLauncherEnabled && this.isAssignedToSampleGroup()); } isAssignedToSampleGroup() { return Math.random() > 0.5; } - captureTiming(t) { - window && a() && a().captureTiming && t && a().captureTiming(t); + captureTiming(e) { + window && a() && a().captureTiming && e && a().captureTiming(e); } // ---- Public methods (mParticle Kit Callbacks) ---- /** * Initializes the Rokt forwarder with settings from the mParticle server. */ - init(t, e, i, r, s) { - const o = t, c = o.accountId; + init(e, t, n, r, s) { + const o = e, c = o.accountId; this.userAttributes = w(s), this._onboardingExpProvider = o.onboardingExpProvider; const u = L(o.placementEventMapping); - this.placementEventMappingLookup = x(u); + this.placementEventMappingLookup = X(u); const l = L( o.placementEventAttributeMapping ); - this.placementEventAttributeMappingLookup = Y(l), o.hashedEmailUserIdentityType && (this._mappedEmailSha256Key = o.hashedEmailUserIdentityType.toLowerCase()), this._workspaceIdSyncApiKey = m(o.workspaceIdSyncApiKey) ? o.workspaceIdSyncApiKey : void 0; - const h = a().Rokt?.domain, { roktExtensionsQueryParams: v, legacyRoktExtensions: R, loadThankYouElement: A } = D( + this.placementEventAttributeMappingLookup = Z(l), o.hashedEmailUserIdentityType && (this._mappedEmailSha256Key = o.hashedEmailUserIdentityType.toLowerCase()), this._workspaceIdSyncApiKey = m(o.workspaceIdSyncApiKey) ? o.workspaceIdSyncApiKey : void 0; + const p = a().Rokt?.domain, { roktExtensionsQueryParams: N, legacyRoktExtensions: R, loadThankYouElement: v } = Q( o.roktExtensions ), g = { ...a().Rokt?.launcherOptions || {} }; - this.integrationName = lt(g.integrationName), g.integrationName = this.integrationName, this.domain = h; - const _ = { + this.integrationName = Be(g.integrationName), g.integrationName = this.integrationName, this.domain = p; + const A = { loggingUrl: o.loggingUrl, errorUrl: o.errorUrl, - integrationDomain: h, + integrationDomain: p, isLoggingEnabled: a().config?.isLoggingEnabled === !0 - }, y = new H( - _, + }, I = new ie( + A, this.integrationName, window.__rokt_li_guid__, o.accountId - ), S = new W( - _, - y, + ), k = new ne( + A, + I, this.integrationName, window.__rokt_li_guid__, o.accountId ); - return this.errorReportingService = y, this.loggingService = S, a()._registerErrorReportingService && a()._registerErrorReportingService(y), a()._registerLoggingService && a()._registerLoggingService(S), i ? (this.testHelpers = { - generateLauncherScript: U, - generateThankYouElementScript: K, - extractRoktExtensionConfig: D, - hashEventMessage: F, + if (this.errorReportingService = I, this.loggingService = k, this.isTargetingDisabled()) + try { + V(), z(); + } catch (h) { + this.errorReportingService?.report({ + message: "Rokt Kit: Failed to clear page views when targeting is disabled", + code: "PAGE_VIEW_CAPTURE_FAILED", + severity: S.INFO, + stackTrace: h instanceof Error ? h.stack : void 0 + }); + } + return a()._registerErrorReportingService && a()._registerErrorReportingService(I), a()._registerLoggingService && a()._registerLoggingService(k), n ? (this.testHelpers = { + generateLauncherScript: $, + generateThankYouElementScript: J, + extractRoktExtensionConfig: Q, + hashEventMessage: ee, parseSettingsString: L, - generateMappedEventLookup: x, - generateMappedEventAttributeLookup: Y, - sendAdBlockMeasurementSignals: j, - createAutoRemovedIframe: N, - djb2: V, - setAllowedOriginHashes: (f) => { - p._allowedOriginHashes = f; + generateMappedEventLookup: X, + generateMappedEventAttributeLookup: Z, + sendAdBlockMeasurementSignals: te, + createAutoRemovedIframe: M, + djb2: de, + setAllowedOriginHashes: (h) => { + f._allowedOriginHashes = h; }, - ReportingTransport: C, - ErrorReportingService: H, - LoggingService: W, - RateLimiter: q, - ErrorCodes: O, - WSDKErrorSeverity: I - }, this.attachLauncher(c, g), "Successfully initialized: " + d) : (A && (a().Rokt.flushOnShoppableAdsReadyMessageQueue?.(this), M(et, K(h), { + ReportingTransport: G, + ErrorReportingService: ie, + LoggingService: ne, + RateLimiter: he, + ErrorCodes: Y, + WSDKErrorSeverity: S, + resetLauncherAttachState: () => Pe(this._launcherAttachState) + }, this.attachLauncher(c, g), "Successfully initialized: " + d) : (v && (a().Rokt.flushOnShoppableAdsReadyMessageQueue?.(this), B(Fe, J(p), { onLoad: () => { this._isThankYouElementLoaded = !0, this._thankYouElementOnLoadCallback && this._thankYouElementOnLoadCallback(); }, - onError: (f) => { - console.error("Error loading Rokt Thank You Element script:", f); + onError: (h) => { + console.error("Error loading Rokt Thank You Element script:", h); } - })), this.isLauncherReadyToAttach() ? this.attachLauncher(c, g, R) : (M(tt, U(h, v), { + })), this.isLauncherReadyToAttach() ? this.attachLauncher(c, g, R) : (B(Ke, $(p, N), { onLoad: () => { this.isLauncherReadyToAttach() ? this.attachLauncher(c, g, R) : console.error("Rokt object is not available after script load."); }, - onError: (f) => { - console.error("Error loading Rokt launcher script:", f); + onError: (h) => { + console.error("Error loading Rokt launcher script:", h); } - }), this.captureTiming(p.PERFORMANCE_MARKS.RoktScriptAppended)), "Successfully initialized: " + d); + }), this.captureTiming(f.PERFORMANCE_MARKS.RoktScriptAppended)), "Successfully initialized: " + d); } - process(t) { - if (!this.isKitReady()) + process(e) { + if (this.isTargetingDisabled() || (e.EventDataType === xe && (Ae(this.loggingService), this.capturePageView(e)), e.EventDataType === Ye && (V(), z())), !this.isKitReady()) return "Kit not ready for forwarder: " + d; - if (typeof a().Rokt?.setLocalSessionAttribute == "function" && (k(this.placementEventAttributeMappingLookup) || this.applyPlacementEventAttributeMapping(t), !k(this.placementEventMappingLookup))) { - const e = F(t.EventDataType, t.EventCategory, t.EventName ?? ""); - this.placementEventMappingLookup[String(e)] && a().Rokt.setLocalSessionAttribute?.(this.placementEventMappingLookup[String(e)], !0); + if (b(a().Rokt?.setLocalSessionAttribute) && (U(this.placementEventAttributeMappingLookup) || this.applyPlacementEventAttributeMapping(e), !U(this.placementEventMappingLookup))) { + const t = ee(e.EventDataType, e.EventCategory, e.EventName ?? ""); + this.placementEventMappingLookup[String(t)] && a().Rokt.setLocalSessionAttribute?.(this.placementEventMappingLookup[String(t)], !0); } return "Successfully sent to forwarder: " + d; } - setExtensionData(t) { + setExtensionData(e) { if (!this.isKitReady()) { console.error("Rokt Kit: Not initialized"); return; } - window.Rokt.setExtensionData(t); + window.Rokt.setExtensionData(e); } - setUserAttribute(t, e) { - return G(t) || (this.userAttributes[t] = e), "Successfully set user attribute for forwarder: " + d; + setUserAttribute(e, t) { + return re(e) || (this.userAttributes[e] = t), "Successfully set user attribute for forwarder: " + d; } - removeUserAttribute(t) { - return delete this.userAttributes[t], "Successfully removed user attribute for forwarder: " + d; + removeUserAttribute(e) { + return delete this.userAttributes[e], "Successfully removed user attribute for forwarder: " + d; } - handleIdentityComplete(t, e) { - return this.userAttributes = w(t.getAllUserAttributes()), "Successfully called " + e + " for forwarder: " + d; + handleIdentityComplete(e, t) { + return this.userAttributes = w(e.getAllUserAttributes()), "Successfully called " + t + " for forwarder: " + d; } - onUserIdentified(t) { - const e = t; - return this.filters.filteredUser = e, this._workspaceSearchInFlightPromise = this.search(e), this.handleIdentityComplete(t, "onUserIdentified"); + onUserIdentified(e) { + const t = e; + return this.filters.filteredUser = t, this._workspaceSearchInFlightPromise = this.search(t), this.handleIdentityComplete(e, "onUserIdentified"); } - search(t) { - const e = this._workspaceIdSyncApiKey; - if (!e) + search(e) { + const t = this._workspaceIdSyncApiKey; + if (!t) return this.userIdentifiedInWorkspace = !1, this._workspaceLastSearchedIdentitiesKey = void 0, Promise.resolve(); - const i = a().Identity?.search; - if (typeof i != "function") + const n = a().Identity?.search; + if (typeof n != "function") return this.userIdentifiedInWorkspace = !1, this._workspaceLastSearchedIdentitiesKey = void 0, Promise.resolve(); - const r = t.getUserIdentities ? t.getUserIdentities().userIdentities : null, s = {}; + const r = e.getUserIdentities ? e.getUserIdentities().userIdentities : null, s = {}; if (r) for (const u of Object.keys(r)) { const l = r[u]; @@ -500,7 +740,7 @@ const p = class p { const c = o.sort().map((u) => `${u}=${s[u]}`).join("&"); return c === this._workspaceLastSearchedIdentitiesKey ? this._workspaceSearchInFlightPromise || Promise.resolve() : (this.userIdentifiedInWorkspace = !1, this._workspaceLastSearchedIdentitiesKey = c, new Promise((u) => { try { - i(e, s, (l) => { + n(t, s, (l) => { l?.httpCode === 200 && (this.userIdentifiedInWorkspace = !0), u(); }); } catch (l) { @@ -508,14 +748,14 @@ const p = class p { } })); } - onLoginComplete(t, e) { - return this.handleIdentityComplete(t, "onLoginComplete"); + onLoginComplete(e, t) { + return this.handleIdentityComplete(e, "onLoginComplete"); } - onLogoutComplete(t, e) { - return this.userIdentifiedInWorkspace = !1, this._workspaceSearchInFlightPromise = null, this._workspaceLastSearchedIdentitiesKey = void 0, this.handleIdentityComplete(t, "onLogoutComplete"); + onLogoutComplete(e, t) { + return this.userIdentifiedInWorkspace = !1, this._workspaceSearchInFlightPromise = null, this._workspaceLastSearchedIdentitiesKey = void 0, this.handleIdentityComplete(e, "onLogoutComplete"); } - onModifyComplete(t, e) { - return this.handleIdentityComplete(t, "onModifyComplete"); + onModifyComplete(e, t) { + return this.handleIdentityComplete(e, "onModifyComplete"); } /** * Selects placements for Rokt Web SDK with merged attributes, filters, and experimentation options. @@ -538,82 +778,109 @@ const p = class p { * rejects it as the awaited return of an async function (TS1058) — * working around that would require a cast or wrapping every return in * `Promise.resolve(...)`. The inner work runs in `_dispatchPlacements`; - * this wrapper just gates it on the in-flight search via `Promise.race`. + * this wrapper just gates it on the in-flight search via `Promise.race`, + * and on a post-terminate createLauncher when the SPA needs a new instance. */ - selectPlacements(t) { + selectPlacements(e) { + const t = this.recreateLauncherIfTerminated(); + if (t) { + const n = this._workspaceSearchInFlightPromise, r = n ? Promise.race([ + n, + new Promise((s) => setTimeout(s, q)) + ]) : Promise.resolve(); + return Promise.all([t, r]).then( + () => this._dispatchPlacements(e) + ); + } if (this._workspaceSearchInFlightPromise) { - const e = this._workspaceSearchInFlightPromise; + const n = this._workspaceSearchInFlightPromise; return Promise.race([ - e, - new Promise((i) => setTimeout(i, nt)) - ]).then(() => this._dispatchPlacements(t)); + n, + new Promise((r) => setTimeout(r, q)) + ]).then(() => this._dispatchPlacements(e)); } - return this._dispatchPlacements(t); + return this._dispatchPlacements(e); } - _dispatchPlacements(t) { - const e = t && t.attributes || {}, r = { ...w(this.userAttributes), ...e }, s = this.filters || {}, o = s.userAttributeFilters || [], c = s.filteredUser || null, u = c ? c.getMPID() : null; + _dispatchPlacements(e) { + const t = e && e.attributes || {}, r = { ...w(this.userAttributes), ...t }, s = this.filters || {}, o = s.userAttributeFilters || [], c = s.filteredUser || null, u = c ? c.getMPID() : null; let l; s ? s.filterUserAttributes ? l = s.filterUserAttributes(r, o) : l = r : (console.warn("Rokt Kit: No filters available, using user attributes"), l = r), this.userAttributes = w(l); - const h = this._onboardingExpProvider === "Optimizely" ? this.fetchOptimizely() : {}, v = this.returnUserIdentities(c), R = this.returnLocalSessionAttributes(), A = { - ...v, + const p = this._onboardingExpProvider === "Optimizely" ? this.fetchOptimizely() : {}, N = this.returnUserIdentities(c), R = this.returnLocalSessionAttributes(), v = ye(H()), g = ke(), A = this.readMpSessionId(), I = this.readMpDeviceId(), k = { + ...N, ...l, - ...h, + ...p, ...R, - ...this.userIdentifiedInWorkspace ? { [it]: !0 } : {}, + ...v.length ? { [Ge]: JSON.stringify(v) } : {}, + ...g ? { [je]: g } : {}, + ...this.userIdentifiedInWorkspace ? { [De]: !0 } : {}, + ...A ? { [We]: A } : {}, + ...I ? { [He]: I } : {}, mpid: u - }, g = { ...t, attributes: A }, _ = this.launcher.selectPlacements(g), y = () => this.logSelectPlacementsEvent(A); - return Promise.resolve(_).then((S) => S?.context?.sessionId?.then((f) => this.setRoktSessionId(f))).catch(() => { - }).finally(y), _; + }, h = { ...e, attributes: k }, j = this.launcher.selectPlacements(h), pe = () => this.logSelectPlacementsEvent(k); + return Promise.resolve(j).then((ge) => ge?.context?.sessionId?.then((fe) => this.setRoktSessionId(fe))).catch(() => { + }).finally(pe), j; } /** * Passes attributes to the Rokt Web SDK for client-side hashing. */ - hashAttributes(t) { - return this.isKitReady() ? this.launcher.hashAttributes(t) : (console.error("Rokt Kit: Not initialized"), null); + hashAttributes(e) { + return this.isKitReady() ? this.launcher.hashAttributes(e) : (console.error("Rokt Kit: Not initialized"), null); } /** * Enables optional Integration Launcher extensions before selecting placements. * * @deprecated This functionality has been internalized and will be removed in a future release. */ - use(t) { - return this.isKitReady() ? !t || !m(t) ? Promise.reject(new Error("Rokt Kit: Invalid extension name")) : this.launcher.use(t) : (console.error("Rokt Kit: Not initialized"), Promise.reject(new Error("Rokt Kit: Not initialized"))); + use(e) { + return this.isKitReady() ? !e || !m(e) ? Promise.reject(new Error("Rokt Kit: Invalid extension name")) : this.launcher.use(e) : (console.error("Rokt Kit: Not initialized"), Promise.reject(new Error("Rokt Kit: Not initialized"))); + } + /** + * Tears down the Rokt launcher and the placements it rendered. + * + * The kit's launcher reference is left in place so isKitReady() stays true. + * The Web SDK clears its memoized launcher on terminate, so a later + * createLauncher (SPA navigation) produces a new instance. The next + * selectPlacements call re-attaches that instance. Nulling the reference + * here would flip the kit to not-ready with no drain path for queued calls. + */ + terminate() { + return this.isKitReady() ? (Te(this._launcherAttachState), this.launcher.terminate()) : (console.error("Rokt Kit: Not initialized"), Promise.resolve()); } /** * Registers a callback to be invoked once rokt-thank-you-element.js becomes available. */ - onShoppableAdsReady(t) { - this._isThankYouElementLoaded ? t() : this._thankYouElementOnLoadCallback = t; + onShoppableAdsReady(e) { + this._isThankYouElementLoaded ? e() : this._thankYouElementOnLoadCallback = e; } }; -p._allowedOriginHashes = [-553112570, 549508659], p.PERFORMANCE_MARKS = { +f._allowedOriginHashes = [-553112570, 549508659], f.PERFORMANCE_MARKS = { RoktScriptAppended: "mp:RoktScriptAppended" -}, p.EMAIL_SHA256_KEY = "emailsha256"; -let E = p; -function pt() { - return b; +}, f.EMAIL_SHA256_KEY = "emailsha256"; +let y = f; +function tt() { + return T; } -function gt(n) { - if (!n) { +function it(i) { + if (!i) { window.console.log("You must pass a config object to register the kit " + d); return; } - if (!T(n)) { - window.console.log("'config' must be an object. You passed in a " + typeof n); + if (!E(i)) { + window.console.log("'config' must be an object. You passed in a " + typeof i); return; } - T(n.kits) ? n.kits[d] = { - constructor: E - } : (n.kits = {}, n.kits[d] = { - constructor: E + E(i.kits) ? i.kits[d] = { + constructor: y + } : (i.kits = {}, i.kits[d] = { + constructor: y }), window.console.log("Successfully registered " + d + " to your mParticle configuration"); } typeof window < "u" && window.mParticle && a().addForwarder && a().addForwarder({ name: d, - constructor: E, - getId: pt + constructor: y, + getId: tt }); export { - gt as register + it as register }; //# sourceMappingURL=Rokt-Kit.esm.js.map diff --git a/kits/rokt/dist/Rokt-Kit.esm.js.map b/kits/rokt/dist/Rokt-Kit.esm.js.map index e5995c8b1..64a75948d 100644 --- a/kits/rokt/dist/Rokt-Kit.esm.js.map +++ b/kits/rokt/dist/Rokt-Kit.esm.js.map @@ -1 +1 @@ -{"version":3,"file":"Rokt-Kit.esm.js","sources":["../src/selectPlacementsAttributePersistence.ts","../src/Rokt-Kit.ts"],"sourcesContent":["const SELECT_PLACEMENTS_ATTRIBUTE_PERSISTENCE_DENY_LIST = [\n 'billingaddress1',\n 'billingaddress2',\n 'billingcity',\n 'billingstate',\n 'billingzipcode',\n 'cartitems',\n 'ccbin',\n 'confirmationref',\n 'conversiontype',\n 'country',\n 'couponcode',\n 'currency',\n 'language',\n 'paymentserviceprovider',\n 'paymentserviceproviderattribute',\n 'paymenttype',\n 'shippingaddress1',\n 'shippingcity',\n 'shippingcountry',\n 'shippingmethod',\n 'shippingstate',\n 'shippingzipcode',\n 'totalprice',\n];\nconst SELECT_PLACEMENTS_ATTRIBUTE_PERSISTENCE_DENY_SET = new Set(SELECT_PLACEMENTS_ATTRIBUTE_PERSISTENCE_DENY_LIST);\n\nexport function isSelectPlacementsAttributePersistenceDenied(key: string): boolean {\n return SELECT_PLACEMENTS_ATTRIBUTE_PERSISTENCE_DENY_SET.has(key.toLowerCase());\n}\n\nexport function removeSelectPlacementsAttributePersistenceDeniedAttributes(\n attributes: Record | null | undefined,\n): Record {\n const filteredAttributes: Record = {};\n const sourceAttributes = attributes || {};\n const attributeKeys = Object.keys(sourceAttributes);\n\n for (let i = 0; i < attributeKeys.length; i++) {\n const key = attributeKeys[i];\n if (!isSelectPlacementsAttributePersistenceDenied(key)) {\n filteredAttributes[key] = sourceAttributes[key];\n }\n }\n\n return filteredAttributes;\n}\n","// Copyright 2025 mParticle, Inc.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n// ============================================================\n// Types\n// ============================================================\n\nimport { KitInterface, IMParticleUser, SDKEvent } from '@mparticle/web-sdk/internal';\nimport type { IUserIdentities } from '@mparticle/web-sdk';\n\nimport {\n isSelectPlacementsAttributePersistenceDenied,\n removeSelectPlacementsAttributePersistenceDeniedAttributes,\n} from './selectPlacementsAttributePersistence';\n\ninterface RoktKitSettings {\n accountId: string;\n roktExtensions?: string;\n placementEventMapping?: string;\n placementEventAttributeMapping?: string;\n hashedEmailUserIdentityType?: string;\n onboardingExpProvider?: string;\n loggingUrl?: string;\n errorUrl?: string;\n workspaceIdSyncApiKey?: string;\n}\n\ninterface EventAttributeCondition {\n operator: string;\n attributeValue: string;\n}\n\ninterface PlacementEventRule {\n eventAttributeKey: string;\n conditions: EventAttributeCondition[];\n}\n\ninterface EventAttributeMapping {\n value: string;\n map: string;\n conditions?: EventAttributeCondition[];\n}\n\ninterface PlacementEventMappingEntry {\n jsmap: string;\n value: string;\n}\n\ninterface RoktExtensionEntry {\n value: string;\n}\n\ninterface RoktSelection {\n context?: {\n sessionId?: Promise;\n };\n then?: (callback: (sel: RoktSelection) => void) => Promise;\n catch?: (callback: () => void) => void;\n}\n\ninterface RoktLauncher {\n selectPlacements(options: Record): RoktSelection | Promise;\n hashAttributes(attributes: Record): Promise>;\n use(extensionName: string): Promise;\n}\n\ninterface RoktGlobal {\n createLauncher(options: Record): Promise;\n createLocalLauncher(options: Record): RoktLauncher;\n currentLauncher?: RoktLauncher;\n setExtensionData(data: Record): void;\n}\n\n// FilteredUser is the IMParticleUser shape we receive after kit filtering.\n// `getMPID` and `getUserIdentities` are inherited from the SDK's `User` base type.\ntype FilteredUser = IMParticleUser;\n\n// TODO: Replace with `IIdentitySearchResult` from `@mparticle/web-sdk` once\n// a version that exports it is published (currently on a feature branch in\n// mParticle/mparticle-web-sdk PR #1255). The shape below is intentionally\n// structurally identical so the swap is a one-line import change.\ninterface WorkspaceIdSyncResult {\n httpCode: number;\n body?: {\n context?: string | null;\n mpid?: string;\n matched_identities?: Record;\n is_ephemeral?: boolean;\n is_logged_in?: boolean;\n };\n}\n\n// TODO: Replace with `IdentitySearchCallback`-compatible reference from\n// `@mparticle/web-sdk` once published (mirrors `SDKIdentityApi.search`).\ntype WorkspaceIdSyncSearcher = (\n apiKey: string,\n knownIdentities: IUserIdentities,\n callback: (result: WorkspaceIdSyncResult) => void,\n) => void;\n\ninterface KitFilters {\n userAttributeFilters?: string[];\n filterUserAttributes?: (attributes: Record, filters?: string[]) => Record;\n filteredUser?: FilteredUser | null;\n}\n\ninterface RoktManager {\n attachKit(kit: RoktKit): void | Promise;\n flushOnShoppableAdsReadyMessageQueue?(kit: RoktKit): void;\n filters?: KitFilters;\n domain?: string;\n launcherOptions?: Record;\n getLocalSessionAttributes?(): Record;\n setLocalSessionAttribute?(key: string, value: unknown): void;\n}\n\ninterface MParticleInstance {\n setIntegrationAttribute(moduleId: number, attrs: Record): void;\n}\n\ninterface OptimizelyState {\n getActiveExperimentIds(): string[];\n getVariationMap(): Record;\n}\n\ninterface OptimizelyGlobal {\n get(key: 'state'): OptimizelyState;\n}\n\n// Our view of the mParticle global with Rokt-specific extensions.\n// We access window.mParticle via an explicit cast (see `mp()` helper below)\n// rather than augmenting Window to avoid conflicts with @mparticle/web-sdk declarations.\ninterface MParticleExtended {\n Rokt: RoktManager;\n addForwarder(config: ForwarderRegistration): void;\n getVersion(): string;\n generateHash(value: string): string | number;\n logEvent(name: string, type: number, attrs?: Record): void;\n EventType: { Other: number };\n getInstance(): MParticleInstance;\n sessionManager?: { getSession(): string };\n _getActiveForwarders(): Array<{ name: string }>;\n config?: { isLocalLauncherEnabled?: boolean; isLoggingEnabled?: boolean };\n captureTiming?(metricName: string): void;\n forwarder?: RoktKit;\n loggedEvents?: Array>;\n _registerErrorReportingService?(service: ErrorReportingService): void;\n _registerLoggingService?(service: LoggingService): void;\n Identity?: { search?: WorkspaceIdSyncSearcher };\n}\n\ninterface TestHelpers {\n generateLauncherScript: (domain: string | undefined, extensions: string[]) => string;\n generateThankYouElementScript: (domain: string | undefined) => string;\n extractRoktExtensionConfig: (settingsString?: string) => RoktExtensionConfig;\n hashEventMessage: (messageType: number, eventType: number, eventName: string) => string | number;\n parseSettingsString: (settingsString?: string) => T[];\n generateMappedEventLookup: (placementEventMapping: PlacementEventMappingEntry[]) => Record;\n generateMappedEventAttributeLookup: (mapping: EventAttributeMapping[]) => Record;\n sendAdBlockMeasurementSignals: (domain: string | undefined, version: string | null) => void;\n createAutoRemovedIframe: (src: string) => void;\n djb2: (str: string) => number;\n setAllowedOriginHashes: (hashes: number[]) => void;\n ReportingTransport: typeof ReportingTransport;\n ErrorReportingService: typeof ErrorReportingService;\n LoggingService: typeof LoggingService;\n RateLimiter: typeof RateLimiter;\n ErrorCodes: typeof ErrorCodes;\n WSDKErrorSeverity: typeof WSDKErrorSeverity;\n}\n\ninterface ForwarderRegistration {\n name: string;\n constructor: new () => RoktKit;\n getId: () => number;\n}\n\ninterface ReportingConfig {\n loggingUrl?: string;\n errorUrl?: string;\n integrationDomain?: string;\n isLoggingEnabled: boolean;\n}\n\ninterface ErrorReport {\n message: string;\n code?: string;\n severity?: string;\n stackTrace?: string;\n}\n\n// A log-delivery failure. statusCode is set when the request reached the server\n// and returned a non-2xx status (server-side); it is absent for network-level\n// failures such as ad-blockers, offline, or CORS rejections (client-side).\ninterface DeliveryError extends Error {\n statusCode?: number;\n}\n\ninterface LogEntry {\n message: string;\n code?: string;\n}\n\ninterface RoktExtensionConfig {\n roktExtensionsQueryParams: string[];\n legacyRoktExtensions: string[];\n loadThankYouElement: boolean;\n}\n\ndeclare global {\n interface Window {\n Rokt?: RoktGlobal;\n __rokt_li_guid__?: string;\n optimizely?: OptimizelyGlobal;\n // mParticle is declared as any to avoid conflicts with @mparticle/web-sdk type declarations.\n // We use the typed mp() accessor for all internal accesses.\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n mParticle: any;\n }\n}\n\n// ============================================================\n// Module-level constants\n// ============================================================\n\nconst name = 'Rokt';\nconst moduleId = 181;\nconst EVENT_NAME_SELECT_PLACEMENTS = 'selectPlacements';\nconst ADBLOCK_CONTROL_DOMAIN = 'apps.roktecommerce.com';\nconst INIT_LOG_SAMPLING_RATE = 0.1;\nconst ROKT_THANK_YOU_JOURNEY_EXTENSION = 'ThankYouPageJourney';\nconst ROKT_INTEGRATION_SCRIPT_ID = 'rokt-launcher';\nconst ROKT_THANK_YOU_ELEMENT_SCRIPT_ID = 'rokt-thank-you-element';\nconst USER_IDENTIFIED_IN_WORKSPACE_KEY = 'userIdentifiedInWorkspace';\n\n// Bound on how long selectPlacements will wait for an in-flight Workspace\n// IDSync search before proceeding without the userIdentifiedInWorkspace flag.\n// Long enough to cover the typical /v1/search round-trip (~50ms); short enough that a\n// stalled search never blocks placement rendering on a thank-you page.\nconst WORKSPACE_SEARCH_SELECT_TIMEOUT_MS = 500;\n\n// ============================================================\n// Reporting service constants\n// ============================================================\n\nconst ErrorCodes = {\n UNKNOWN_ERROR: 'UNKNOWN_ERROR',\n UNHANDLED_EXCEPTION: 'UNHANDLED_EXCEPTION',\n IDENTITY_REQUEST: 'IDENTITY_REQUEST',\n LOG_DELIVERY_FAILURE: 'LOG_DELIVERY_FAILURE',\n} as const;\n\nconst WSDKErrorSeverity = {\n ERROR: 'ERROR',\n INFO: 'INFO',\n WARNING: 'WARNING',\n} as const;\n\nconst DEFAULT_ROKT_DOMAIN = 'apps.rokt-api.com';\nconst LOGGING_ENDPOINT = '/v1/log';\nconst ERROR_ENDPOINT = '/v1/errors';\nconst RATE_LIMIT_PER_SEVERITY = 10;\n\n// ============================================================\n// Helper: typed accessor for window.mParticle\n// We use an explicit cast here to avoid conflicts with @mparticle/web-sdk\n// type declarations while still providing full type safety for our usages.\n// ============================================================\n\nfunction mp(): MParticleExtended {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n return (window as any).mParticle as MParticleExtended;\n}\n\n// ============================================================\n// Module-level utility functions\n// ============================================================\n\nfunction generateLauncherScript(domain: string | undefined, extensions: string[]): string {\n const launcherPath = '/wsdk/integrations/launcher.js';\n const baseUrl = [generateBaseUrl(domain), launcherPath].join('');\n\n if (!extensions || extensions.length === 0) {\n return baseUrl;\n }\n return baseUrl + '?extensions=' + extensions.join(',');\n}\n\nfunction generateThankYouElementScript(domain: string | undefined) {\n const thankYouElementPath = '/rokt-elements/rokt-element-thank-you.js';\n return [generateBaseUrl(domain), thankYouElementPath].join('');\n}\n\nfunction generateBaseUrl(domain: string | undefined) {\n const resolvedDomain = typeof domain !== 'undefined' ? domain : DEFAULT_ROKT_DOMAIN;\n const protocol = 'https://';\n\n return [protocol, resolvedDomain].join('');\n}\n\nfunction generateReportingUrl(configuredUrl: string | undefined, domain: string | undefined, endpoint: string): string {\n if (configuredUrl) {\n if (configuredUrl.startsWith('http://') || configuredUrl.startsWith('https://')) {\n return configuredUrl;\n }\n return 'https://' + configuredUrl;\n }\n\n return generateBaseUrl(domain) + endpoint;\n}\n\nfunction loadRoktScript(\n scriptId: string,\n source: string,\n handlers?: { onLoad?: () => void; onError?: (e: Event | string) => void },\n): void {\n if (document.getElementById(scriptId)) return; // resolves the preexisting script issue\n\n const target = document.head || document.body;\n const script = document.createElement('script');\n script.id = scriptId;\n script.type = 'text/javascript';\n script.src = source;\n script.async = true;\n script.crossOrigin = 'anonymous';\n (script as HTMLScriptElement & { fetchPriority: string }).fetchPriority = 'high';\n if (handlers?.onLoad) script.onload = handlers.onLoad;\n if (handlers?.onError) script.onerror = handlers.onError;\n target.appendChild(script);\n}\n\nfunction isObject(val: unknown): val is Record {\n return val != null && typeof val === 'object' && Array.isArray(val) === false;\n}\n\nfunction parseSettingsString(settingsString?: string): T[] {\n if (!settingsString) {\n return [];\n }\n try {\n return JSON.parse(settingsString.replace(/"/g, '\"')) as T[];\n } catch (_error) {\n console.error('Settings string contains invalid JSON');\n }\n return [];\n}\n\nfunction extractRoktExtensionConfig(settingsString?: string): RoktExtensionConfig {\n const settings = settingsString ? parseSettingsString(settingsString) : [];\n const roktExtensionsQueryParams: string[] = [];\n const legacyRoktExtensions: string[] = [];\n let loadThankYouElement = false;\n\n for (let i = 0; i < settings.length; i++) {\n const extensionName = settings[i].value;\n if (extensionName === 'thank-you-journey') {\n loadThankYouElement = true;\n legacyRoktExtensions.push(ROKT_THANK_YOU_JOURNEY_EXTENSION);\n } else {\n roktExtensionsQueryParams.push(extensionName);\n }\n }\n\n return {\n roktExtensionsQueryParams,\n legacyRoktExtensions,\n loadThankYouElement,\n };\n}\n\nasync function registerLegacyExtensions(legacyExtensions: string[], launcher: RoktLauncher | null) {\n const extensions: Promise[] = [];\n if (launcher) {\n for (const extension of legacyExtensions) {\n extensions.push(launcher.use(extension));\n }\n }\n\n return Promise.all(extensions);\n}\n\nfunction generateMappedEventLookup(placementEventMapping: PlacementEventMappingEntry[]): Record {\n if (!placementEventMapping) {\n return {};\n }\n\n const mappedEvents: Record = {};\n for (let i = 0; i < placementEventMapping.length; i++) {\n const mapping = placementEventMapping[i];\n mappedEvents[mapping.jsmap] = mapping.value;\n }\n return mappedEvents;\n}\n\nfunction generateMappedEventAttributeLookup(\n placementEventAttributeMapping: EventAttributeMapping[],\n): Record {\n const mappedAttributeKeys: Record = {};\n if (!Array.isArray(placementEventAttributeMapping)) {\n return mappedAttributeKeys;\n }\n for (let i = 0; i < placementEventAttributeMapping.length; i++) {\n const mapping = placementEventAttributeMapping[i];\n if (!mapping || !isString(mapping.value) || !isString(mapping.map)) {\n continue;\n }\n\n const mappedAttributeKey = mapping.value;\n const eventAttributeKey = mapping.map;\n\n if (!mappedAttributeKeys[mappedAttributeKey]) {\n mappedAttributeKeys[mappedAttributeKey] = [];\n }\n\n mappedAttributeKeys[mappedAttributeKey].push({\n eventAttributeKey: eventAttributeKey,\n conditions: Array.isArray(mapping.conditions) ? mapping.conditions : [],\n });\n }\n return mappedAttributeKeys;\n}\n\nfunction hashEventMessage(messageType: number, eventType: number, eventName: string): string | number {\n return mp().generateHash([messageType, eventType, eventName].join(''));\n}\n\nfunction isEmpty(value: unknown): boolean {\n if (value == null) return true;\n if (typeof value === 'object') {\n return Object.keys(value as object).length === 0;\n }\n if (Array.isArray(value)) {\n return (value as unknown[]).length === 0;\n }\n return false;\n}\n\nfunction isString(value: unknown): value is string {\n return typeof value === 'string';\n}\n\nfunction generateIntegrationName(customIntegrationName?: string): string {\n const coreSdkVersion = mp().getVersion();\n const kitVersion = process.env.PACKAGE_VERSION;\n let integrationName = 'mParticle_' + 'wsdkv_' + coreSdkVersion + '_kitv_' + kitVersion;\n\n if (customIntegrationName) {\n integrationName += '_' + customIntegrationName;\n }\n return integrationName;\n}\n\nfunction djb2(str: string): number {\n let hash = 5381;\n for (let i = 0; i < str.length; i++) {\n hash = (hash << 5) + hash + str.charCodeAt(i);\n hash = hash & hash;\n }\n return hash;\n}\n\nfunction createAutoRemovedIframe(src: string): void {\n const iframe = document.createElement('iframe');\n iframe.style.display = 'none';\n iframe.setAttribute('sandbox', 'allow-scripts allow-same-origin');\n iframe.src = src;\n iframe.onload = function () {\n iframe.onload = null;\n if (iframe.parentNode) {\n iframe.parentNode.removeChild(iframe);\n }\n };\n const target = document.body || document.head;\n if (target) {\n target.appendChild(iframe);\n }\n}\n\nfunction sendAdBlockMeasurementSignals(domain: string | undefined, version: string | null): void {\n const originHash = djb2(window.location.origin);\n const allowedOriginHashes = RoktKit._allowedOriginHashes;\n if (allowedOriginHashes.indexOf(originHash) === -1) {\n return;\n }\n\n if (Math.random() >= INIT_LOG_SAMPLING_RATE) {\n return;\n }\n\n const guid = window.__rokt_li_guid__;\n if (!guid) {\n return;\n }\n\n const pageUrl = window.location.href.split('?')[0].split('#')[0];\n const params =\n 'version=' +\n encodeURIComponent(version ?? '') +\n '&launcherInstanceGuid=' +\n encodeURIComponent(guid) +\n '&pageUrl=' +\n encodeURIComponent(pageUrl);\n\n const existingDomain = domain || 'apps.rokt.com';\n createAutoRemovedIframe('https://' + existingDomain + '/v1/wsdk-init/index.html?' + params);\n\n createAutoRemovedIframe(\n 'https://' + ADBLOCK_CONTROL_DOMAIN + '/v1/wsdk-init/index.html?' + params + '&isControl=true',\n );\n}\n\n// ============================================================\n// Reporting helpers\n// ============================================================\n\nfunction _isDebugModeEnabled(): boolean {\n return typeof window !== 'undefined' && !!window.location?.search?.toLowerCase().includes('mp_enable_logging=true');\n}\n\nfunction _getReportingUrl(): string | undefined {\n return typeof window !== 'undefined' ? window.location?.href : undefined;\n}\n\nfunction _getUserAgent(): string | undefined {\n return typeof window !== 'undefined' ? window.navigator?.userAgent : undefined;\n}\n\nclass RateLimiter {\n private _logCount: Record = {};\n\n incrementAndCheck(severity: string): boolean {\n const count = this._logCount[severity] || 0;\n const newCount = count + 1;\n this._logCount[severity] = newCount;\n return newCount > RATE_LIMIT_PER_SEVERITY;\n }\n}\n\nclass ReportingTransport {\n private _isEnabled: boolean;\n private _integrationName: string;\n private _launcherInstanceGuid: string | undefined;\n private _accountId: string | null;\n private _rateLimiter: RateLimiter;\n private readonly _reporter = 'mp-wsdk';\n\n constructor(\n config: ReportingConfig,\n integrationName: string | null | undefined,\n launcherInstanceGuid: string | undefined,\n accountId: string | null | undefined,\n rateLimiter?: RateLimiter,\n ) {\n const isLoggingEnabled = config.isLoggingEnabled;\n this._integrationName = integrationName || '';\n this._launcherInstanceGuid = launcherInstanceGuid;\n this._accountId = accountId || null;\n this._rateLimiter = rateLimiter || new RateLimiter();\n this._isEnabled = _isDebugModeEnabled() || isLoggingEnabled;\n }\n\n send(\n url: string,\n severity: string,\n msg: string,\n code?: string,\n stackTrace?: string,\n onError?: (error: DeliveryError) => void,\n ): void {\n if (!this._isEnabled || this._rateLimiter.incrementAndCheck(severity)) {\n return;\n }\n\n try {\n const logRequest = {\n additionalInformation: {\n message: msg,\n version: this._integrationName,\n },\n severity,\n code: code || ErrorCodes.UNKNOWN_ERROR,\n url: _getReportingUrl(),\n deviceInfo: _getUserAgent(),\n stackTrace,\n reporter: this._reporter,\n integration: this._integrationName,\n };\n\n const headers: Record = {\n Accept: 'text/plain;charset=UTF-8',\n 'Content-Type': 'application/json',\n 'rokt-launcher-version': this._integrationName,\n 'rokt-wsdk-version': 'joint',\n };\n\n if (this._launcherInstanceGuid) {\n headers['rokt-launcher-instance-guid'] = this._launcherInstanceGuid;\n }\n if (this._accountId) {\n headers['rokt-account-id'] = this._accountId;\n }\n\n fetch(url, {\n method: 'POST',\n headers,\n body: JSON.stringify(logRequest),\n })\n .then((response: Response) => {\n // fetch only rejects on network failures; an HTTP 5xx resolves with\n // ok === false. Surface server-side failures so they are not swallowed.\n if (!response.ok) {\n const serverError: DeliveryError = new Error('HTTP ' + response.status + ' from log endpoint');\n serverError.statusCode = response.status;\n throw serverError;\n }\n })\n .catch((error: DeliveryError) => {\n console.error('ReportingTransport: Failed to send log', error);\n if (onError) onError(error);\n });\n } catch (error) {\n console.error('ReportingTransport: Failed to send log', error);\n if (onError) onError(error as DeliveryError);\n }\n }\n}\n\nclass ErrorReportingService {\n private _transport: ReportingTransport;\n private _errorUrl: string;\n\n constructor(\n config: ReportingConfig,\n integrationName: string | null | undefined,\n launcherInstanceGuid?: string,\n accountId?: string | null,\n rateLimiter?: RateLimiter,\n ) {\n this._transport = new ReportingTransport(config, integrationName, launcherInstanceGuid, accountId, rateLimiter);\n this._errorUrl = generateReportingUrl(config?.errorUrl, config?.integrationDomain, ERROR_ENDPOINT);\n }\n\n report(error: ErrorReport | null | undefined): void {\n if (!error) return;\n const severity = error.severity || WSDKErrorSeverity.ERROR;\n this._transport.send(this._errorUrl, severity, error.message, error.code, error.stackTrace);\n }\n}\n\nclass LoggingService {\n private _transport: ReportingTransport;\n private _loggingUrl: string;\n private _errorReportingService: { report: (e: ErrorReport) => void };\n\n constructor(\n config: ReportingConfig,\n errorReportingService: { report: (e: ErrorReport) => void },\n integrationName: string | null | undefined,\n launcherInstanceGuid?: string,\n accountId?: string | null,\n rateLimiter?: RateLimiter,\n ) {\n this._transport = new ReportingTransport(config, integrationName, launcherInstanceGuid, accountId, rateLimiter);\n this._loggingUrl = generateReportingUrl(config?.loggingUrl, config?.integrationDomain, LOGGING_ENDPOINT);\n this._errorReportingService = errorReportingService;\n }\n\n log(entry: LogEntry | null | undefined): void {\n if (!entry) return;\n this._transport.send(\n this._loggingUrl,\n WSDKErrorSeverity.INFO,\n entry.message,\n entry.code,\n undefined,\n (error: DeliveryError) => {\n if (this._errorReportingService) {\n // A failed log POST is not itself an SDK error. Network-level failures\n // (ad-blockers, offline, CORS) are client-side noise and reported as a\n // WARNING; only a server-side non-2xx response stays at ERROR severity.\n const isServerSide = typeof error.statusCode === 'number';\n this._errorReportingService.report({\n message: 'LoggingService: Failed to send log: ' + error.message,\n code: ErrorCodes.LOG_DELIVERY_FAILURE,\n severity: isServerSide ? WSDKErrorSeverity.ERROR : WSDKErrorSeverity.WARNING,\n });\n }\n },\n );\n }\n}\n\n// ============================================================\n// RoktKit class\n// ============================================================\n\nclass RoktKit implements KitInterface {\n // Static field for allowed origin hashes (mutable by testHelpers)\n public static _allowedOriginHashes: number[] = [-553112570, 549508659];\n\n private static readonly PERFORMANCE_MARKS = {\n RoktScriptAppended: 'mp:RoktScriptAppended',\n };\n\n private static readonly EMAIL_SHA256_KEY = 'emailsha256';\n\n // Public fields (accessed by tests and the mParticle framework)\n public name = name;\n public id = moduleId;\n public moduleId = moduleId;\n public isInitialized = false;\n public launcher: RoktLauncher | null = null;\n public filters: KitFilters = {};\n public userAttributes: Record = {};\n // Flag set by the Workspace IDSync flow on a 200 response. Stored on the\n // kit instance and merged into placement attributes inside selectPlacements.\n public userIdentifiedInWorkspace = false;\n public testHelpers: TestHelpers | null = null;\n public placementEventMappingLookup: Record = {};\n public placementEventAttributeMappingLookup: Record = {};\n public integrationName: string | null = null;\n public domain?: string;\n public errorReportingService: ErrorReportingService | null = null;\n public loggingService: LoggingService | null = null;\n\n // Private fields\n private _mappedEmailSha256Key?: string;\n private _onboardingExpProvider?: string;\n private _thankYouElementOnLoadCallback: (() => void) | null = null;\n private _isThankYouElementLoaded = false;\n private _workspaceIdSyncApiKey?: string;\n\n // Held during a search dispatch so the next selectPlacements call;\n // can wait for the HTTP response before reading userIdentifiedInWorkspace;\n // — otherwise the first placement call ships without the flag.\n private _workspaceSearchInFlightPromise: Promise | null = null;\n // Stable serialization of the identifier set sent in the most recent\n // successful search dispatch. If a subsequent identification arrives with\n // an identical set, we skip the network call (the flag is still correct\n // from the prior search). Keyed over the full IUserIdentities map — not\n // just email — so partners passing hashed email through `other`/`other2-10`\n // or any other identifier benefit from the same dedupe. Cleared on logout\n // so a re-login re-evaluates fresh.\n private _workspaceLastSearchedIdentitiesKey?: string;\n\n // ---- Private helpers ----\n\n private getEventAttributeValue(event: SDKEvent, eventAttributeKey: string): unknown {\n const attributes = event && event.EventAttributes;\n if (!attributes) {\n return null;\n }\n\n if (typeof attributes[eventAttributeKey] === 'undefined') {\n return null;\n }\n\n return attributes[eventAttributeKey];\n }\n\n private doesEventAttributeConditionMatch(condition: EventAttributeCondition, actualValue: unknown): boolean {\n if (!condition || !isString(condition.operator)) {\n return false;\n }\n\n const operator = condition.operator.toLowerCase();\n const expectedValue = condition.attributeValue;\n\n if (operator === 'exists') {\n return actualValue !== null;\n }\n\n if (actualValue == null) {\n return false;\n }\n\n if (operator === 'equals') {\n return String(actualValue) === String(expectedValue);\n }\n\n if (operator === 'contains') {\n return String(actualValue).indexOf(String(expectedValue)) !== -1;\n }\n\n return false;\n }\n\n private doesEventMatchRule(event: SDKEvent, rule: PlacementEventRule): boolean {\n if (!rule || !isString(rule.eventAttributeKey)) {\n return false;\n }\n\n const conditions = rule.conditions;\n if (!Array.isArray(conditions)) {\n return false;\n }\n\n const actualValue = this.getEventAttributeValue(event, rule.eventAttributeKey);\n\n if (conditions.length === 0) {\n return actualValue !== null;\n }\n for (let i = 0; i < conditions.length; i++) {\n if (!this.doesEventAttributeConditionMatch(conditions[i], actualValue)) {\n return false;\n }\n }\n\n return true;\n }\n\n private applyPlacementEventAttributeMapping(event: SDKEvent): void {\n const mappedAttributeKeys = Object.keys(this.placementEventAttributeMappingLookup);\n for (let i = 0; i < mappedAttributeKeys.length; i++) {\n const mappedAttributeKey = mappedAttributeKeys[i];\n const rulesForMappedAttributeKey = this.placementEventAttributeMappingLookup[mappedAttributeKey];\n if (isEmpty(rulesForMappedAttributeKey)) {\n continue;\n }\n\n // Require ALL rules for the same key to match (AND).\n let allMatch = true;\n for (let j = 0; j < rulesForMappedAttributeKey.length; j++) {\n if (!this.doesEventMatchRule(event, rulesForMappedAttributeKey[j])) {\n allMatch = false;\n break;\n }\n }\n if (!allMatch) {\n continue;\n }\n\n mp().Rokt.setLocalSessionAttribute?.(mappedAttributeKey, true);\n }\n }\n\n private isLauncherReadyToAttach(): boolean {\n return !!window.Rokt && typeof window.Rokt.createLauncher === 'function';\n }\n\n /**\n * Returns the user identities from the filtered user, if any.\n */\n private returnUserIdentities(filteredUser: FilteredUser | null | undefined): Record {\n if (!filteredUser || !filteredUser.getUserIdentities) {\n return {};\n }\n\n const userIdentities: IUserIdentities = filteredUser.getUserIdentities().userIdentities;\n\n return this.replaceOtherIdentityWithEmailsha256(userIdentities);\n }\n\n private returnLocalSessionAttributes(): Record {\n if (!mp().Rokt || typeof mp().Rokt.getLocalSessionAttributes !== 'function') {\n return {};\n }\n if (isEmpty(this.placementEventMappingLookup) && isEmpty(this.placementEventAttributeMappingLookup)) {\n return {};\n }\n return mp().Rokt.getLocalSessionAttributes!();\n }\n\n private replaceOtherIdentityWithEmailsha256(userIdentities: IUserIdentities): Record {\n const newUserIdentities: Record = { ...(userIdentities || {}) };\n const key = this._mappedEmailSha256Key;\n if (key && userIdentities[key as keyof IUserIdentities]) {\n newUserIdentities[RoktKit.EMAIL_SHA256_KEY] = userIdentities[key as keyof IUserIdentities] as string;\n }\n if (key) {\n delete newUserIdentities[key];\n }\n\n return newUserIdentities;\n }\n\n private logSelectPlacementsEvent(attributes: unknown): void {\n if (!window.mParticle || typeof mp().logEvent !== 'function') {\n return;\n }\n\n if (!isObject(attributes)) {\n return;\n }\n\n const EVENT_TYPE_OTHER = mp().EventType.Other;\n\n mp().logEvent(EVENT_NAME_SELECT_PLACEMENTS, EVENT_TYPE_OTHER, attributes as Record);\n }\n\n private setRoktSessionId(sessionId: string): void {\n if (!sessionId || typeof sessionId !== 'string') {\n return;\n }\n try {\n const mpInstance = mp().getInstance();\n if (mpInstance && typeof mpInstance.setIntegrationAttribute === 'function') {\n mpInstance.setIntegrationAttribute(moduleId, {\n roktSessionId: sessionId,\n });\n }\n } catch (_e) {\n // Best effort — never let this break the partner page\n }\n }\n\n private attachLauncher(\n accountId: string,\n launcherOptions: Record,\n legacyRoktExtensions: string[] = [],\n ): void {\n const mpSessionId =\n mp() && mp().sessionManager && typeof mp().sessionManager!.getSession === 'function'\n ? mp().sessionManager!.getSession()\n : undefined;\n\n const options: Record = {\n accountId,\n ...(launcherOptions || {}),\n ...(mpSessionId ? { mpSessionId } : {}),\n };\n\n let launcherPromise: Promise;\n if (this.isPartnerInLocalLauncherTestGroup()) {\n launcherPromise = Promise.resolve(window.Rokt!.createLocalLauncher(options));\n } else {\n launcherPromise = window.Rokt!.createLauncher(options);\n }\n\n launcherPromise\n .then(async (launcher) => {\n await registerLegacyExtensions(legacyRoktExtensions, launcher);\n this.initRoktLauncher(launcher);\n })\n .catch((err: unknown) => {\n console.error('Error creating Rokt launcher:', err);\n });\n }\n\n private initRoktLauncher(launcher: RoktLauncher): void {\n // Assign the launcher to a global variable for later access\n if (window.Rokt) {\n window.Rokt.currentLauncher = launcher;\n }\n // Locally cache the launcher and filters\n this.launcher = launcher;\n\n const roktFilters = mp().Rokt?.filters;\n\n if (!roktFilters) {\n console.warn('Rokt Kit: No filters have been set.');\n } else {\n this.filters = roktFilters;\n if (!roktFilters.filteredUser) {\n console.warn('Rokt Kit: No filtered user has been set.');\n } else {\n this._workspaceSearchInFlightPromise = this.search(roktFilters.filteredUser);\n }\n }\n\n // Kit must be initialized before attaching to the Rokt manager\n this.isInitialized = true;\n\n sendAdBlockMeasurementSignals(this.domain, this.integrationName);\n\n // Attaches the kit to the Rokt manager\n mp().Rokt.attachKit(this);\n }\n\n private fetchOptimizely(): Record {\n const forwarders = mp()\n ._getActiveForwarders()\n .filter((forwarder) => forwarder.name === 'Optimizely');\n\n try {\n if (forwarders.length > 0 && window.optimizely) {\n const optimizelyState = window.optimizely.get('state');\n if (!optimizelyState || !optimizelyState.getActiveExperimentIds) {\n return {};\n }\n const activeExperimentIds = optimizelyState.getActiveExperimentIds();\n const activeExperiments = activeExperimentIds.reduce((acc: Record, expId: string) => {\n acc['rokt.custom.optimizely.experiment.' + expId + '.variationId'] =\n optimizelyState.getVariationMap()[expId].id;\n return acc;\n }, {});\n return activeExperiments;\n }\n } catch (error) {\n console.error('Error fetching Optimizely attributes:', error);\n }\n return {};\n }\n\n private isKitReady(): boolean {\n return !!(this.isInitialized && this.launcher);\n }\n\n private isPartnerInLocalLauncherTestGroup(): boolean {\n return !!(mp().config && mp().config!.isLocalLauncherEnabled && this.isAssignedToSampleGroup());\n }\n\n private isAssignedToSampleGroup(): boolean {\n const LOCAL_LAUNCHER_TEST_GROUP_THRESHOLD = 0.5;\n return Math.random() > LOCAL_LAUNCHER_TEST_GROUP_THRESHOLD;\n }\n\n private captureTiming(metricName: string): void {\n if (window && mp() && mp().captureTiming && metricName) {\n mp().captureTiming!(metricName);\n }\n }\n\n // ---- Public methods (mParticle Kit Callbacks) ----\n\n /**\n * Initializes the Rokt forwarder with settings from the mParticle server.\n */\n public init(\n settings: Record,\n _service: unknown,\n testMode: boolean,\n _trackerId: unknown,\n filteredUserAttributes?: Record,\n ): string {\n const kitSettings = settings as unknown as RoktKitSettings;\n const accountId = kitSettings.accountId;\n this.userAttributes = removeSelectPlacementsAttributePersistenceDeniedAttributes(filteredUserAttributes);\n this._onboardingExpProvider = kitSettings.onboardingExpProvider;\n\n const placementEventMapping = parseSettingsString(kitSettings.placementEventMapping);\n this.placementEventMappingLookup = generateMappedEventLookup(placementEventMapping);\n\n const placementEventAttributeMapping = parseSettingsString(\n kitSettings.placementEventAttributeMapping,\n );\n this.placementEventAttributeMappingLookup = generateMappedEventAttributeLookup(placementEventAttributeMapping);\n\n // Set dynamic OTHER_IDENTITY based on server settings\n if (kitSettings.hashedEmailUserIdentityType) {\n this._mappedEmailSha256Key = kitSettings.hashedEmailUserIdentityType.toLowerCase();\n }\n\n this._workspaceIdSyncApiKey = isString(kitSettings.workspaceIdSyncApiKey)\n ? kitSettings.workspaceIdSyncApiKey\n : undefined;\n\n const domain = mp().Rokt?.domain;\n const { roktExtensionsQueryParams, legacyRoktExtensions, loadThankYouElement } = extractRoktExtensionConfig(\n kitSettings.roktExtensions,\n );\n const launcherOptions: Record = {\n ...((mp().Rokt?.launcherOptions as Record) || {}),\n };\n this.integrationName = generateIntegrationName(launcherOptions.integrationName as string | undefined);\n launcherOptions.integrationName = this.integrationName;\n\n this.domain = domain;\n\n const reportingConfig: ReportingConfig = {\n loggingUrl: kitSettings.loggingUrl,\n errorUrl: kitSettings.errorUrl,\n integrationDomain: domain,\n isLoggingEnabled: mp().config?.isLoggingEnabled === true,\n };\n const errorReportingService = new ErrorReportingService(\n reportingConfig,\n this.integrationName,\n window.__rokt_li_guid__,\n kitSettings.accountId,\n );\n const loggingService = new LoggingService(\n reportingConfig,\n errorReportingService,\n this.integrationName,\n window.__rokt_li_guid__,\n kitSettings.accountId,\n );\n\n this.errorReportingService = errorReportingService;\n this.loggingService = loggingService;\n\n if (mp()._registerErrorReportingService) {\n mp()._registerErrorReportingService!(errorReportingService);\n }\n if (mp()._registerLoggingService) {\n mp()._registerLoggingService!(loggingService);\n }\n\n if (testMode) {\n this.testHelpers = {\n generateLauncherScript: generateLauncherScript,\n generateThankYouElementScript: generateThankYouElementScript,\n extractRoktExtensionConfig: extractRoktExtensionConfig,\n hashEventMessage: hashEventMessage,\n parseSettingsString: parseSettingsString,\n generateMappedEventLookup: generateMappedEventLookup,\n generateMappedEventAttributeLookup: generateMappedEventAttributeLookup,\n sendAdBlockMeasurementSignals: sendAdBlockMeasurementSignals,\n createAutoRemovedIframe: createAutoRemovedIframe,\n djb2: djb2,\n setAllowedOriginHashes: (hashes: number[]) => {\n RoktKit._allowedOriginHashes = hashes;\n },\n ReportingTransport: ReportingTransport,\n ErrorReportingService: ErrorReportingService,\n LoggingService: LoggingService,\n RateLimiter: RateLimiter,\n ErrorCodes: ErrorCodes,\n WSDKErrorSeverity: WSDKErrorSeverity,\n };\n this.attachLauncher(accountId, launcherOptions);\n return 'Successfully initialized: ' + name;\n }\n\n if (loadThankYouElement) {\n mp().Rokt.flushOnShoppableAdsReadyMessageQueue?.(this);\n loadRoktScript(ROKT_THANK_YOU_ELEMENT_SCRIPT_ID, generateThankYouElementScript(domain), {\n onLoad: () => {\n this._isThankYouElementLoaded = true;\n if (this._thankYouElementOnLoadCallback) {\n this._thankYouElementOnLoadCallback();\n }\n },\n onError: (error) => {\n console.error('Error loading Rokt Thank You Element script:', error);\n },\n });\n }\n\n if (this.isLauncherReadyToAttach()) {\n this.attachLauncher(accountId, launcherOptions, legacyRoktExtensions);\n } else {\n loadRoktScript(ROKT_INTEGRATION_SCRIPT_ID, generateLauncherScript(domain, roktExtensionsQueryParams), {\n onLoad: () => {\n if (this.isLauncherReadyToAttach()) {\n this.attachLauncher(accountId, launcherOptions, legacyRoktExtensions);\n } else {\n console.error('Rokt object is not available after script load.');\n }\n },\n onError: (error) => {\n console.error('Error loading Rokt launcher script:', error);\n },\n });\n\n this.captureTiming(RoktKit.PERFORMANCE_MARKS.RoktScriptAppended);\n }\n\n return 'Successfully initialized: ' + name;\n }\n\n public process(event: SDKEvent): string {\n if (!this.isKitReady()) {\n return 'Kit not ready for forwarder: ' + name;\n }\n if (typeof mp().Rokt?.setLocalSessionAttribute === 'function') {\n if (!isEmpty(this.placementEventAttributeMappingLookup)) {\n this.applyPlacementEventAttributeMapping(event);\n }\n\n if (!isEmpty(this.placementEventMappingLookup)) {\n const hashedEvent = hashEventMessage(event.EventDataType, event.EventCategory, event.EventName ?? '');\n if (this.placementEventMappingLookup[String(hashedEvent)]) {\n mp().Rokt.setLocalSessionAttribute?.(this.placementEventMappingLookup[String(hashedEvent)], true);\n }\n }\n }\n\n return 'Successfully sent to forwarder: ' + name;\n }\n\n public setExtensionData(partnerExtensionData: Record): void {\n if (!this.isKitReady()) {\n console.error('Rokt Kit: Not initialized');\n return;\n }\n\n window.Rokt!.setExtensionData(partnerExtensionData);\n }\n\n public setUserAttribute(key: string, value: unknown): string {\n if (!isSelectPlacementsAttributePersistenceDenied(key)) {\n this.userAttributes[key] = value;\n }\n return 'Successfully set user attribute for forwarder: ' + name;\n }\n\n public removeUserAttribute(key: string): string {\n delete this.userAttributes[key];\n return 'Successfully removed user attribute for forwarder: ' + name;\n }\n\n private handleIdentityComplete(user: IMParticleUser, callbackName: string): string {\n this.userAttributes = removeSelectPlacementsAttributePersistenceDeniedAttributes(user.getAllUserAttributes());\n return 'Successfully called ' + callbackName + ' for forwarder: ' + name;\n }\n\n public onUserIdentified(user: IMParticleUser): string {\n const filteredUser = user as FilteredUser;\n this.filters.filteredUser = filteredUser;\n this._workspaceSearchInFlightPromise = this.search(filteredUser);\n return this.handleIdentityComplete(user, 'onUserIdentified');\n }\n\n private search(filteredUser: FilteredUser): Promise {\n const apiKey = this._workspaceIdSyncApiKey;\n if (!apiKey) {\n this.userIdentifiedInWorkspace = false;\n this._workspaceLastSearchedIdentitiesKey = undefined;\n return Promise.resolve();\n }\n const search = mp().Identity?.search;\n if (typeof search !== 'function') {\n this.userIdentifiedInWorkspace = false;\n this._workspaceLastSearchedIdentitiesKey = undefined;\n return Promise.resolve();\n }\n\n const userIdentities: IUserIdentities | null = filteredUser.getUserIdentities\n ? filteredUser.getUserIdentities().userIdentities\n : null;\n\n // Forward every non-empty string identifier the user has — email,\n // customerid, other/other2-10 (commonly used for hashed email),\n // mobile_number, facebook, etc. The host SDK's Identity.search accepts\n // the full IUserIdentities surface and the server validates it.\n const knownIdentities: Record = {};\n if (userIdentities) {\n for (const key of Object.keys(userIdentities) as Array) {\n const value = userIdentities[key];\n if (isString(value) && value.length > 0) {\n knownIdentities[key] = value;\n }\n }\n }\n\n const identityKeys = Object.keys(knownIdentities);\n if (identityKeys.length === 0) {\n this.userIdentifiedInWorkspace = false;\n this._workspaceLastSearchedIdentitiesKey = undefined;\n return Promise.resolve();\n }\n\n // Stable cache key: sort keys so insertion-order differences don't\n // cause false misses. The values are partner-supplied strings; no\n // hashing needed — equality on this serialization is sufficient.\n const identitiesKey = identityKeys\n .sort()\n .map((k) => `${k}=${knownIdentities[k]}`)\n .join('&');\n\n // Same identifier set as the last successful dispatch → skip the\n // network call. The current flag value still reflects the correct\n // match status.\n if (identitiesKey === this._workspaceLastSearchedIdentitiesKey) {\n return this._workspaceSearchInFlightPromise || Promise.resolve();\n }\n\n // New / different identifier set → reset and re-search. Cache the key\n // up front so a second concurrent invocation with the same set also\n // dedupes.\n this.userIdentifiedInWorkspace = false;\n this._workspaceLastSearchedIdentitiesKey = identitiesKey;\n\n return new Promise((resolve) => {\n try {\n search(apiKey, knownIdentities as IUserIdentities, (result: WorkspaceIdSyncResult) => {\n if (result?.httpCode === 200) {\n this.userIdentifiedInWorkspace = true;\n }\n resolve();\n });\n } catch (err) {\n console.error('Rokt Kit: Workspace IDSync search failed', err);\n // Dispatch failed — clear the cache so the same identifier set\n // can retry on the next identification rather than being stuck\n // behind a poisoned entry that short-circuits future searches.\n this._workspaceLastSearchedIdentitiesKey = undefined;\n resolve();\n }\n });\n }\n\n public onLoginComplete(user: IMParticleUser, _filteredIdentityRequest: unknown): string {\n return this.handleIdentityComplete(user, 'onLoginComplete');\n }\n\n public onLogoutComplete(user: IMParticleUser, _filteredIdentityRequest: unknown): string {\n // Anonymous sessions must not carry the previous user's match forward.\n // Clear the flag explicitly here. Also clear the identities cache so a\n // re-login (possibly with the same identifiers) dispatches a fresh\n // search rather than reusing a stale answer.\n this.userIdentifiedInWorkspace = false;\n this._workspaceSearchInFlightPromise = null;\n this._workspaceLastSearchedIdentitiesKey = undefined;\n return this.handleIdentityComplete(user, 'onLogoutComplete');\n }\n\n public onModifyComplete(user: IMParticleUser, _filteredIdentityRequest: unknown): string {\n return this.handleIdentityComplete(user, 'onModifyComplete');\n }\n\n /**\n * Selects placements for Rokt Web SDK with merged attributes, filters, and experimentation options.\n *\n * If a Workspace IDSync search is in flight from a recent onUserIdentified\n * call, this method waits up to `WORKSPACE_SEARCH_SELECT_TIMEOUT_MS` for it\n * to settle so the first placement call can include the\n * `userIdentifiedInWorkspace` flag without racing the network response.\n * The timeout protects against a stalled or slow search blocking placement\n * rendering — if it fires, selectPlacements proceeds without the flag.\n *\n * Implementation note: this method stays non-async deliberately. First,\n * the public return type is `RoktSelection | Promise |\n * undefined` — a superset of the `RoktSelection | Promise`\n * shape declared for `RoktLauncher.selectPlacements` above (line ~70).\n * Marking this `async` would narrow it to `Promise` and silently change the contract for callers that read\n * the result synchronously. Second, `RoktSelection` has an optional\n * `then?` member, so TS treats it as ambiguously promise-like and\n * rejects it as the awaited return of an async function (TS1058) —\n * working around that would require a cast or wrapping every return in\n * `Promise.resolve(...)`. The inner work runs in `_dispatchPlacements`;\n * this wrapper just gates it on the in-flight search via `Promise.race`.\n */\n public selectPlacements(options: Record): RoktSelection | Promise | undefined {\n if (this._workspaceSearchInFlightPromise) {\n const inFlight = this._workspaceSearchInFlightPromise;\n return Promise.race([\n inFlight,\n new Promise((resolve) => setTimeout(resolve, WORKSPACE_SEARCH_SELECT_TIMEOUT_MS)),\n ]).then(() => this._dispatchPlacements(options)) as Promise;\n }\n return this._dispatchPlacements(options);\n }\n\n private _dispatchPlacements(options: Record): RoktSelection | Promise | undefined {\n const attributes = ((options && (options.attributes as Record)) || {}) as Record;\n const cachedUserAttributes = removeSelectPlacementsAttributePersistenceDeniedAttributes(this.userAttributes);\n const placementAttributes: Record = { ...cachedUserAttributes, ...attributes };\n\n const filters = this.filters || {};\n const userAttributeFilters = (filters.userAttributeFilters as string[]) || [];\n const filteredUser = filters.filteredUser || null;\n const mpid = filteredUser ? filteredUser.getMPID() : null;\n\n let filteredAttributes: Record;\n\n if (!filters) {\n console.warn('Rokt Kit: No filters available, using user attributes');\n filteredAttributes = placementAttributes;\n } else if (filters.filterUserAttributes) {\n filteredAttributes = filters.filterUserAttributes(placementAttributes, userAttributeFilters);\n } else {\n filteredAttributes = placementAttributes;\n }\n\n this.userAttributes = removeSelectPlacementsAttributePersistenceDeniedAttributes(filteredAttributes);\n\n const optimizelyAttributes = this._onboardingExpProvider === 'Optimizely' ? this.fetchOptimizely() : {};\n\n const filteredUserIdentities = this.returnUserIdentities(filteredUser);\n\n const localSessionAttributes = this.returnLocalSessionAttributes();\n\n const selectPlacementsAttributes: Record = {\n ...(filteredUserIdentities as Record),\n ...filteredAttributes,\n ...optimizelyAttributes,\n ...localSessionAttributes,\n ...(this.userIdentifiedInWorkspace ? { [USER_IDENTIFIED_IN_WORKSPACE_KEY]: true } : {}),\n mpid,\n };\n\n const selectPlacementsOptions: Record = { ...options, attributes: selectPlacementsAttributes };\n\n const selection = this.launcher!.selectPlacements(selectPlacementsOptions);\n\n // After selection resolves, sync the Rokt session ID back to mParticle, then log\n const logSelection = () => this.logSelectPlacementsEvent(selectPlacementsAttributes);\n\n void Promise.resolve(selection)\n .then((sel) => sel?.context?.sessionId?.then((sessionId) => this.setRoktSessionId(sessionId)))\n .catch(() => undefined)\n .finally(logSelection);\n\n return selection;\n }\n\n /**\n * Passes attributes to the Rokt Web SDK for client-side hashing.\n */\n public hashAttributes(attributes: Record): Promise> | null {\n if (!this.isKitReady()) {\n console.error('Rokt Kit: Not initialized');\n return null;\n }\n return this.launcher!.hashAttributes(attributes);\n }\n\n /**\n * Enables optional Integration Launcher extensions before selecting placements.\n *\n * @deprecated This functionality has been internalized and will be removed in a future release.\n */\n public use(extensionName: string): Promise {\n if (!this.isKitReady()) {\n console.error('Rokt Kit: Not initialized');\n return Promise.reject(new Error('Rokt Kit: Not initialized'));\n }\n if (!extensionName || !isString(extensionName)) {\n return Promise.reject(new Error('Rokt Kit: Invalid extension name'));\n }\n return this.launcher!.use(extensionName);\n }\n\n /**\n * Registers a callback to be invoked once rokt-thank-you-element.js becomes available.\n */\n public onShoppableAdsReady(callback: () => void) {\n if (this._isThankYouElementLoaded) {\n callback();\n } else {\n this._thankYouElementOnLoadCallback = callback;\n }\n }\n}\n\n// ============================================================\n// Kit registration\n// ============================================================\n\nfunction getId(): number {\n return moduleId;\n}\n\nfunction register(config: { kits?: Record }): void {\n if (!config) {\n window.console.log('You must pass a config object to register the kit ' + name);\n return;\n }\n if (!isObject(config)) {\n window.console.log(\"'config' must be an object. You passed in a \" + typeof config);\n return;\n }\n\n if (isObject(config.kits)) {\n (config.kits as Record)[name] = {\n constructor: RoktKit,\n };\n } else {\n config.kits = {};\n config.kits[name] = {\n constructor: RoktKit,\n };\n }\n window.console.log('Successfully registered ' + name + ' to your mParticle configuration');\n}\n\nif (typeof window !== 'undefined' && window.mParticle && mp().addForwarder) {\n mp().addForwarder({\n name: name,\n constructor: RoktKit,\n getId: getId,\n });\n}\n\nexport { register };\n"],"names":["SELECT_PLACEMENTS_ATTRIBUTE_PERSISTENCE_DENY_LIST","SELECT_PLACEMENTS_ATTRIBUTE_PERSISTENCE_DENY_SET","isSelectPlacementsAttributePersistenceDenied","key","removeSelectPlacementsAttributePersistenceDeniedAttributes","attributes","filteredAttributes","sourceAttributes","attributeKeys","i","name","moduleId","EVENT_NAME_SELECT_PLACEMENTS","ADBLOCK_CONTROL_DOMAIN","INIT_LOG_SAMPLING_RATE","ROKT_THANK_YOU_JOURNEY_EXTENSION","ROKT_INTEGRATION_SCRIPT_ID","ROKT_THANK_YOU_ELEMENT_SCRIPT_ID","USER_IDENTIFIED_IN_WORKSPACE_KEY","WORKSPACE_SEARCH_SELECT_TIMEOUT_MS","ErrorCodes","WSDKErrorSeverity","DEFAULT_ROKT_DOMAIN","LOGGING_ENDPOINT","ERROR_ENDPOINT","RATE_LIMIT_PER_SEVERITY","mp","generateLauncherScript","domain","extensions","baseUrl","generateBaseUrl","generateThankYouElementScript","generateReportingUrl","configuredUrl","endpoint","loadRoktScript","scriptId","source","handlers","target","script","isObject","val","parseSettingsString","settingsString","extractRoktExtensionConfig","settings","roktExtensionsQueryParams","legacyRoktExtensions","loadThankYouElement","extensionName","registerLegacyExtensions","legacyExtensions","launcher","extension","generateMappedEventLookup","placementEventMapping","mappedEvents","mapping","generateMappedEventAttributeLookup","placementEventAttributeMapping","mappedAttributeKeys","isString","mappedAttributeKey","eventAttributeKey","hashEventMessage","messageType","eventType","eventName","isEmpty","value","generateIntegrationName","customIntegrationName","integrationName","djb2","str","hash","createAutoRemovedIframe","src","iframe","sendAdBlockMeasurementSignals","version","originHash","RoktKit","guid","pageUrl","params","_isDebugModeEnabled","_getReportingUrl","_getUserAgent","RateLimiter","severity","newCount","ReportingTransport","config","launcherInstanceGuid","accountId","rateLimiter","isLoggingEnabled","url","msg","code","stackTrace","onError","logRequest","headers","response","serverError","error","ErrorReportingService","LoggingService","errorReportingService","entry","isServerSide","_RoktKit","event","condition","actualValue","operator","expectedValue","rule","conditions","rulesForMappedAttributeKey","allMatch","j","filteredUser","userIdentities","newUserIdentities","EVENT_TYPE_OTHER","sessionId","mpInstance","launcherOptions","mpSessionId","options","launcherPromise","err","roktFilters","forwarders","forwarder","optimizelyState","acc","expId","metricName","_service","testMode","_trackerId","filteredUserAttributes","kitSettings","reportingConfig","loggingService","hashes","hashedEvent","partnerExtensionData","user","callbackName","apiKey","search","knownIdentities","identityKeys","identitiesKey","k","resolve","result","_filteredIdentityRequest","inFlight","placementAttributes","filters","userAttributeFilters","mpid","optimizelyAttributes","filteredUserIdentities","localSessionAttributes","selectPlacementsAttributes","selectPlacementsOptions","selection","logSelection","sel","callback","getId","register"],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"Rokt-Kit.esm.js","sources":["../src/selectPlacementsAttributePersistence.ts","../src/utils.ts","../src/storage.ts","../src/pageViewStorage.ts","../src/launcherAttachState.ts","../src/Rokt-Kit.ts"],"sourcesContent":["const SELECT_PLACEMENTS_ATTRIBUTE_PERSISTENCE_DENY_LIST = [\n 'active_time_on_site_ms',\n 'billingaddress1',\n 'billingaddress2',\n 'billingcity',\n 'billingstate',\n 'billingzipcode',\n 'cartitems',\n 'ccbin',\n 'confirmationref',\n 'conversiontype',\n 'country',\n 'couponcode',\n 'currency',\n 'language',\n 'paymentserviceprovider',\n 'paymentserviceproviderattribute',\n 'paymenttype',\n 'shippingaddress1',\n 'shippingcity',\n 'shippingcountry',\n 'shippingmethod',\n 'shippingstate',\n 'shippingzipcode',\n 'totalprice',\n];\nconst SELECT_PLACEMENTS_ATTRIBUTE_PERSISTENCE_DENY_SET = new Set(SELECT_PLACEMENTS_ATTRIBUTE_PERSISTENCE_DENY_LIST);\n\nexport function isSelectPlacementsAttributePersistenceDenied(key: string): boolean {\n return SELECT_PLACEMENTS_ATTRIBUTE_PERSISTENCE_DENY_SET.has(key.toLowerCase());\n}\n\nexport function removeSelectPlacementsAttributePersistenceDeniedAttributes(\n attributes: Record | null | undefined,\n): Record {\n const filteredAttributes: Record = {};\n const sourceAttributes = attributes || {};\n const attributeKeys = Object.keys(sourceAttributes);\n\n for (let i = 0; i < attributeKeys.length; i++) {\n const key = attributeKeys[i];\n if (!isSelectPlacementsAttributePersistenceDenied(key)) {\n filteredAttributes[key] = sourceAttributes[key];\n }\n }\n\n return filteredAttributes;\n}\n","export function isObject(value: unknown): value is Record {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nexport function isString(value: unknown): value is string {\n return typeof value === 'string';\n}\n\nexport function isFunction(value: unknown): value is (...args: Array) => unknown {\n return typeof value === 'function';\n}\n\nexport function isEmpty(value: unknown): boolean {\n if (value == null) return true;\n if (typeof value === 'object') {\n return Object.keys(value as object).length === 0;\n }\n return false;\n}\n\n// Strips the query string from a URL before it is persisted and sent to Rokt,\n// since query params commonly carry PII (emails, tokens, order refs).\n// Returns the input unchanged if it can't be parsed as a URL.\nexport function sanitizeUrl(href: string): string {\n try {\n const url = new URL(href);\n url.search = '';\n return url.toString();\n } catch {\n return href;\n }\n}\n","import { isObject } from './utils';\n\nconst LS_PROBE_KEY = '__rokt_ls_probe__';\n\nexport function isLocalStorageAvailable(): boolean {\n try {\n window.localStorage.setItem(LS_PROBE_KEY, '1');\n window.localStorage.removeItem(LS_PROBE_KEY);\n return true;\n } catch {\n return false;\n }\n}\n\nexport function readJSON(key: string): unknown {\n try {\n const stored = window.localStorage.getItem(key);\n return stored === null ? null : JSON.parse(stored);\n } catch {\n return null;\n }\n}\n\nexport function writeJSON(key: string, value: unknown): boolean {\n try {\n window.localStorage.setItem(key, JSON.stringify(value));\n return true;\n } catch {\n return false;\n }\n}\n\nexport function removeKey(key: string): void {\n try {\n window.localStorage.removeItem(key);\n } catch {\n /* empty */\n }\n}\n\nexport function readNamespacedField(namespaceKey: string, field: string): unknown {\n const blob = readJSON(namespaceKey);\n return isObject(blob) ? blob[field] : undefined;\n}\n\nexport function writeNamespacedField(namespaceKey: string, field: string, value: unknown): boolean {\n const blob = readJSON(namespaceKey);\n const next = isObject(blob) ? { ...blob } : {};\n next[field] = value;\n return writeJSON(namespaceKey, next);\n}\n\nexport function removeNamespacedField(namespaceKey: string, field: string): void {\n const blob = readJSON(namespaceKey);\n if (!isObject(blob) || !(field in blob)) {\n return;\n }\n const next = { ...blob };\n delete next[field];\n if (Object.keys(next).length === 0) {\n removeKey(namespaceKey);\n } else {\n writeJSON(namespaceKey, next);\n }\n}\n","import type { LoggingService } from './Rokt-Kit';\nimport { readNamespacedField, writeNamespacedField, removeNamespacedField, isLocalStorageAvailable } from './storage';\nimport { sanitizeUrl, isObject } from './utils';\n\nconst LS_NAMESPACE_KEY = 'mp-rokt-kit';\nconst LS_PAGE_VIEWS_FIELD = 'pageViews';\nconst LS_UTM_PARAMS_FIELD = 'utmParams';\nexport const PAGE_VIEWS_MAX_COUNT = 25;\n\nconst UTM_KEYS = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content'] as const;\ntype UtmKey = (typeof UTM_KEYS)[number];\nexport type UtmParams = Partial>;\n\nexport interface PageEvent {\n pageUrl: string;\n sourceMessageId: string;\n timestamp: number;\n pageTitle?: string;\n canonicalUrl?: string;\n activeTimeOnSite?: number;\n activeTimeOnPage?: number;\n}\n\nfunction capPageViews(views: PageEvent[]): PageEvent[] {\n return views.slice(-PAGE_VIEWS_MAX_COUNT);\n}\n\nexport function loadPageViews(): PageEvent[] {\n const stored = readNamespacedField(LS_NAMESPACE_KEY, LS_PAGE_VIEWS_FIELD);\n return Array.isArray(stored) ? (stored as PageEvent[]) : [];\n}\n\nexport function writePageViews(pageViews: PageEvent[]): number {\n const views = capPageViews(pageViews);\n for (let i = 0; i < views.length; i++) {\n const toWrite = views.slice(i);\n if (writeNamespacedField(LS_NAMESPACE_KEY, LS_PAGE_VIEWS_FIELD, toWrite)) {\n return toWrite.length;\n }\n }\n return 0;\n}\n\nexport function clearPageViews(): void {\n removeNamespacedField(LS_NAMESPACE_KEY, LS_PAGE_VIEWS_FIELD);\n}\n\nexport function buildPageEvents(pageViews: PageEvent[]): PageEvent[] {\n const views = capPageViews(pageViews);\n return views.map((pageView, index) => {\n const activeTimeOnSite = pageView.activeTimeOnSite;\n const hasActiveTime = activeTimeOnSite !== undefined && Number.isFinite(activeTimeOnSite);\n\n const next = views[index + 1];\n const nextActiveTimeOnSite = next?.activeTimeOnSite;\n const hasNextActiveTimeOnSite = nextActiveTimeOnSite !== undefined && Number.isFinite(nextActiveTimeOnSite);\n\n const diff = hasActiveTime && hasNextActiveTimeOnSite ? nextActiveTimeOnSite - activeTimeOnSite : undefined;\n\n return {\n pageUrl: pageView.pageUrl,\n sourceMessageId: pageView.sourceMessageId,\n timestamp: pageView.timestamp,\n ...(pageView.pageTitle !== undefined ? { pageTitle: pageView.pageTitle } : {}),\n ...(pageView.canonicalUrl !== undefined ? { canonicalUrl: pageView.canonicalUrl } : {}),\n ...(hasActiveTime ? { activeTimeOnSite } : {}),\n ...(diff !== undefined && diff >= 0 ? { activeTimeOnPage: diff } : {}),\n };\n });\n}\n\nexport function captureUtmParams(loggingService: LoggingService | null): void {\n if (readNamespacedField(LS_NAMESPACE_KEY, LS_UTM_PARAMS_FIELD) !== undefined) {\n return;\n }\n const search = new URLSearchParams(window.location.search);\n const params: UtmParams = {};\n for (const key of UTM_KEYS) {\n const value = search.get(key);\n if (value) params[key] = value;\n }\n if (Object.keys(params).length === 0) {\n return;\n }\n const captured = Object.keys(params).join(', ');\n if (!writeNamespacedField(LS_NAMESPACE_KEY, LS_UTM_PARAMS_FIELD, params)) {\n const reason = isLocalStorageAvailable() ? 'quota' : 'ls_unavailable';\n loggingService?.log({\n message: `Rokt Kit: Failed to persist UTM params [reason: ${reason}]`,\n code: 'UTM_CAPTURE_FAILED',\n });\n return;\n }\n loggingService?.log({\n message: `Rokt Kit: Captured UTM params [${captured}]`,\n code: 'UTM_CAPTURE_SUCCESS',\n });\n}\n\nexport function loadUtmParams(): UtmParams | null {\n const stored = readNamespacedField(LS_NAMESPACE_KEY, LS_UTM_PARAMS_FIELD);\n return isObject(stored) ? (stored as UtmParams) : null;\n}\n\nexport function clearUtmParams(): void {\n removeNamespacedField(LS_NAMESPACE_KEY, LS_UTM_PARAMS_FIELD);\n}\n\nexport function readCanonicalUrl(): string | undefined {\n const link = document.querySelector('link[rel=\"canonical\"]');\n const href = link?.href;\n if (!href) {\n return undefined;\n }\n return sanitizeUrl(href);\n}\n","export type RoktLauncherOptions = Record;\n\nexport interface LauncherAttachContext {\n accountId: string;\n launcherOptions: RoktLauncherOptions;\n legacyRoktExtensions: readonly string[];\n}\n\nexport type LauncherLifecycle = 'idle' | 'attached' | 'terminated' | 'recreating';\n\nexport interface LauncherAttachState {\n context: LauncherAttachContext | null;\n lifecycle: LauncherLifecycle;\n recreateInFlight: Promise | null;\n}\n\nexport type AttachLauncher = (context: LauncherAttachContext) => Promise;\n\nexport function createLauncherAttachState(): LauncherAttachState {\n return {\n context: null,\n lifecycle: 'idle',\n recreateInFlight: null,\n };\n}\n\nexport function rememberAttachContext(state: LauncherAttachState, context: LauncherAttachContext): void {\n state.context = {\n accountId: context.accountId,\n launcherOptions: { ...context.launcherOptions },\n legacyRoktExtensions: [...context.legacyRoktExtensions],\n };\n}\n\nexport function markLauncherAttached(state: LauncherAttachState): void {\n state.lifecycle = 'attached';\n}\n\nexport function markLauncherTerminated(state: LauncherAttachState): void {\n if (state.lifecycle === 'idle') {\n return;\n }\n state.lifecycle = 'terminated';\n}\n\nexport function markLauncherAttachFailed(state: LauncherAttachState): void {\n state.lifecycle = 'terminated';\n}\n\nexport function resetLauncherAttachState(state: LauncherAttachState): void {\n state.context = null;\n state.lifecycle = 'idle';\n state.recreateInFlight = null;\n}\n\nexport function recreateIfTerminated(\n state: LauncherAttachState,\n canAttach: boolean,\n attach: AttachLauncher,\n): Promise | undefined {\n if (state.recreateInFlight) {\n return state.recreateInFlight;\n }\n if (state.lifecycle !== 'terminated' || !state.context || !canAttach) {\n return undefined;\n }\n\n state.lifecycle = 'recreating';\n const context = state.context;\n state.recreateInFlight = attach(context).finally(() => {\n state.recreateInFlight = null;\n });\n return state.recreateInFlight;\n}\n","// Copyright 2025 mParticle, Inc.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n// ============================================================\n// Types\n// ============================================================\n\nimport { KitInterface, IMParticleUser, SDKEvent } from '@mparticle/web-sdk/internal';\nimport type { IUserIdentities } from '@mparticle/web-sdk';\n\nimport {\n isSelectPlacementsAttributePersistenceDenied,\n removeSelectPlacementsAttributePersistenceDeniedAttributes,\n} from './selectPlacementsAttributePersistence';\n\nimport {\n PageEvent,\n PAGE_VIEWS_MAX_COUNT,\n buildPageEvents,\n loadPageViews,\n writePageViews,\n clearPageViews,\n readCanonicalUrl,\n captureUtmParams,\n loadUtmParams,\n clearUtmParams,\n} from './pageViewStorage';\nimport { isLocalStorageAvailable } from './storage';\n\nimport { isObject, isString, isEmpty, isFunction, sanitizeUrl } from './utils';\nimport {\n createLauncherAttachState,\n markLauncherAttached,\n markLauncherAttachFailed,\n markLauncherTerminated,\n rememberAttachContext,\n recreateIfTerminated,\n resetLauncherAttachState,\n type LauncherAttachState,\n type RoktLauncherOptions,\n} from './launcherAttachState';\n\ninterface RoktKitSettings {\n accountId: string;\n roktExtensions?: string;\n placementEventMapping?: string;\n placementEventAttributeMapping?: string;\n hashedEmailUserIdentityType?: string;\n onboardingExpProvider?: string;\n loggingUrl?: string;\n errorUrl?: string;\n workspaceIdSyncApiKey?: string;\n}\n\ninterface EventAttributeCondition {\n operator: string;\n attributeValue: string;\n}\n\ninterface PlacementEventRule {\n eventAttributeKey: string;\n conditions: EventAttributeCondition[];\n}\n\ninterface EventAttributeMapping {\n value: string;\n map: string;\n conditions?: EventAttributeCondition[];\n}\n\ninterface PlacementEventMappingEntry {\n jsmap: string;\n value: string;\n}\n\ninterface RoktExtensionEntry {\n value: string;\n}\n\ninterface RoktSelection {\n context?: {\n sessionId?: Promise;\n };\n then?: (callback: (sel: RoktSelection) => void) => Promise;\n catch?: (callback: () => void) => void;\n}\n\ninterface RoktLauncher {\n selectPlacements(options: Record): RoktSelection | Promise;\n hashAttributes(attributes: Record): Promise>;\n use(extensionName: string): Promise;\n terminate(): Promise;\n}\n\ninterface RoktGlobal {\n createLauncher(options: RoktLauncherOptions): Promise;\n createLocalLauncher(options: RoktLauncherOptions): RoktLauncher;\n currentLauncher?: RoktLauncher;\n setExtensionData(data: Record): void;\n}\n\n// FilteredUser is the IMParticleUser shape we receive after kit filtering.\n// `getMPID` and `getUserIdentities` are inherited from the SDK's `User` base type.\ntype FilteredUser = IMParticleUser;\n\n// TODO: Replace with `IIdentitySearchResult` from `@mparticle/web-sdk` once\n// a version that exports it is published (currently on a feature branch in\n// mParticle/mparticle-web-sdk PR #1255). The shape below is intentionally\n// structurally identical so the swap is a one-line import change.\ninterface WorkspaceIdSyncResult {\n httpCode: number;\n body?: {\n context?: string | null;\n mpid?: string;\n matched_identities?: Record;\n is_ephemeral?: boolean;\n is_logged_in?: boolean;\n };\n}\n\n// TODO: Replace with `IdentitySearchCallback`-compatible reference from\n// `@mparticle/web-sdk` once published (mirrors `SDKIdentityApi.search`).\ntype WorkspaceIdSyncSearcher = (\n apiKey: string,\n knownIdentities: IUserIdentities,\n callback: (result: WorkspaceIdSyncResult) => void,\n) => void;\n\ninterface KitFilters {\n userAttributeFilters?: string[];\n filterUserAttributes?: (attributes: Record, filters?: string[]) => Record;\n filteredUser?: FilteredUser | null;\n}\n\ninterface RoktManager {\n attachKit(kit: RoktKit): void | Promise;\n flushOnShoppableAdsReadyMessageQueue?(kit: RoktKit): void;\n filters?: KitFilters;\n domain?: string;\n launcherOptions?: Record;\n getLocalSessionAttributes?(): Record;\n setLocalSessionAttribute?(key: string, value: unknown): void;\n}\n\ninterface MParticleInstance {\n setIntegrationAttribute(moduleId: number, attrs: Record): void;\n}\n\ninterface OptimizelyState {\n getActiveExperimentIds(): string[];\n getVariationMap(): Record;\n}\n\ninterface OptimizelyGlobal {\n get(key: 'state'): OptimizelyState;\n}\n\n// Our view of the mParticle global with Rokt-specific extensions.\n// We access window.mParticle via an explicit cast (see `mp()` helper below)\n// rather than augmenting Window to avoid conflicts with @mparticle/web-sdk declarations.\ninterface MParticleExtended {\n Rokt: RoktManager;\n addForwarder(config: ForwarderRegistration): void;\n getVersion(): string;\n generateHash(value: string): string | number;\n logEvent(name: string, type: number, attrs?: Record): void;\n EventType: { Other: number };\n getInstance(): MParticleInstance;\n getDeviceId?(): string;\n sessionManager?: { getSession?(): string; getSessionId?(): string };\n _getActiveForwarders(): Array<{ name: string }>;\n config?: { isLocalLauncherEnabled?: boolean; isLoggingEnabled?: boolean };\n captureTiming?(metricName: string): void;\n forwarder?: RoktKit;\n loggedEvents?: Array>;\n _registerErrorReportingService?(service: ErrorReportingService): void;\n _registerLoggingService?(service: LoggingService): void;\n Identity?: { search?: WorkspaceIdSyncSearcher };\n}\n\ninterface TestHelpers {\n generateLauncherScript: (domain: string | undefined, extensions: string[]) => string;\n generateThankYouElementScript: (domain: string | undefined) => string;\n extractRoktExtensionConfig: (settingsString?: string) => RoktExtensionConfig;\n hashEventMessage: (messageType: number, eventType: number, eventName: string) => string | number;\n parseSettingsString: (settingsString?: string) => T[];\n generateMappedEventLookup: (placementEventMapping: PlacementEventMappingEntry[]) => Record;\n generateMappedEventAttributeLookup: (mapping: EventAttributeMapping[]) => Record;\n sendAdBlockMeasurementSignals: (domain: string | undefined, version: string | null) => void;\n createAutoRemovedIframe: (src: string) => void;\n djb2: (str: string) => number;\n setAllowedOriginHashes: (hashes: number[]) => void;\n ReportingTransport: typeof ReportingTransport;\n ErrorReportingService: typeof ErrorReportingService;\n LoggingService: typeof LoggingService;\n RateLimiter: typeof RateLimiter;\n ErrorCodes: typeof ErrorCodes;\n WSDKErrorSeverity: typeof WSDKErrorSeverity;\n resetLauncherAttachState: () => void;\n}\n\ninterface ForwarderRegistration {\n name: string;\n constructor: new () => RoktKit;\n getId: () => number;\n}\n\ninterface ReportingConfig {\n loggingUrl?: string;\n errorUrl?: string;\n integrationDomain?: string;\n isLoggingEnabled: boolean;\n}\n\ninterface ErrorReport {\n message: string;\n code?: string;\n severity?: string;\n stackTrace?: string;\n}\n\n// A log-delivery failure. statusCode is set when the request reached the server\n// and returned a non-2xx status (server-side); it is absent for network-level\n// failures such as ad-blockers, offline, or CORS rejections (client-side).\ninterface DeliveryError extends Error {\n statusCode?: number;\n}\n\ninterface LogEntry {\n message: string;\n code?: string;\n}\n\ninterface RoktExtensionConfig {\n roktExtensionsQueryParams: string[];\n legacyRoktExtensions: string[];\n loadThankYouElement: boolean;\n}\n\ndeclare global {\n interface Window {\n Rokt?: RoktGlobal;\n __rokt_li_guid__?: string;\n optimizely?: OptimizelyGlobal;\n // mParticle is declared as any to avoid conflicts with @mparticle/web-sdk type declarations.\n // We use the typed mp() accessor for all internal accesses.\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n mParticle: any;\n }\n}\n\n// ============================================================\n// Module-level constants\n// ============================================================\n\nconst name = 'Rokt';\nconst moduleId = 181;\nconst EVENT_NAME_SELECT_PLACEMENTS = 'selectPlacements';\nconst ADBLOCK_CONTROL_DOMAIN = 'apps.roktecommerce.com';\nconst INIT_LOG_SAMPLING_RATE = 0.1;\nconst ROKT_THANK_YOU_JOURNEY_EXTENSION = 'ThankYouPageJourney';\nconst ROKT_INTEGRATION_SCRIPT_ID = 'rokt-launcher';\nconst ROKT_THANK_YOU_ELEMENT_SCRIPT_ID = 'rokt-thank-you-element';\nconst USER_IDENTIFIED_IN_WORKSPACE_KEY = 'userIdentifiedInWorkspace';\n\nconst MESSAGE_TYPE_PAGE_VIEW = 3; // mParticle MessageType.PageView\nconst MESSAGE_TYPE_SESSION_END = 2; // mParticle MessageType.SessionEnd\nconst PAGE_EVENTS_KEY = 'page_events';\nconst PAGE_VIEW_ATTRIBUTES_KEY = 'page_view_attributes';\nconst MPARTICLE_SESSION_ID_KEY = 'mparticle_session_id';\nconst MPARTICLE_DEVICE_ID_KEY = 'mparticle_device_id';\n\n// Bound on how long selectPlacements will wait for an in-flight Workspace\n// IDSync search before proceeding without the userIdentifiedInWorkspace flag.\n// Long enough to cover the typical /v1/search round-trip (~50ms); short enough that a\n// stalled search never blocks placement rendering on a thank-you page.\nconst WORKSPACE_SEARCH_SELECT_TIMEOUT_MS = 500;\n\n// ============================================================\n// Reporting service constants\n// ============================================================\n\nconst ErrorCodes = {\n UNKNOWN_ERROR: 'UNKNOWN_ERROR',\n UNHANDLED_EXCEPTION: 'UNHANDLED_EXCEPTION',\n IDENTITY_REQUEST: 'IDENTITY_REQUEST',\n LOG_DELIVERY_FAILURE: 'LOG_DELIVERY_FAILURE',\n} as const;\n\nconst WSDKErrorSeverity = {\n ERROR: 'ERROR',\n INFO: 'INFO',\n WARNING: 'WARNING',\n} as const;\n\nconst DEFAULT_ROKT_DOMAIN = 'apps.rokt-api.com';\nconst LOGGING_ENDPOINT = '/v1/log';\nconst ERROR_ENDPOINT = '/v1/errors';\nconst RATE_LIMIT_PER_SEVERITY = 10;\n\n// ============================================================\n// Helper: typed accessor for window.mParticle\n// We use an explicit cast here to avoid conflicts with @mparticle/web-sdk\n// type declarations while still providing full type safety for our usages.\n// ============================================================\n\nfunction mp(): MParticleExtended {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n return (window as any).mParticle as MParticleExtended;\n}\n\n// ============================================================\n// Module-level utility functions\n// ============================================================\n\nfunction generateLauncherScript(domain: string | undefined, extensions: string[]): string {\n const launcherPath = '/wsdk/integrations/launcher.js';\n const baseUrl = [generateBaseUrl(domain), launcherPath].join('');\n\n if (!extensions || extensions.length === 0) {\n return baseUrl;\n }\n return baseUrl + '?extensions=' + extensions.join(',');\n}\n\nfunction generateThankYouElementScript(domain: string | undefined) {\n const thankYouElementPath = '/rokt-elements/rokt-element-thank-you.js';\n return [generateBaseUrl(domain), thankYouElementPath].join('');\n}\n\nfunction generateBaseUrl(domain: string | undefined) {\n const resolvedDomain = typeof domain !== 'undefined' ? domain : DEFAULT_ROKT_DOMAIN;\n\n if (resolvedDomain.includes('://')) {\n return resolvedDomain.replace(/\\/+$/, '');\n }\n\n const protocol = 'https://';\n\n return [protocol, resolvedDomain].join('');\n}\n\nfunction generateReportingUrl(configuredUrl: string | undefined, domain: string | undefined, endpoint: string): string {\n if (configuredUrl) {\n if (configuredUrl.startsWith('http://') || configuredUrl.startsWith('https://')) {\n return configuredUrl;\n }\n return 'https://' + configuredUrl;\n }\n\n const hasNonHttpScheme = domain?.includes('://') && !/^https?:\\/\\//i.test(domain);\n const reportingDomain = hasNonHttpScheme ? undefined : domain;\n\n return generateBaseUrl(reportingDomain) + endpoint;\n}\n\nfunction loadRoktScript(\n scriptId: string,\n source: string,\n handlers?: { onLoad?: () => void; onError?: (e: Event | string) => void },\n): void {\n if (document.getElementById(scriptId)) return; // resolves the preexisting script issue\n\n const target = document.head || document.body;\n const script = document.createElement('script');\n script.id = scriptId;\n script.type = 'text/javascript';\n script.src = source;\n script.async = true;\n script.crossOrigin = 'anonymous';\n (script as HTMLScriptElement & { fetchPriority: string }).fetchPriority = 'high';\n if (handlers?.onLoad) script.onload = handlers.onLoad;\n if (handlers?.onError) script.onerror = handlers.onError;\n target.appendChild(script);\n}\n\nfunction parseSettingsString(settingsString?: string): T[] {\n if (!settingsString) {\n return [];\n }\n try {\n return JSON.parse(settingsString.replace(/"/g, '\"')) as T[];\n } catch (_error) {\n console.error('Settings string contains invalid JSON');\n }\n return [];\n}\n\nfunction extractRoktExtensionConfig(settingsString?: string): RoktExtensionConfig {\n const settings = settingsString ? parseSettingsString(settingsString) : [];\n const roktExtensionsQueryParams: string[] = [];\n const legacyRoktExtensions: string[] = [];\n let loadThankYouElement = false;\n\n for (let i = 0; i < settings.length; i++) {\n const extensionName = settings[i].value;\n if (extensionName === 'thank-you-journey') {\n loadThankYouElement = true;\n legacyRoktExtensions.push(ROKT_THANK_YOU_JOURNEY_EXTENSION);\n } else {\n roktExtensionsQueryParams.push(extensionName);\n }\n }\n\n return {\n roktExtensionsQueryParams,\n legacyRoktExtensions,\n loadThankYouElement,\n };\n}\n\nasync function registerLegacyExtensions(legacyExtensions: string[], launcher: RoktLauncher | null) {\n const extensions: Promise[] = [];\n if (launcher) {\n for (const extension of legacyExtensions) {\n extensions.push(launcher.use(extension));\n }\n }\n\n return Promise.all(extensions);\n}\n\nfunction generateMappedEventLookup(placementEventMapping: PlacementEventMappingEntry[]): Record {\n if (!placementEventMapping) {\n return {};\n }\n\n const mappedEvents: Record = {};\n for (let i = 0; i < placementEventMapping.length; i++) {\n const mapping = placementEventMapping[i];\n mappedEvents[mapping.jsmap] = mapping.value;\n }\n return mappedEvents;\n}\n\nfunction generateMappedEventAttributeLookup(\n placementEventAttributeMapping: EventAttributeMapping[],\n): Record {\n const mappedAttributeKeys: Record = {};\n if (!Array.isArray(placementEventAttributeMapping)) {\n return mappedAttributeKeys;\n }\n for (let i = 0; i < placementEventAttributeMapping.length; i++) {\n const mapping = placementEventAttributeMapping[i];\n if (!mapping || !isString(mapping.value) || !isString(mapping.map)) {\n continue;\n }\n\n const mappedAttributeKey = mapping.value;\n const eventAttributeKey = mapping.map;\n\n if (!mappedAttributeKeys[mappedAttributeKey]) {\n mappedAttributeKeys[mappedAttributeKey] = [];\n }\n\n mappedAttributeKeys[mappedAttributeKey].push({\n eventAttributeKey: eventAttributeKey,\n conditions: Array.isArray(mapping.conditions) ? mapping.conditions : [],\n });\n }\n return mappedAttributeKeys;\n}\n\nfunction hashEventMessage(messageType: number, eventType: number, eventName: string): string | number {\n return mp().generateHash([messageType, eventType, eventName].join(''));\n}\n\nfunction generateIntegrationName(customIntegrationName?: string): string {\n const coreSdkVersion = mp().getVersion();\n const kitVersion = process.env.PACKAGE_VERSION;\n let integrationName = 'mParticle_' + 'wsdkv_' + coreSdkVersion + '_kitv_' + kitVersion;\n\n if (customIntegrationName) {\n integrationName += '_' + customIntegrationName;\n }\n return integrationName;\n}\n\nfunction djb2(str: string): number {\n let hash = 5381;\n for (let i = 0; i < str.length; i++) {\n hash = (hash << 5) + hash + str.charCodeAt(i);\n hash = hash & hash;\n }\n return hash;\n}\n\nfunction createAutoRemovedIframe(src: string): void {\n const iframe = document.createElement('iframe');\n iframe.style.display = 'none';\n iframe.setAttribute('sandbox', 'allow-scripts allow-same-origin');\n iframe.src = src;\n iframe.onload = function () {\n iframe.onload = null;\n if (iframe.parentNode) {\n iframe.parentNode.removeChild(iframe);\n }\n };\n const target = document.body || document.head;\n if (target) {\n target.appendChild(iframe);\n }\n}\n\nfunction sendAdBlockMeasurementSignals(domain: string | undefined, version: string | null): void {\n const originHash = djb2(window.location.origin);\n const allowedOriginHashes = RoktKit._allowedOriginHashes;\n if (allowedOriginHashes.indexOf(originHash) === -1) {\n return;\n }\n\n if (Math.random() >= INIT_LOG_SAMPLING_RATE) {\n return;\n }\n\n const guid = window.__rokt_li_guid__;\n if (!guid) {\n return;\n }\n\n if (domain && domain.includes('://') && !/^https:\\/\\//i.test(domain)) {\n return;\n }\n\n const pageUrl = window.location.href.split('?')[0].split('#')[0];\n const params =\n 'version=' +\n encodeURIComponent(version ?? '') +\n '&launcherInstanceGuid=' +\n encodeURIComponent(guid) +\n '&pageUrl=' +\n encodeURIComponent(pageUrl);\n\n const existingBaseUrl = domain ? generateBaseUrl(domain) : 'https://apps.rokt.com';\n createAutoRemovedIframe(existingBaseUrl + '/v1/wsdk-init/index.html?' + params);\n\n createAutoRemovedIframe(\n 'https://' + ADBLOCK_CONTROL_DOMAIN + '/v1/wsdk-init/index.html?' + params + '&isControl=true',\n );\n}\n\n// ============================================================\n// Reporting helpers\n// ============================================================\n\nfunction _isDebugModeEnabled(): boolean {\n return typeof window !== 'undefined' && !!window.location?.search?.toLowerCase().includes('mp_enable_logging=true');\n}\n\nfunction _getReportingUrl(): string | undefined {\n return typeof window !== 'undefined' ? window.location?.href : undefined;\n}\n\nfunction _getUserAgent(): string | undefined {\n return typeof window !== 'undefined' ? window.navigator?.userAgent : undefined;\n}\n\nclass RateLimiter {\n private _logCount: Record = {};\n\n incrementAndCheck(severity: string): boolean {\n const count = this._logCount[severity] || 0;\n const newCount = count + 1;\n this._logCount[severity] = newCount;\n return newCount > RATE_LIMIT_PER_SEVERITY;\n }\n}\n\nclass ReportingTransport {\n private _isEnabled: boolean;\n private _integrationName: string;\n private _launcherInstanceGuid: string | undefined;\n private _accountId: string | null;\n private _rateLimiter: RateLimiter;\n private readonly _reporter = 'mp-wsdk';\n\n constructor(\n config: ReportingConfig,\n integrationName: string | null | undefined,\n launcherInstanceGuid: string | undefined,\n accountId: string | null | undefined,\n rateLimiter?: RateLimiter,\n ) {\n const isLoggingEnabled = config.isLoggingEnabled;\n this._integrationName = integrationName || '';\n this._launcherInstanceGuid = launcherInstanceGuid;\n this._accountId = accountId || null;\n this._rateLimiter = rateLimiter || new RateLimiter();\n this._isEnabled = _isDebugModeEnabled() || isLoggingEnabled;\n }\n\n send(\n url: string,\n severity: string,\n msg: string,\n code?: string,\n stackTrace?: string,\n onError?: (error: DeliveryError) => void,\n ): void {\n if (!this._isEnabled || this._rateLimiter.incrementAndCheck(severity)) {\n return;\n }\n\n try {\n const logRequest = {\n additionalInformation: {\n message: msg,\n version: this._integrationName,\n },\n severity,\n code: code || ErrorCodes.UNKNOWN_ERROR,\n url: _getReportingUrl(),\n deviceInfo: _getUserAgent(),\n stackTrace,\n reporter: this._reporter,\n integration: this._integrationName,\n };\n\n const headers: Record = {\n Accept: 'text/plain;charset=UTF-8',\n 'Content-Type': 'application/json',\n 'rokt-launcher-version': this._integrationName,\n 'rokt-wsdk-version': 'joint',\n };\n\n if (this._launcherInstanceGuid) {\n headers['rokt-launcher-instance-guid'] = this._launcherInstanceGuid;\n }\n if (this._accountId) {\n headers['rokt-account-id'] = this._accountId;\n }\n\n fetch(url, {\n method: 'POST',\n headers,\n body: JSON.stringify(logRequest),\n })\n .then((response: Response) => {\n // fetch only rejects on network failures; an HTTP 5xx resolves with\n // ok === false. Surface server-side failures so they are not swallowed.\n if (!response.ok) {\n const serverError: DeliveryError = new Error('HTTP ' + response.status + ' from log endpoint');\n serverError.statusCode = response.status;\n throw serverError;\n }\n })\n .catch((error: DeliveryError) => {\n console.error('ReportingTransport: Failed to send log', error);\n if (onError) onError(error);\n });\n } catch (error) {\n console.error('ReportingTransport: Failed to send log', error);\n if (onError) onError(error as DeliveryError);\n }\n }\n}\n\nclass ErrorReportingService {\n private _transport: ReportingTransport;\n private _errorUrl: string;\n\n constructor(\n config: ReportingConfig,\n integrationName: string | null | undefined,\n launcherInstanceGuid?: string,\n accountId?: string | null,\n rateLimiter?: RateLimiter,\n ) {\n this._transport = new ReportingTransport(config, integrationName, launcherInstanceGuid, accountId, rateLimiter);\n this._errorUrl = generateReportingUrl(config?.errorUrl, config?.integrationDomain, ERROR_ENDPOINT);\n }\n\n report(error: ErrorReport | null | undefined): void {\n if (!error) return;\n const severity = error.severity || WSDKErrorSeverity.ERROR;\n this._transport.send(this._errorUrl, severity, error.message, error.code, error.stackTrace);\n }\n}\n\nclass LoggingService {\n private _transport: ReportingTransport;\n private _loggingUrl: string;\n private _errorReportingService: { report: (e: ErrorReport) => void };\n\n constructor(\n config: ReportingConfig,\n errorReportingService: { report: (e: ErrorReport) => void },\n integrationName: string | null | undefined,\n launcherInstanceGuid?: string,\n accountId?: string | null,\n rateLimiter?: RateLimiter,\n ) {\n this._transport = new ReportingTransport(config, integrationName, launcherInstanceGuid, accountId, rateLimiter);\n this._loggingUrl = generateReportingUrl(config?.loggingUrl, config?.integrationDomain, LOGGING_ENDPOINT);\n this._errorReportingService = errorReportingService;\n }\n\n log(entry: LogEntry | null | undefined): void {\n if (!entry) return;\n this._transport.send(\n this._loggingUrl,\n WSDKErrorSeverity.INFO,\n entry.message,\n entry.code,\n undefined,\n (error: DeliveryError) => {\n if (this._errorReportingService) {\n // A failed log POST is not itself an SDK error. Network-level failures\n // (ad-blockers, offline, CORS) are client-side noise and reported as a\n // WARNING; only a server-side non-2xx response stays at ERROR severity.\n const isServerSide = typeof error.statusCode === 'number';\n this._errorReportingService.report({\n message: 'LoggingService: Failed to send log: ' + error.message,\n code: ErrorCodes.LOG_DELIVERY_FAILURE,\n severity: isServerSide ? WSDKErrorSeverity.ERROR : WSDKErrorSeverity.WARNING,\n });\n }\n },\n );\n }\n}\n\nfunction buildPageEvent(event: SDKEvent): PageEvent {\n const pageUrl = sanitizeUrl(window.location.href);\n const pageTitle = event.EventAttributes?.title || document.title;\n const canonicalUrl = readCanonicalUrl();\n const activeTimeOnSite = event.ActiveTimeOnSite;\n\n return {\n pageUrl,\n sourceMessageId: event.SourceMessageId,\n timestamp: event.Timestamp,\n ...(pageTitle ? { pageTitle } : {}),\n ...(canonicalUrl !== undefined ? { canonicalUrl } : {}),\n ...(Number.isFinite(activeTimeOnSite) ? { activeTimeOnSite } : {}),\n };\n}\n\n// ============================================================\n// RoktKit class\n// ============================================================\n\nclass RoktKit implements KitInterface {\n // Static field for allowed origin hashes (mutable by testHelpers)\n public static _allowedOriginHashes: number[] = [-553112570, 549508659];\n\n private static readonly PERFORMANCE_MARKS = {\n RoktScriptAppended: 'mp:RoktScriptAppended',\n };\n\n private static readonly EMAIL_SHA256_KEY = 'emailsha256';\n\n // Public fields (accessed by tests and the mParticle framework)\n public name = name;\n public id = moduleId;\n public moduleId = moduleId;\n public isInitialized = false;\n public launcher: RoktLauncher | null = null;\n public filters: KitFilters = {};\n public userAttributes: Record = {};\n // Flag set by the Workspace IDSync flow on a 200 response. Stored on the\n // kit instance and merged into placement attributes inside selectPlacements.\n public userIdentifiedInWorkspace = false;\n public testHelpers: TestHelpers | null = null;\n public placementEventMappingLookup: Record = {};\n public placementEventAttributeMappingLookup: Record = {};\n public integrationName: string | null = null;\n public domain?: string;\n public errorReportingService: ErrorReportingService | null = null;\n public loggingService: LoggingService | null = null;\n\n // Private fields\n private _mappedEmailSha256Key?: string;\n private _onboardingExpProvider?: string;\n private _thankYouElementOnLoadCallback: (() => void) | null = null;\n private _isThankYouElementLoaded = false;\n private _workspaceIdSyncApiKey?: string;\n\n // Held during a search dispatch so the next selectPlacements call;\n // can wait for the HTTP response before reading userIdentifiedInWorkspace;\n // — otherwise the first placement call ships without the flag.\n private _workspaceSearchInFlightPromise: Promise | null = null;\n // Stable serialization of the identifier set sent in the most recent\n // successful search dispatch. If a subsequent identification arrives with\n // an identical set, we skip the network call (the flag is still correct\n // from the prior search). Keyed over the full IUserIdentities map — not\n // just email — so partners passing hashed email through `other`/`other2-10`\n // or any other identifier benefit from the same dedupe. Cleared on logout\n // so a re-login re-evaluates fresh.\n private _workspaceLastSearchedIdentitiesKey?: string;\n\n private _launcherAttachState: LauncherAttachState = createLauncherAttachState();\n\n // ---- Private helpers ----\n\n private getEventAttributeValue(event: SDKEvent, eventAttributeKey: string): unknown {\n const attributes = event && event.EventAttributes;\n if (!attributes) {\n return null;\n }\n\n if (typeof attributes[eventAttributeKey] === 'undefined') {\n return null;\n }\n\n return attributes[eventAttributeKey];\n }\n\n private doesEventAttributeConditionMatch(condition: EventAttributeCondition, actualValue: unknown): boolean {\n if (!condition || !isString(condition.operator)) {\n return false;\n }\n\n const operator = condition.operator.toLowerCase();\n const expectedValue = condition.attributeValue;\n\n if (operator === 'exists') {\n return actualValue !== null;\n }\n\n if (actualValue == null) {\n return false;\n }\n\n if (operator === 'equals') {\n return String(actualValue) === String(expectedValue);\n }\n\n if (operator === 'contains') {\n return String(actualValue).indexOf(String(expectedValue)) !== -1;\n }\n\n return false;\n }\n\n private doesEventMatchRule(event: SDKEvent, rule: PlacementEventRule): boolean {\n if (!rule || !isString(rule.eventAttributeKey)) {\n return false;\n }\n\n const conditions = rule.conditions;\n if (!Array.isArray(conditions)) {\n return false;\n }\n\n const actualValue = this.getEventAttributeValue(event, rule.eventAttributeKey);\n\n if (conditions.length === 0) {\n return actualValue !== null;\n }\n for (let i = 0; i < conditions.length; i++) {\n if (!this.doesEventAttributeConditionMatch(conditions[i], actualValue)) {\n return false;\n }\n }\n\n return true;\n }\n\n private applyPlacementEventAttributeMapping(event: SDKEvent): void {\n const mappedAttributeKeys = Object.keys(this.placementEventAttributeMappingLookup);\n for (let i = 0; i < mappedAttributeKeys.length; i++) {\n const mappedAttributeKey = mappedAttributeKeys[i];\n const rulesForMappedAttributeKey = this.placementEventAttributeMappingLookup[mappedAttributeKey];\n if (isEmpty(rulesForMappedAttributeKey)) {\n continue;\n }\n\n // Require ALL rules for the same key to match (AND).\n let allMatch = true;\n for (let j = 0; j < rulesForMappedAttributeKey.length; j++) {\n if (!this.doesEventMatchRule(event, rulesForMappedAttributeKey[j])) {\n allMatch = false;\n break;\n }\n }\n if (!allMatch) {\n continue;\n }\n\n mp().Rokt.setLocalSessionAttribute?.(mappedAttributeKey, true);\n }\n }\n\n private capturePageView(event: SDKEvent): void {\n let pageUrl: string | undefined;\n\n try {\n pageUrl = sanitizeUrl(window.location.href);\n\n const pageViews = loadPageViews();\n const pageView = buildPageEvent(event);\n pageViews.push(pageView);\n\n const requested = Math.min(pageViews.length, PAGE_VIEWS_MAX_COUNT);\n const stored = writePageViews(pageViews);\n if (stored === 0) {\n const reason = isLocalStorageAvailable() ? 'quota' : 'ls_unavailable';\n this.loggingService?.log({\n message: `Rokt Kit: Failed to persist page view for ${pageUrl} [reason: ${reason}]`,\n code: 'PAGE_VIEW_CAPTURE_FAILED',\n });\n } else if (stored < requested) {\n this.loggingService?.log({\n message: `Rokt Kit: Page view storage reduced from ${requested} to ${stored} record(s) under quota pressure [reason: quota_eviction]`,\n code: 'PAGE_VIEW_QUOTA_EVICTION',\n });\n }\n } catch (err) {\n const reason = isLocalStorageAvailable() ? 'exception' : 'ls_unavailable';\n const errMessage = err instanceof Error ? err.message : String(err);\n this.loggingService?.log({\n message: `Rokt Kit: Failed to capture page view for ${pageUrl}: ${errMessage} [reason: ${reason}]`,\n code: 'PAGE_VIEW_CAPTURE_FAILED',\n });\n }\n }\n\n private isLauncherReadyToAttach(): boolean {\n return !!window.Rokt && isFunction(window.Rokt.createLauncher);\n }\n\n /**\n * Returns the user identities from the filtered user, if any.\n */\n private returnUserIdentities(filteredUser: FilteredUser | null | undefined): Record {\n if (!filteredUser || !filteredUser.getUserIdentities) {\n return {};\n }\n\n const userIdentities: IUserIdentities = filteredUser.getUserIdentities().userIdentities;\n\n return this.replaceOtherIdentityWithEmailsha256(userIdentities);\n }\n\n private returnLocalSessionAttributes(): Record {\n if (!mp().Rokt || typeof mp().Rokt.getLocalSessionAttributes !== 'function') {\n return {};\n }\n return mp().Rokt.getLocalSessionAttributes!();\n }\n\n private replaceOtherIdentityWithEmailsha256(userIdentities: IUserIdentities): Record {\n const newUserIdentities: Record = { ...(userIdentities || {}) };\n const key = this._mappedEmailSha256Key;\n if (key && userIdentities[key as keyof IUserIdentities]) {\n newUserIdentities[RoktKit.EMAIL_SHA256_KEY] = userIdentities[key as keyof IUserIdentities] as string;\n }\n if (key) {\n delete newUserIdentities[key];\n }\n\n return newUserIdentities;\n }\n\n private logSelectPlacementsEvent(attributes: unknown): void {\n if (!window.mParticle || typeof mp().logEvent !== 'function') {\n return;\n }\n\n if (!isObject(attributes)) {\n return;\n }\n\n const EVENT_TYPE_OTHER = mp().EventType.Other;\n\n mp().logEvent(EVENT_NAME_SELECT_PLACEMENTS, EVENT_TYPE_OTHER, attributes as Record);\n }\n\n private setRoktSessionId(sessionId: string): void {\n if (!sessionId || typeof sessionId !== 'string') {\n return;\n }\n try {\n const mpInstance = mp().getInstance();\n if (mpInstance && isFunction(mpInstance.setIntegrationAttribute)) {\n mpInstance.setIntegrationAttribute(moduleId, {\n roktSessionId: sessionId,\n });\n }\n } catch (_e) {\n // Best effort — never let this break the partner page\n }\n }\n\n private readMpSessionId(): string | undefined {\n // The public mParticle.sessionManager facade exposes only getSession(), which already returns\n // the session id. getSessionId() lives on the internal _SessionManager and has never been\n // re-exported, so prefer it if a future core adds it and fall back to getSession() until then.\n const sessionManager = mp()?.sessionManager;\n const readSessionId = sessionManager?.getSessionId ?? sessionManager?.getSession;\n if (!isFunction(readSessionId)) {\n return undefined;\n }\n\n return readSessionId.call(sessionManager) || undefined;\n }\n\n private readMpDeviceId(): string | undefined {\n // The device application stamp (`das`) outlives the session id: core clears the session on\n // timeout, cross-tab rotation and endSession(), but never the device id, which lives in\n // localStorage/cookie for cookieExpiration days (365 by default) and survives login/logout.\n // Read it per call anyway — a partner can reassign it at any time via setDeviceId().\n return mp()?.getDeviceId?.() || undefined;\n }\n\n private attachLauncher(\n accountId: string,\n launcherOptions: RoktLauncherOptions,\n legacyRoktExtensions: readonly string[] = [],\n ): Promise {\n rememberAttachContext(this._launcherAttachState, {\n accountId,\n launcherOptions: launcherOptions || {},\n legacyRoktExtensions,\n });\n\n const options: RoktLauncherOptions = {\n accountId,\n ...(launcherOptions || {}),\n };\n\n let launcherPromise: Promise;\n if (this.isPartnerInLocalLauncherTestGroup()) {\n launcherPromise = Promise.resolve(window.Rokt!.createLocalLauncher(options));\n } else {\n launcherPromise = window.Rokt!.createLauncher(options);\n }\n\n return launcherPromise\n .then(async (launcher) => {\n await registerLegacyExtensions([...legacyRoktExtensions], launcher);\n this.initRoktLauncher(launcher);\n })\n .catch((err: unknown) => {\n markLauncherAttachFailed(this._launcherAttachState);\n console.error('Error creating Rokt launcher:', err);\n });\n }\n\n private recreateLauncherIfTerminated(): Promise | undefined {\n return recreateIfTerminated(this._launcherAttachState, this.isLauncherReadyToAttach(), (context) =>\n this.attachLauncher(context.accountId, context.launcherOptions, context.legacyRoktExtensions),\n );\n }\n\n private initRoktLauncher(launcher: RoktLauncher): void {\n // Assign the launcher to a global variable for later access\n if (window.Rokt) {\n window.Rokt.currentLauncher = launcher;\n }\n // Locally cache the launcher and filters\n this.launcher = launcher;\n markLauncherAttached(this._launcherAttachState);\n\n const roktFilters = mp().Rokt?.filters;\n\n if (!roktFilters) {\n console.warn('Rokt Kit: No filters have been set.');\n } else {\n this.filters = roktFilters;\n if (!roktFilters.filteredUser) {\n console.warn('Rokt Kit: No filtered user has been set.');\n } else {\n this._workspaceSearchInFlightPromise = this.search(roktFilters.filteredUser);\n }\n }\n\n // Kit must be initialized before attaching to the Rokt manager\n this.isInitialized = true;\n\n sendAdBlockMeasurementSignals(this.domain, this.integrationName);\n\n // Attaches the kit to the Rokt manager\n mp().Rokt.attachKit(this);\n }\n\n private fetchOptimizely(): Record {\n const forwarders = mp()\n ._getActiveForwarders()\n .filter((forwarder) => forwarder.name === 'Optimizely');\n\n try {\n if (forwarders.length > 0 && window.optimizely) {\n const optimizelyState = window.optimizely.get('state');\n if (!optimizelyState || !optimizelyState.getActiveExperimentIds) {\n return {};\n }\n const activeExperimentIds = optimizelyState.getActiveExperimentIds();\n const activeExperiments = activeExperimentIds.reduce((acc: Record, expId: string) => {\n acc['rokt.custom.optimizely.experiment.' + expId + '.variationId'] =\n optimizelyState.getVariationMap()[expId].id;\n return acc;\n }, {});\n return activeExperiments;\n }\n } catch (error) {\n console.error('Error fetching Optimizely attributes:', error);\n }\n return {};\n }\n\n private isKitReady(): boolean {\n return !!(this.isInitialized && this.launcher);\n }\n\n // When the partner has opted out of targeting (noTargeting launcher option),\n // the kit must not collect behavioral targeting signals such as page views.\n private isTargetingDisabled(): boolean {\n return (mp().Rokt?.launcherOptions as Record | undefined)?.noTargeting === true;\n }\n\n private isPartnerInLocalLauncherTestGroup(): boolean {\n return !!(mp().config && mp().config!.isLocalLauncherEnabled && this.isAssignedToSampleGroup());\n }\n\n private isAssignedToSampleGroup(): boolean {\n const LOCAL_LAUNCHER_TEST_GROUP_THRESHOLD = 0.5;\n return Math.random() > LOCAL_LAUNCHER_TEST_GROUP_THRESHOLD;\n }\n\n private captureTiming(metricName: string): void {\n if (window && mp() && mp().captureTiming && metricName) {\n mp().captureTiming!(metricName);\n }\n }\n\n // ---- Public methods (mParticle Kit Callbacks) ----\n\n /**\n * Initializes the Rokt forwarder with settings from the mParticle server.\n */\n public init(\n settings: Record,\n _service: unknown,\n testMode: boolean,\n _trackerId: unknown,\n filteredUserAttributes?: Record,\n ): string {\n const kitSettings = settings as unknown as RoktKitSettings;\n const accountId = kitSettings.accountId;\n this.userAttributes = removeSelectPlacementsAttributePersistenceDeniedAttributes(filteredUserAttributes);\n this._onboardingExpProvider = kitSettings.onboardingExpProvider;\n\n const placementEventMapping = parseSettingsString(kitSettings.placementEventMapping);\n this.placementEventMappingLookup = generateMappedEventLookup(placementEventMapping);\n\n const placementEventAttributeMapping = parseSettingsString(\n kitSettings.placementEventAttributeMapping,\n );\n this.placementEventAttributeMappingLookup = generateMappedEventAttributeLookup(placementEventAttributeMapping);\n\n // Set dynamic OTHER_IDENTITY based on server settings\n if (kitSettings.hashedEmailUserIdentityType) {\n this._mappedEmailSha256Key = kitSettings.hashedEmailUserIdentityType.toLowerCase();\n }\n\n this._workspaceIdSyncApiKey = isString(kitSettings.workspaceIdSyncApiKey)\n ? kitSettings.workspaceIdSyncApiKey\n : undefined;\n\n const domain = mp().Rokt?.domain;\n const { roktExtensionsQueryParams, legacyRoktExtensions, loadThankYouElement } = extractRoktExtensionConfig(\n kitSettings.roktExtensions,\n );\n const launcherOptions: Record = {\n ...((mp().Rokt?.launcherOptions as Record) || {}),\n };\n this.integrationName = generateIntegrationName(launcherOptions.integrationName as string | undefined);\n launcherOptions.integrationName = this.integrationName;\n\n this.domain = domain;\n\n const reportingConfig: ReportingConfig = {\n loggingUrl: kitSettings.loggingUrl,\n errorUrl: kitSettings.errorUrl,\n integrationDomain: domain,\n isLoggingEnabled: mp().config?.isLoggingEnabled === true,\n };\n const errorReportingService = new ErrorReportingService(\n reportingConfig,\n this.integrationName,\n window.__rokt_li_guid__,\n kitSettings.accountId,\n );\n const loggingService = new LoggingService(\n reportingConfig,\n errorReportingService,\n this.integrationName,\n window.__rokt_li_guid__,\n kitSettings.accountId,\n );\n\n this.errorReportingService = errorReportingService;\n this.loggingService = loggingService;\n\n if (this.isTargetingDisabled()) {\n try {\n clearPageViews();\n clearUtmParams();\n } catch (err) {\n this.errorReportingService?.report({\n message: 'Rokt Kit: Failed to clear page views when targeting is disabled',\n code: 'PAGE_VIEW_CAPTURE_FAILED',\n severity: WSDKErrorSeverity.INFO,\n stackTrace: err instanceof Error ? err.stack : undefined,\n });\n }\n }\n\n if (mp()._registerErrorReportingService) {\n mp()._registerErrorReportingService!(errorReportingService);\n }\n if (mp()._registerLoggingService) {\n mp()._registerLoggingService!(loggingService);\n }\n\n if (testMode) {\n this.testHelpers = {\n generateLauncherScript: generateLauncherScript,\n generateThankYouElementScript: generateThankYouElementScript,\n extractRoktExtensionConfig: extractRoktExtensionConfig,\n hashEventMessage: hashEventMessage,\n parseSettingsString: parseSettingsString,\n generateMappedEventLookup: generateMappedEventLookup,\n generateMappedEventAttributeLookup: generateMappedEventAttributeLookup,\n sendAdBlockMeasurementSignals: sendAdBlockMeasurementSignals,\n createAutoRemovedIframe: createAutoRemovedIframe,\n djb2: djb2,\n setAllowedOriginHashes: (hashes: number[]) => {\n RoktKit._allowedOriginHashes = hashes;\n },\n ReportingTransport: ReportingTransport,\n ErrorReportingService: ErrorReportingService,\n LoggingService: LoggingService,\n RateLimiter: RateLimiter,\n ErrorCodes: ErrorCodes,\n WSDKErrorSeverity: WSDKErrorSeverity,\n resetLauncherAttachState: () => resetLauncherAttachState(this._launcherAttachState),\n };\n this.attachLauncher(accountId, launcherOptions);\n return 'Successfully initialized: ' + name;\n }\n\n if (loadThankYouElement) {\n mp().Rokt.flushOnShoppableAdsReadyMessageQueue?.(this);\n loadRoktScript(ROKT_THANK_YOU_ELEMENT_SCRIPT_ID, generateThankYouElementScript(domain), {\n onLoad: () => {\n this._isThankYouElementLoaded = true;\n if (this._thankYouElementOnLoadCallback) {\n this._thankYouElementOnLoadCallback();\n }\n },\n onError: (error) => {\n console.error('Error loading Rokt Thank You Element script:', error);\n },\n });\n }\n\n if (this.isLauncherReadyToAttach()) {\n this.attachLauncher(accountId, launcherOptions, legacyRoktExtensions);\n } else {\n loadRoktScript(ROKT_INTEGRATION_SCRIPT_ID, generateLauncherScript(domain, roktExtensionsQueryParams), {\n onLoad: () => {\n if (this.isLauncherReadyToAttach()) {\n this.attachLauncher(accountId, launcherOptions, legacyRoktExtensions);\n } else {\n console.error('Rokt object is not available after script load.');\n }\n },\n onError: (error) => {\n console.error('Error loading Rokt launcher script:', error);\n },\n });\n\n this.captureTiming(RoktKit.PERFORMANCE_MARKS.RoktScriptAppended);\n }\n\n return 'Successfully initialized: ' + name;\n }\n\n public process(event: SDKEvent): string {\n if (!this.isTargetingDisabled()) {\n if (event.EventDataType === MESSAGE_TYPE_PAGE_VIEW) {\n captureUtmParams(this.loggingService);\n this.capturePageView(event);\n }\n\n if (event.EventDataType === MESSAGE_TYPE_SESSION_END) {\n clearPageViews();\n clearUtmParams();\n }\n }\n\n // The forwarding work below (LSA mapping) depends on the launcher, so guard\n // it here and surface the not-ready signal to the core SDK.\n if (!this.isKitReady()) {\n return 'Kit not ready for forwarder: ' + name;\n }\n\n if (isFunction(mp().Rokt?.setLocalSessionAttribute)) {\n if (!isEmpty(this.placementEventAttributeMappingLookup)) {\n this.applyPlacementEventAttributeMapping(event);\n }\n\n if (!isEmpty(this.placementEventMappingLookup)) {\n const hashedEvent = hashEventMessage(event.EventDataType, event.EventCategory, event.EventName ?? '');\n if (this.placementEventMappingLookup[String(hashedEvent)]) {\n mp().Rokt.setLocalSessionAttribute?.(this.placementEventMappingLookup[String(hashedEvent)], true);\n }\n }\n }\n\n return 'Successfully sent to forwarder: ' + name;\n }\n\n public setExtensionData(partnerExtensionData: Record): void {\n if (!this.isKitReady()) {\n console.error('Rokt Kit: Not initialized');\n return;\n }\n\n window.Rokt!.setExtensionData(partnerExtensionData);\n }\n\n public setUserAttribute(key: string, value: unknown): string {\n if (!isSelectPlacementsAttributePersistenceDenied(key)) {\n this.userAttributes[key] = value;\n }\n return 'Successfully set user attribute for forwarder: ' + name;\n }\n\n public removeUserAttribute(key: string): string {\n delete this.userAttributes[key];\n return 'Successfully removed user attribute for forwarder: ' + name;\n }\n\n private handleIdentityComplete(user: IMParticleUser, callbackName: string): string {\n this.userAttributes = removeSelectPlacementsAttributePersistenceDeniedAttributes(user.getAllUserAttributes());\n return 'Successfully called ' + callbackName + ' for forwarder: ' + name;\n }\n\n public onUserIdentified(user: IMParticleUser): string {\n const filteredUser = user as FilteredUser;\n this.filters.filteredUser = filteredUser;\n this._workspaceSearchInFlightPromise = this.search(filteredUser);\n return this.handleIdentityComplete(user, 'onUserIdentified');\n }\n\n private search(filteredUser: FilteredUser): Promise {\n const apiKey = this._workspaceIdSyncApiKey;\n if (!apiKey) {\n this.userIdentifiedInWorkspace = false;\n this._workspaceLastSearchedIdentitiesKey = undefined;\n return Promise.resolve();\n }\n const search = mp().Identity?.search;\n if (typeof search !== 'function') {\n this.userIdentifiedInWorkspace = false;\n this._workspaceLastSearchedIdentitiesKey = undefined;\n return Promise.resolve();\n }\n\n const userIdentities: IUserIdentities | null = filteredUser.getUserIdentities\n ? filteredUser.getUserIdentities().userIdentities\n : null;\n\n // Forward every non-empty string identifier the user has — email,\n // customerid, other/other2-10 (commonly used for hashed email),\n // mobile_number, facebook, etc. The host SDK's Identity.search accepts\n // the full IUserIdentities surface and the server validates it.\n const knownIdentities: Record = {};\n if (userIdentities) {\n for (const key of Object.keys(userIdentities) as Array) {\n const value = userIdentities[key];\n if (isString(value) && value.length > 0) {\n knownIdentities[key] = value;\n }\n }\n }\n\n const identityKeys = Object.keys(knownIdentities);\n if (identityKeys.length === 0) {\n this.userIdentifiedInWorkspace = false;\n this._workspaceLastSearchedIdentitiesKey = undefined;\n return Promise.resolve();\n }\n\n // Stable cache key: sort keys so insertion-order differences don't\n // cause false misses. The values are partner-supplied strings; no\n // hashing needed — equality on this serialization is sufficient.\n const identitiesKey = identityKeys\n .sort()\n .map((k) => `${k}=${knownIdentities[k]}`)\n .join('&');\n\n // Same identifier set as the last successful dispatch → skip the\n // network call. The current flag value still reflects the correct\n // match status.\n if (identitiesKey === this._workspaceLastSearchedIdentitiesKey) {\n return this._workspaceSearchInFlightPromise || Promise.resolve();\n }\n\n // New / different identifier set → reset and re-search. Cache the key\n // up front so a second concurrent invocation with the same set also\n // dedupes.\n this.userIdentifiedInWorkspace = false;\n this._workspaceLastSearchedIdentitiesKey = identitiesKey;\n\n return new Promise((resolve) => {\n try {\n search(apiKey, knownIdentities as IUserIdentities, (result: WorkspaceIdSyncResult) => {\n if (result?.httpCode === 200) {\n this.userIdentifiedInWorkspace = true;\n }\n resolve();\n });\n } catch (err) {\n console.error('Rokt Kit: Workspace IDSync search failed', err);\n // Dispatch failed — clear the cache so the same identifier set\n // can retry on the next identification rather than being stuck\n // behind a poisoned entry that short-circuits future searches.\n this._workspaceLastSearchedIdentitiesKey = undefined;\n resolve();\n }\n });\n }\n\n public onLoginComplete(user: IMParticleUser, _filteredIdentityRequest: unknown): string {\n return this.handleIdentityComplete(user, 'onLoginComplete');\n }\n\n public onLogoutComplete(user: IMParticleUser, _filteredIdentityRequest: unknown): string {\n // Anonymous sessions must not carry the previous user's match forward.\n // Clear the flag explicitly here. Also clear the identities cache so a\n // re-login (possibly with the same identifiers) dispatches a fresh\n // search rather than reusing a stale answer.\n this.userIdentifiedInWorkspace = false;\n this._workspaceSearchInFlightPromise = null;\n this._workspaceLastSearchedIdentitiesKey = undefined;\n return this.handleIdentityComplete(user, 'onLogoutComplete');\n }\n\n public onModifyComplete(user: IMParticleUser, _filteredIdentityRequest: unknown): string {\n return this.handleIdentityComplete(user, 'onModifyComplete');\n }\n\n /**\n * Selects placements for Rokt Web SDK with merged attributes, filters, and experimentation options.\n *\n * If a Workspace IDSync search is in flight from a recent onUserIdentified\n * call, this method waits up to `WORKSPACE_SEARCH_SELECT_TIMEOUT_MS` for it\n * to settle so the first placement call can include the\n * `userIdentifiedInWorkspace` flag without racing the network response.\n * The timeout protects against a stalled or slow search blocking placement\n * rendering — if it fires, selectPlacements proceeds without the flag.\n *\n * Implementation note: this method stays non-async deliberately. First,\n * the public return type is `RoktSelection | Promise |\n * undefined` — a superset of the `RoktSelection | Promise`\n * shape declared for `RoktLauncher.selectPlacements` above (line ~70).\n * Marking this `async` would narrow it to `Promise` and silently change the contract for callers that read\n * the result synchronously. Second, `RoktSelection` has an optional\n * `then?` member, so TS treats it as ambiguously promise-like and\n * rejects it as the awaited return of an async function (TS1058) —\n * working around that would require a cast or wrapping every return in\n * `Promise.resolve(...)`. The inner work runs in `_dispatchPlacements`;\n * this wrapper just gates it on the in-flight search via `Promise.race`,\n * and on a post-terminate createLauncher when the SPA needs a new instance.\n */\n public selectPlacements(options: Record): RoktSelection | Promise | undefined {\n const recreate = this.recreateLauncherIfTerminated();\n if (recreate) {\n const inFlight = this._workspaceSearchInFlightPromise;\n const waitForSearch = inFlight\n ? Promise.race([\n inFlight,\n new Promise((resolve) => setTimeout(resolve, WORKSPACE_SEARCH_SELECT_TIMEOUT_MS)),\n ])\n : Promise.resolve();\n return Promise.all([recreate, waitForSearch]).then(() =>\n this._dispatchPlacements(options),\n ) as Promise;\n }\n if (this._workspaceSearchInFlightPromise) {\n const inFlight = this._workspaceSearchInFlightPromise;\n return Promise.race([\n inFlight,\n new Promise((resolve) => setTimeout(resolve, WORKSPACE_SEARCH_SELECT_TIMEOUT_MS)),\n ]).then(() => this._dispatchPlacements(options)) as Promise;\n }\n return this._dispatchPlacements(options);\n }\n\n private _dispatchPlacements(options: Record): RoktSelection | Promise | undefined {\n const attributes = ((options && (options.attributes as Record)) || {}) as Record;\n const cachedUserAttributes = removeSelectPlacementsAttributePersistenceDeniedAttributes(this.userAttributes);\n const placementAttributes: Record = { ...cachedUserAttributes, ...attributes };\n\n const filters = this.filters || {};\n const userAttributeFilters = (filters.userAttributeFilters as string[]) || [];\n const filteredUser = filters.filteredUser || null;\n const mpid = filteredUser ? filteredUser.getMPID() : null;\n\n let filteredAttributes: Record;\n\n if (!filters) {\n console.warn('Rokt Kit: No filters available, using user attributes');\n filteredAttributes = placementAttributes;\n } else if (filters.filterUserAttributes) {\n filteredAttributes = filters.filterUserAttributes(placementAttributes, userAttributeFilters);\n } else {\n filteredAttributes = placementAttributes;\n }\n\n this.userAttributes = removeSelectPlacementsAttributePersistenceDeniedAttributes(filteredAttributes);\n\n const optimizelyAttributes = this._onboardingExpProvider === 'Optimizely' ? this.fetchOptimizely() : {};\n\n const filteredUserIdentities = this.returnUserIdentities(filteredUser);\n\n const sessionAttributes = this.returnLocalSessionAttributes();\n const pageEvents = buildPageEvents(loadPageViews());\n const utmParams = loadUtmParams();\n const mpSessionId = this.readMpSessionId();\n const mpDeviceId = this.readMpDeviceId();\n\n const selectPlacementsAttributes: Record = {\n ...(filteredUserIdentities as Record),\n ...filteredAttributes,\n ...optimizelyAttributes,\n ...sessionAttributes,\n ...(pageEvents.length ? { [PAGE_EVENTS_KEY]: JSON.stringify(pageEvents) } : {}),\n ...(utmParams ? { [PAGE_VIEW_ATTRIBUTES_KEY]: utmParams } : {}),\n ...(this.userIdentifiedInWorkspace ? { [USER_IDENTIFIED_IN_WORKSPACE_KEY]: true } : {}),\n ...(mpSessionId ? { [MPARTICLE_SESSION_ID_KEY]: mpSessionId } : {}),\n ...(mpDeviceId ? { [MPARTICLE_DEVICE_ID_KEY]: mpDeviceId } : {}),\n mpid,\n };\n\n const selectPlacementsOptions: Record = { ...options, attributes: selectPlacementsAttributes };\n\n const selection = this.launcher!.selectPlacements(selectPlacementsOptions);\n\n // After selection resolves, sync the Rokt session ID back to mParticle, then log\n const logSelection = () => this.logSelectPlacementsEvent(selectPlacementsAttributes);\n\n void Promise.resolve(selection)\n .then((sel) => sel?.context?.sessionId?.then((sessionId) => this.setRoktSessionId(sessionId)))\n .catch(() => undefined)\n .finally(logSelection);\n\n return selection;\n }\n\n /**\n * Passes attributes to the Rokt Web SDK for client-side hashing.\n */\n public hashAttributes(attributes: Record): Promise> | null {\n if (!this.isKitReady()) {\n console.error('Rokt Kit: Not initialized');\n return null;\n }\n return this.launcher!.hashAttributes(attributes);\n }\n\n /**\n * Enables optional Integration Launcher extensions before selecting placements.\n *\n * @deprecated This functionality has been internalized and will be removed in a future release.\n */\n public use(extensionName: string): Promise {\n if (!this.isKitReady()) {\n console.error('Rokt Kit: Not initialized');\n return Promise.reject(new Error('Rokt Kit: Not initialized'));\n }\n if (!extensionName || !isString(extensionName)) {\n return Promise.reject(new Error('Rokt Kit: Invalid extension name'));\n }\n return this.launcher!.use(extensionName);\n }\n\n /**\n * Tears down the Rokt launcher and the placements it rendered.\n *\n * The kit's launcher reference is left in place so isKitReady() stays true.\n * The Web SDK clears its memoized launcher on terminate, so a later\n * createLauncher (SPA navigation) produces a new instance. The next\n * selectPlacements call re-attaches that instance. Nulling the reference\n * here would flip the kit to not-ready with no drain path for queued calls.\n */\n public terminate(): Promise {\n if (!this.isKitReady()) {\n console.error('Rokt Kit: Not initialized');\n return Promise.resolve();\n }\n markLauncherTerminated(this._launcherAttachState);\n return this.launcher!.terminate();\n }\n\n /**\n * Registers a callback to be invoked once rokt-thank-you-element.js becomes available.\n */\n public onShoppableAdsReady(callback: () => void) {\n if (this._isThankYouElementLoaded) {\n callback();\n } else {\n this._thankYouElementOnLoadCallback = callback;\n }\n }\n}\n\n// ============================================================\n// Kit registration\n// ============================================================\n\nfunction getId(): number {\n return moduleId;\n}\n\nfunction register(config: { kits?: Record }): void {\n if (!config) {\n window.console.log('You must pass a config object to register the kit ' + name);\n return;\n }\n if (!isObject(config)) {\n window.console.log(\"'config' must be an object. You passed in a \" + typeof config);\n return;\n }\n\n if (isObject(config.kits)) {\n (config.kits as Record)[name] = {\n constructor: RoktKit,\n };\n } else {\n config.kits = {};\n config.kits[name] = {\n constructor: RoktKit,\n };\n }\n window.console.log('Successfully registered ' + name + ' to your mParticle configuration');\n}\n\nif (typeof window !== 'undefined' && window.mParticle && mp().addForwarder) {\n mp().addForwarder({\n name: name,\n constructor: RoktKit,\n getId: getId,\n });\n}\n\nexport { register };\nexport type { LoggingService };\n"],"names":["SELECT_PLACEMENTS_ATTRIBUTE_PERSISTENCE_DENY_LIST","SELECT_PLACEMENTS_ATTRIBUTE_PERSISTENCE_DENY_SET","isSelectPlacementsAttributePersistenceDenied","key","removeSelectPlacementsAttributePersistenceDeniedAttributes","attributes","filteredAttributes","sourceAttributes","attributeKeys","i","isObject","value","isString","isFunction","isEmpty","sanitizeUrl","href","url","LS_PROBE_KEY","isLocalStorageAvailable","readJSON","stored","writeJSON","removeKey","readNamespacedField","namespaceKey","field","blob","writeNamespacedField","next","removeNamespacedField","LS_NAMESPACE_KEY","LS_PAGE_VIEWS_FIELD","LS_UTM_PARAMS_FIELD","PAGE_VIEWS_MAX_COUNT","UTM_KEYS","capPageViews","views","loadPageViews","writePageViews","pageViews","toWrite","clearPageViews","buildPageEvents","pageView","index","activeTimeOnSite","hasActiveTime","nextActiveTimeOnSite","hasNextActiveTimeOnSite","diff","captureUtmParams","loggingService","search","params","captured","reason","loadUtmParams","clearUtmParams","readCanonicalUrl","createLauncherAttachState","rememberAttachContext","state","context","markLauncherAttached","markLauncherTerminated","markLauncherAttachFailed","resetLauncherAttachState","recreateIfTerminated","canAttach","attach","name","moduleId","EVENT_NAME_SELECT_PLACEMENTS","ADBLOCK_CONTROL_DOMAIN","INIT_LOG_SAMPLING_RATE","ROKT_THANK_YOU_JOURNEY_EXTENSION","ROKT_INTEGRATION_SCRIPT_ID","ROKT_THANK_YOU_ELEMENT_SCRIPT_ID","USER_IDENTIFIED_IN_WORKSPACE_KEY","MESSAGE_TYPE_PAGE_VIEW","MESSAGE_TYPE_SESSION_END","PAGE_EVENTS_KEY","PAGE_VIEW_ATTRIBUTES_KEY","MPARTICLE_SESSION_ID_KEY","MPARTICLE_DEVICE_ID_KEY","WORKSPACE_SEARCH_SELECT_TIMEOUT_MS","ErrorCodes","WSDKErrorSeverity","DEFAULT_ROKT_DOMAIN","LOGGING_ENDPOINT","ERROR_ENDPOINT","RATE_LIMIT_PER_SEVERITY","mp","generateLauncherScript","domain","extensions","baseUrl","generateBaseUrl","generateThankYouElementScript","resolvedDomain","generateReportingUrl","configuredUrl","endpoint","reportingDomain","loadRoktScript","scriptId","source","handlers","target","script","parseSettingsString","settingsString","extractRoktExtensionConfig","settings","roktExtensionsQueryParams","legacyRoktExtensions","loadThankYouElement","extensionName","registerLegacyExtensions","legacyExtensions","launcher","extension","generateMappedEventLookup","placementEventMapping","mappedEvents","mapping","generateMappedEventAttributeLookup","placementEventAttributeMapping","mappedAttributeKeys","mappedAttributeKey","eventAttributeKey","hashEventMessage","messageType","eventType","eventName","generateIntegrationName","customIntegrationName","integrationName","djb2","str","hash","createAutoRemovedIframe","src","iframe","sendAdBlockMeasurementSignals","version","originHash","RoktKit","guid","pageUrl","existingBaseUrl","_isDebugModeEnabled","_getReportingUrl","_getUserAgent","RateLimiter","severity","newCount","ReportingTransport","config","launcherInstanceGuid","accountId","rateLimiter","isLoggingEnabled","msg","code","stackTrace","onError","logRequest","headers","response","serverError","error","ErrorReportingService","LoggingService","errorReportingService","entry","isServerSide","buildPageEvent","event","pageTitle","canonicalUrl","_RoktKit","condition","actualValue","operator","expectedValue","rule","conditions","rulesForMappedAttributeKey","allMatch","j","requested","err","errMessage","filteredUser","userIdentities","newUserIdentities","EVENT_TYPE_OTHER","sessionId","mpInstance","sessionManager","readSessionId","launcherOptions","options","launcherPromise","roktFilters","forwarders","forwarder","optimizelyState","acc","expId","metricName","_service","testMode","_trackerId","filteredUserAttributes","kitSettings","reportingConfig","hashes","hashedEvent","partnerExtensionData","user","callbackName","apiKey","knownIdentities","identityKeys","identitiesKey","k","resolve","result","_filteredIdentityRequest","recreate","inFlight","waitForSearch","placementAttributes","filters","userAttributeFilters","mpid","optimizelyAttributes","filteredUserIdentities","sessionAttributes","pageEvents","utmParams","mpSessionId","mpDeviceId","selectPlacementsAttributes","selectPlacementsOptions","selection","logSelection","sel","callback","getId","register"],"mappings":"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"} \ No newline at end of file diff --git a/kits/rokt/dist/Rokt-Kit.iife.js b/kits/rokt/dist/Rokt-Kit.iife.js index fbe239f74..c6341a590 100644 --- a/kits/rokt/dist/Rokt-Kit.iife.js +++ b/kits/rokt/dist/Rokt-Kit.iife.js @@ -1,3 +1,2 @@ -console.info('[mParticle QA kit path smoke] Loaded kits/rokt/dist/Rokt-Kit.iife.js from monorepo GitHub path'); -var RoktKit=(function(v){"use strict";const J=["billingaddress1","billingaddress2","billingcity","billingstate","billingzipcode","cartitems","ccbin","confirmationref","conversiontype","country","couponcode","currency","language","paymentserviceprovider","paymentserviceproviderattribute","paymenttype","shippingaddress1","shippingcity","shippingcountry","shippingmethod","shippingstate","shippingzipcode","totalprice"],Q=new Set(J);function K(n){return Q.has(n.toLowerCase())}function R(n){const t={},e=n||{},i=Object.keys(e);for(let r=0;r=Z)return;const r=window.__rokt_li_guid__;if(!r)return;const s=window.location.href.split("?")[0].split("#")[0],o="version="+encodeURIComponent(t??"")+"&launcherInstanceGuid="+encodeURIComponent(r)+"&pageUrl="+encodeURIComponent(s);P("https://"+(n||"apps.rokt.com")+"/v1/wsdk-init/index.html?"+o),P("https://"+$+"/v1/wsdk-init/index.html?"+o+"&isControl=true")}function dt(){return typeof window<"u"&&!!window.location?.search?.toLowerCase().includes("mp_enable_logging=true")}function ht(){return typeof window<"u"?window.location?.href:void 0}function pt(){return typeof window<"u"?window.navigator?.userAgent:void 0}class V{constructor(){this._logCount={}}incrementAndCheck(t){const i=(this._logCount[t]||0)+1;return this._logCount[t]=i,i>ct}}class C{constructor(t,e,i,r,s){this._reporter="mp-wsdk";const o=t.isLoggingEnabled;this._integrationName=e||"",this._launcherInstanceGuid=i,this._accountId=r||null,this._rateLimiter=s||new V,this._isEnabled=dt()||o}send(t,e,i,r,s,o){if(!(!this._isEnabled||this._rateLimiter.incrementAndCheck(e)))try{const c={additionalInformation:{message:i,version:this._integrationName},severity:e,code:r||T.UNKNOWN_ERROR,url:ht(),deviceInfo:pt(),stackTrace:s,reporter:this._reporter,integration:this._integrationName},u={Accept:"text/plain;charset=UTF-8","Content-Type":"application/json","rokt-launcher-version":this._integrationName,"rokt-wsdk-version":"joint"};this._launcherInstanceGuid&&(u["rokt-launcher-instance-guid"]=this._launcherInstanceGuid),this._accountId&&(u["rokt-account-id"]=this._accountId),fetch(t,{method:"POST",headers:u,body:JSON.stringify(c)}).then(l=>{if(!l.ok){const h=new Error("HTTP "+l.status+" from log endpoint");throw h.statusCode=l.status,h}}).catch(l=>{console.error("ReportingTransport: Failed to send log",l),o&&o(l)})}catch(c){console.error("ReportingTransport: Failed to send log",c),o&&o(c)}}}class q{constructor(t,e,i,r,s){this._transport=new C(t,e,i,r,s),this._errorUrl=Y(t?.errorUrl,t?.integrationDomain,at)}report(t){if(!t)return;const e=t.severity||_.ERROR;this._transport.send(this._errorUrl,e,t.message,t.code,t.stackTrace)}}class B{constructor(t,e,i,r,s,o){this._transport=new C(t,i,r,s,o),this._loggingUrl=Y(t?.loggingUrl,t?.integrationDomain,ot),this._errorReportingService=e}log(t){t&&this._transport.send(this._loggingUrl,_.INFO,t.message,t.code,void 0,e=>{if(this._errorReportingService){const i=typeof e.statusCode=="number";this._errorReportingService.report({message:"LoggingService: Failed to send log: "+e.message,code:T.LOG_DELIVERY_FAILURE,severity:i?_.ERROR:_.WARNING})}})}}const p=class p{constructor(){this.name=d,this.id=A,this.moduleId=A,this.isInitialized=!1,this.launcher=null,this.filters={},this.userAttributes={},this.userIdentifiedInWorkspace=!1,this.testHelpers=null,this.placementEventMappingLookup={},this.placementEventAttributeMappingLookup={},this.integrationName=null,this.errorReportingService=null,this.loggingService=null,this._thankYouElementOnLoadCallback=null,this._isThankYouElementLoaded=!1,this._workspaceSearchInFlightPromise=null}getEventAttributeValue(t,e){const i=t&&t.EventAttributes;return!i||typeof i[e]>"u"?null:i[e]}doesEventAttributeConditionMatch(t,e){if(!t||!g(t.operator))return!1;const i=t.operator.toLowerCase(),r=t.attributeValue;return i==="exists"?e!==null:e==null?!1:i==="equals"?String(e)===String(r):i==="contains"?String(e).indexOf(String(r))!==-1:!1}doesEventMatchRule(t,e){if(!e||!g(e.eventAttributeKey))return!1;const i=e.conditions;if(!Array.isArray(i))return!1;const r=this.getEventAttributeValue(t,e.eventAttributeKey);if(i.length===0)return r!==null;for(let s=0;s{await lt(i,c),this.initRoktLauncher(c)}).catch(c=>{console.error("Error creating Rokt launcher:",c)})}initRoktLauncher(t){window.Rokt&&(window.Rokt.currentLauncher=t),this.launcher=t;const e=a().Rokt?.filters;e?(this.filters=e,e.filteredUser?this._workspaceSearchInFlightPromise=this.search(e.filteredUser):console.warn("Rokt Kit: No filtered user has been set.")):console.warn("Rokt Kit: No filters have been set."),this.isInitialized=!0,z(this.domain,this.integrationName),a().Rokt.attachKit(this)}fetchOptimizely(){const t=a()._getActiveForwarders().filter(e=>e.name==="Optimizely");try{if(t.length>0&&window.optimizely){const e=window.optimizely.get("state");return!e||!e.getActiveExperimentIds?{}:e.getActiveExperimentIds().reduce((s,o)=>(s["rokt.custom.optimizely.experiment."+o+".variationId"]=e.getVariationMap()[o].id,s),{})}}catch(e){console.error("Error fetching Optimizely attributes:",e)}return{}}isKitReady(){return!!(this.isInitialized&&this.launcher)}isPartnerInLocalLauncherTestGroup(){return!!(a().config&&a().config.isLocalLauncherEnabled&&this.isAssignedToSampleGroup())}isAssignedToSampleGroup(){return Math.random()>.5}captureTiming(t){window&&a()&&a().captureTiming&&t&&a().captureTiming(t)}init(t,e,i,r,s){const o=t,c=o.accountId;this.userAttributes=R(s),this._onboardingExpProvider=o.onboardingExpProvider;const u=S(o.placementEventMapping);this.placementEventMappingLookup=F(u);const l=S(o.placementEventAttributeMapping);this.placementEventAttributeMappingLookup=H(l),o.hashedEmailUserIdentityType&&(this._mappedEmailSha256Key=o.hashedEmailUserIdentityType.toLowerCase()),this._workspaceIdSyncApiKey=g(o.workspaceIdSyncApiKey)?o.workspaceIdSyncApiKey:void 0;const h=a().Rokt?.domain,{roktExtensionsQueryParams:U,legacyRoktExtensions:w,loadThankYouElement:b}=j(o.roktExtensions),f={...a().Rokt?.launcherOptions||{}};this.integrationName=ut(f.integrationName),f.integrationName=this.integrationName,this.domain=h;const k={loggingUrl:o.loggingUrl,errorUrl:o.errorUrl,integrationDomain:h,isLoggingEnabled:a().config?.isLoggingEnabled===!0},I=new q(k,this.integrationName,window.__rokt_li_guid__,o.accountId),L=new B(k,I,this.integrationName,window.__rokt_li_guid__,o.accountId);return this.errorReportingService=I,this.loggingService=L,a()._registerErrorReportingService&&a()._registerErrorReportingService(I),a()._registerLoggingService&&a()._registerLoggingService(L),i?(this.testHelpers={generateLauncherScript:M,generateThankYouElementScript:D,extractRoktExtensionConfig:j,hashEventMessage:W,parseSettingsString:S,generateMappedEventLookup:F,generateMappedEventAttributeLookup:H,sendAdBlockMeasurementSignals:z,createAutoRemovedIframe:P,djb2:G,setAllowedOriginHashes:m=>{p._allowedOriginHashes=m},ReportingTransport:C,ErrorReportingService:q,LoggingService:B,RateLimiter:V,ErrorCodes:T,WSDKErrorSeverity:_},this.attachLauncher(c,f),"Successfully initialized: "+d):(b&&(a().Rokt.flushOnShoppableAdsReadyMessageQueue?.(this),x(it,D(h),{onLoad:()=>{this._isThankYouElementLoaded=!0,this._thankYouElementOnLoadCallback&&this._thankYouElementOnLoadCallback()},onError:m=>{console.error("Error loading Rokt Thank You Element script:",m)}})),this.isLauncherReadyToAttach()?this.attachLauncher(c,f,w):(x(et,M(h,U),{onLoad:()=>{this.isLauncherReadyToAttach()?this.attachLauncher(c,f,w):console.error("Rokt object is not available after script load.")},onError:m=>{console.error("Error loading Rokt launcher script:",m)}}),this.captureTiming(p.PERFORMANCE_MARKS.RoktScriptAppended)),"Successfully initialized: "+d)}process(t){if(!this.isKitReady())return"Kit not ready for forwarder: "+d;if(typeof a().Rokt?.setLocalSessionAttribute=="function"&&(y(this.placementEventAttributeMappingLookup)||this.applyPlacementEventAttributeMapping(t),!y(this.placementEventMappingLookup))){const e=W(t.EventDataType,t.EventCategory,t.EventName??"");this.placementEventMappingLookup[String(e)]&&a().Rokt.setLocalSessionAttribute?.(this.placementEventMappingLookup[String(e)],!0)}return"Successfully sent to forwarder: "+d}setExtensionData(t){if(!this.isKitReady()){console.error("Rokt Kit: Not initialized");return}window.Rokt.setExtensionData(t)}setUserAttribute(t,e){return K(t)||(this.userAttributes[t]=e),"Successfully set user attribute for forwarder: "+d}removeUserAttribute(t){return delete this.userAttributes[t],"Successfully removed user attribute for forwarder: "+d}handleIdentityComplete(t,e){return this.userAttributes=R(t.getAllUserAttributes()),"Successfully called "+e+" for forwarder: "+d}onUserIdentified(t){const e=t;return this.filters.filteredUser=e,this._workspaceSearchInFlightPromise=this.search(e),this.handleIdentityComplete(t,"onUserIdentified")}search(t){const e=this._workspaceIdSyncApiKey;if(!e)return this.userIdentifiedInWorkspace=!1,this._workspaceLastSearchedIdentitiesKey=void 0,Promise.resolve();const i=a().Identity?.search;if(typeof i!="function")return this.userIdentifiedInWorkspace=!1,this._workspaceLastSearchedIdentitiesKey=void 0,Promise.resolve();const r=t.getUserIdentities?t.getUserIdentities().userIdentities:null,s={};if(r)for(const u of Object.keys(r)){const l=r[u];g(l)&&l.length>0&&(s[u]=l)}const o=Object.keys(s);if(o.length===0)return this.userIdentifiedInWorkspace=!1,this._workspaceLastSearchedIdentitiesKey=void 0,Promise.resolve();const c=o.sort().map(u=>`${u}=${s[u]}`).join("&");return c===this._workspaceLastSearchedIdentitiesKey?this._workspaceSearchInFlightPromise||Promise.resolve():(this.userIdentifiedInWorkspace=!1,this._workspaceLastSearchedIdentitiesKey=c,new Promise(u=>{try{i(e,s,l=>{l?.httpCode===200&&(this.userIdentifiedInWorkspace=!0),u()})}catch(l){console.error("Rokt Kit: Workspace IDSync search failed",l),this._workspaceLastSearchedIdentitiesKey=void 0,u()}}))}onLoginComplete(t,e){return this.handleIdentityComplete(t,"onLoginComplete")}onLogoutComplete(t,e){return this.userIdentifiedInWorkspace=!1,this._workspaceSearchInFlightPromise=null,this._workspaceLastSearchedIdentitiesKey=void 0,this.handleIdentityComplete(t,"onLogoutComplete")}onModifyComplete(t,e){return this.handleIdentityComplete(t,"onModifyComplete")}selectPlacements(t){if(this._workspaceSearchInFlightPromise){const e=this._workspaceSearchInFlightPromise;return Promise.race([e,new Promise(i=>setTimeout(i,rt))]).then(()=>this._dispatchPlacements(t))}return this._dispatchPlacements(t)}_dispatchPlacements(t){const e=t&&t.attributes||{},r={...R(this.userAttributes),...e},s=this.filters||{},o=s.userAttributeFilters||[],c=s.filteredUser||null,u=c?c.getMPID():null;let l;s?s.filterUserAttributes?l=s.filterUserAttributes(r,o):l=r:(console.warn("Rokt Kit: No filters available, using user attributes"),l=r),this.userAttributes=R(l);const h=this._onboardingExpProvider==="Optimizely"?this.fetchOptimizely():{},U=this.returnUserIdentities(c),w=this.returnLocalSessionAttributes(),b={...U,...l,...h,...w,...this.userIdentifiedInWorkspace?{[nt]:!0}:{},mpid:u},f={...t,attributes:b},k=this.launcher.selectPlacements(f),I=()=>this.logSelectPlacementsEvent(b);return Promise.resolve(k).then(L=>L?.context?.sessionId?.then(m=>this.setRoktSessionId(m))).catch(()=>{}).finally(I),k}hashAttributes(t){return this.isKitReady()?this.launcher.hashAttributes(t):(console.error("Rokt Kit: Not initialized"),null)}use(t){return this.isKitReady()?!t||!g(t)?Promise.reject(new Error("Rokt Kit: Invalid extension name")):this.launcher.use(t):(console.error("Rokt Kit: Not initialized"),Promise.reject(new Error("Rokt Kit: Not initialized")))}onShoppableAdsReady(t){this._isThankYouElementLoaded?t():this._thankYouElementOnLoadCallback=t}};p._allowedOriginHashes=[-553112570,549508659],p.PERFORMANCE_MARKS={RoktScriptAppended:"mp:RoktScriptAppended"},p.EMAIL_SHA256_KEY="emailsha256";let E=p;function gt(){return A}function ft(n){if(!n){window.console.log("You must pass a config object to register the kit "+d);return}if(!N(n)){window.console.log("'config' must be an object. You passed in a "+typeof n);return}N(n.kits)?n.kits[d]={constructor:E}:(n.kits={},n.kits[d]={constructor:E}),window.console.log("Successfully registered "+d+" to your mParticle configuration")}return typeof window<"u"&&window.mParticle&&a().addForwarder&&a().addForwarder({name:d,constructor:E,getId:gt}),v.register=ft,Object.defineProperty(v,Symbol.toStringTag,{value:"Module"}),v})({}); +var RoktKit=(function(N){"use strict";const ge=["active_time_on_site_ms","billingaddress1","billingaddress2","billingcity","billingstate","billingzipcode","cartitems","ccbin","confirmationref","conversiontype","country","couponcode","currency","language","paymentserviceprovider","paymentserviceproviderattribute","paymenttype","shippingaddress1","shippingcity","shippingcountry","shippingmethod","shippingstate","shippingzipcode","totalprice"],fe=new Set(ge);function W(i){return fe.has(i.toLowerCase())}function R(i){const e={},t=i||{},n=Object.keys(t);for(let r=0;r{const r=t.activeTimeOnSite,o=r!==void 0&&Number.isFinite(r),c=e[n+1]?.activeTimeOnSite,u=c!==void 0&&Number.isFinite(c),l=o&&u?c-r:void 0;return{pageUrl:t.pageUrl,sourceMessageId:t.sourceMessageId,timestamp:t.timestamp,...t.pageTitle!==void 0?{pageTitle:t.pageTitle}:{},...t.canonicalUrl!==void 0?{canonicalUrl:t.canonicalUrl}:{},...o?{activeTimeOnSite:r}:{},...l!==void 0&&l>=0?{activeTimeOnPage:l}:{}}})}function Se(i){if(F(_,w)!==void 0)return;const e=new URLSearchParams(window.location.search),t={};for(const r of Ee){const o=e.get(r);o&&(t[r]=o)}if(Object.keys(t).length===0)return;const n=Object.keys(t).join(", ");if(!z(_,w,t)){const r=M()?"quota":"ls_unavailable";i?.log({message:`Rokt Kit: Failed to persist UTM params [reason: ${r}]`,code:"UTM_CAPTURE_FAILED"});return}i?.log({message:`Rokt Kit: Captured UTM params [${n}]`,code:"UTM_CAPTURE_SUCCESS"})}function ye(){const i=F(_,w);return m(i)?i:null}function X(){q(_,w)}function Ae(){const e=document.querySelector('link[rel="canonical"]')?.href;if(e)return C(e)}function ke(){return{context:null,lifecycle:"idle",recreateInFlight:null}}function Re(i,e){i.context={accountId:e.accountId,launcherOptions:{...e.launcherOptions},legacyRoktExtensions:[...e.legacyRoktExtensions]}}function ve(i){i.lifecycle="attached"}function we(i){i.lifecycle!=="idle"&&(i.lifecycle="terminated")}function be(i){i.lifecycle="terminated"}function Te(i){i.context=null,i.lifecycle="idle",i.recreateInFlight=null}function Le(i,e,t){if(i.recreateInFlight)return i.recreateInFlight;if(i.lifecycle!=="terminated"||!i.context||!e)return;i.lifecycle="recreating";const n=i.context;return i.recreateInFlight=t(n).finally(()=>{i.recreateInFlight=null}),i.recreateInFlight}const d="Rokt",b=181,Pe="selectPlacements",Oe="apps.roktecommerce.com",Ne=.1,Ue="ThankYouPageJourney",Ce="rokt-launcher",Me="rokt-thank-you-element",Ke="userIdentifiedInWorkspace",Fe=3,De=2,xe="page_events",Ye="page_view_attributes",je="mparticle_session_id",Ge="mparticle_device_id",Z=500,x={UNKNOWN_ERROR:"UNKNOWN_ERROR",UNHANDLED_EXCEPTION:"UNHANDLED_EXCEPTION",IDENTITY_REQUEST:"IDENTITY_REQUEST",LOG_DELIVERY_FAILURE:"LOG_DELIVERY_FAILURE"},I={ERROR:"ERROR",INFO:"INFO",WARNING:"WARNING"},We="apps.rokt-api.com",He="/v1/log",Ve="/v1/errors",ze=10;function a(){return window.mParticle}function ee(i,e){const n=[T(i),"/wsdk/integrations/launcher.js"].join("");return!e||e.length===0?n:n+"?extensions="+e.join(",")}function te(i){return[T(i),"/rokt-elements/rokt-element-thank-you.js"].join("")}function T(i){const e=typeof i<"u"?i:We;return e.includes("://")?e.replace(/\/+$/,""):["https://",e].join("")}function ie(i,e,t){if(i)return i.startsWith("http://")||i.startsWith("https://")?i:"https://"+i;const r=e?.includes("://")&&!/^https?:\/\//i.test(e)?void 0:e;return T(r)+t}function ne(i,e,t){if(document.getElementById(i))return;const n=document.head||document.body,r=document.createElement("script");r.id=i,r.type="text/javascript",r.src=e,r.async=!0,r.crossOrigin="anonymous",r.fetchPriority="high",t?.onLoad&&(r.onload=t.onLoad),t?.onError&&(r.onerror=t.onError),n.appendChild(r)}function L(i){if(!i)return[];try{return JSON.parse(i.replace(/"/g,'"'))}catch{console.error("Settings string contains invalid JSON")}return[]}function re(i){const e=i?L(i):[],t=[],n=[];let r=!1;for(let o=0;o=Ne)return;const r=window.__rokt_li_guid__;if(!r||i&&i.includes("://")&&!/^https:\/\//i.test(i))return;const o=window.location.href.split("?")[0].split("#")[0],s="version="+encodeURIComponent(e??"")+"&launcherInstanceGuid="+encodeURIComponent(r)+"&pageUrl="+encodeURIComponent(o),c=i?T(i):"https://apps.rokt.com";Y(c+"/v1/wsdk-init/index.html?"+s),Y("https://"+Oe+"/v1/wsdk-init/index.html?"+s+"&isControl=true")}function Je(){return typeof window<"u"&&!!window.location?.search?.toLowerCase().includes("mp_enable_logging=true")}function Be(){return typeof window<"u"?window.location?.href:void 0}function Qe(){return typeof window<"u"?window.navigator?.userAgent:void 0}class ue{constructor(){this._logCount={}}incrementAndCheck(e){const n=(this._logCount[e]||0)+1;return this._logCount[e]=n,n>ze}}class j{constructor(e,t,n,r,o){this._reporter="mp-wsdk";const s=e.isLoggingEnabled;this._integrationName=t||"",this._launcherInstanceGuid=n,this._accountId=r||null,this._rateLimiter=o||new ue,this._isEnabled=Je()||s}send(e,t,n,r,o,s){if(!(!this._isEnabled||this._rateLimiter.incrementAndCheck(t)))try{const c={additionalInformation:{message:n,version:this._integrationName},severity:t,code:r||x.UNKNOWN_ERROR,url:Be(),deviceInfo:Qe(),stackTrace:o,reporter:this._reporter,integration:this._integrationName},u={Accept:"text/plain;charset=UTF-8","Content-Type":"application/json","rokt-launcher-version":this._integrationName,"rokt-wsdk-version":"joint"};this._launcherInstanceGuid&&(u["rokt-launcher-instance-guid"]=this._launcherInstanceGuid),this._accountId&&(u["rokt-account-id"]=this._accountId),fetch(e,{method:"POST",headers:u,body:JSON.stringify(c)}).then(l=>{if(!l.ok){const p=new Error("HTTP "+l.status+" from log endpoint");throw p.statusCode=l.status,p}}).catch(l=>{console.error("ReportingTransport: Failed to send log",l),s&&s(l)})}catch(c){console.error("ReportingTransport: Failed to send log",c),s&&s(c)}}}class de{constructor(e,t,n,r,o){this._transport=new j(e,t,n,r,o),this._errorUrl=ie(e?.errorUrl,e?.integrationDomain,Ve)}report(e){if(!e)return;const t=e.severity||I.ERROR;this._transport.send(this._errorUrl,t,e.message,e.code,e.stackTrace)}}class he{constructor(e,t,n,r,o,s){this._transport=new j(e,n,r,o,s),this._loggingUrl=ie(e?.loggingUrl,e?.integrationDomain,He),this._errorReportingService=t}log(e){e&&this._transport.send(this._loggingUrl,I.INFO,e.message,e.code,void 0,t=>{if(this._errorReportingService){const n=typeof t.statusCode=="number";this._errorReportingService.report({message:"LoggingService: Failed to send log: "+t.message,code:x.LOG_DELIVERY_FAILURE,severity:n?I.ERROR:I.WARNING})}})}}function Xe(i){const e=C(window.location.href),t=i.EventAttributes?.title||document.title,n=Ae(),r=i.ActiveTimeOnSite;return{pageUrl:e,sourceMessageId:i.SourceMessageId,timestamp:i.Timestamp,...t?{pageTitle:t}:{},...n!==void 0?{canonicalUrl:n}:{},...Number.isFinite(r)?{activeTimeOnSite:r}:{}}}const g=class g{constructor(){this.name=d,this.id=b,this.moduleId=b,this.isInitialized=!1,this.launcher=null,this.filters={},this.userAttributes={},this.userIdentifiedInWorkspace=!1,this.testHelpers=null,this.placementEventMappingLookup={},this.placementEventAttributeMappingLookup={},this.integrationName=null,this.errorReportingService=null,this.loggingService=null,this._thankYouElementOnLoadCallback=null,this._isThankYouElementLoaded=!1,this._workspaceSearchInFlightPromise=null,this._launcherAttachState=ke()}getEventAttributeValue(e,t){const n=e&&e.EventAttributes;return!n||typeof n[t]>"u"?null:n[t]}doesEventAttributeConditionMatch(e,t){if(!e||!E(e.operator))return!1;const n=e.operator.toLowerCase(),r=e.attributeValue;return n==="exists"?t!==null:t==null?!1:n==="equals"?String(t)===String(r):n==="contains"?String(t).indexOf(String(r))!==-1:!1}doesEventMatchRule(e,t){if(!t||!E(t.eventAttributeKey))return!1;const n=t.conditions;if(!Array.isArray(n))return!1;const r=this.getEventAttributeValue(e,t.eventAttributeKey);if(n.length===0)return r!==null;for(let o=0;o{await qe([...n],s),this.initRoktLauncher(s)}).catch(s=>{be(this._launcherAttachState),console.error("Error creating Rokt launcher:",s)})}recreateLauncherIfTerminated(){return Le(this._launcherAttachState,this.isLauncherReadyToAttach(),e=>this.attachLauncher(e.accountId,e.launcherOptions,e.legacyRoktExtensions))}initRoktLauncher(e){window.Rokt&&(window.Rokt.currentLauncher=e),this.launcher=e,ve(this._launcherAttachState);const t=a().Rokt?.filters;t?(this.filters=t,t.filteredUser?this._workspaceSearchInFlightPromise=this.search(t.filteredUser):console.warn("Rokt Kit: No filtered user has been set.")):console.warn("Rokt Kit: No filters have been set."),this.isInitialized=!0,le(this.domain,this.integrationName),a().Rokt.attachKit(this)}fetchOptimizely(){const e=a()._getActiveForwarders().filter(t=>t.name==="Optimizely");try{if(e.length>0&&window.optimizely){const t=window.optimizely.get("state");return!t||!t.getActiveExperimentIds?{}:t.getActiveExperimentIds().reduce((o,s)=>(o["rokt.custom.optimizely.experiment."+s+".variationId"]=t.getVariationMap()[s].id,o),{})}}catch(t){console.error("Error fetching Optimizely attributes:",t)}return{}}isKitReady(){return!!(this.isInitialized&&this.launcher)}isTargetingDisabled(){return a().Rokt?.launcherOptions?.noTargeting===!0}isPartnerInLocalLauncherTestGroup(){return!!(a().config&&a().config.isLocalLauncherEnabled&&this.isAssignedToSampleGroup())}isAssignedToSampleGroup(){return Math.random()>.5}captureTiming(e){window&&a()&&a().captureTiming&&e&&a().captureTiming(e)}init(e,t,n,r,o){const s=e,c=s.accountId;this.userAttributes=R(o),this._onboardingExpProvider=s.onboardingExpProvider;const u=L(s.placementEventMapping);this.placementEventMappingLookup=oe(u);const l=L(s.placementEventAttributeMapping);this.placementEventAttributeMappingLookup=se(l),s.hashedEmailUserIdentityType&&(this._mappedEmailSha256Key=s.hashedEmailUserIdentityType.toLowerCase()),this._workspaceIdSyncApiKey=E(s.workspaceIdSyncApiKey)?s.workspaceIdSyncApiKey:void 0;const p=a().Rokt?.domain,{roktExtensionsQueryParams:G,legacyRoktExtensions:P,loadThankYouElement:O}=re(s.roktExtensions),f={...a().Rokt?.launcherOptions||{}};this.integrationName=$e(f.integrationName),f.integrationName=this.integrationName,this.domain=p;const A={loggingUrl:s.loggingUrl,errorUrl:s.errorUrl,integrationDomain:p,isLoggingEnabled:a().config?.isLoggingEnabled===!0},y=new de(A,this.integrationName,window.__rokt_li_guid__,s.accountId),k=new he(A,y,this.integrationName,window.__rokt_li_guid__,s.accountId);if(this.errorReportingService=y,this.loggingService=k,this.isTargetingDisabled())try{Q(),X()}catch(h){this.errorReportingService?.report({message:"Rokt Kit: Failed to clear page views when targeting is disabled",code:"PAGE_VIEW_CAPTURE_FAILED",severity:I.INFO,stackTrace:h instanceof Error?h.stack:void 0})}return a()._registerErrorReportingService&&a()._registerErrorReportingService(y),a()._registerLoggingService&&a()._registerLoggingService(k),n?(this.testHelpers={generateLauncherScript:ee,generateThankYouElementScript:te,extractRoktExtensionConfig:re,hashEventMessage:ae,parseSettingsString:L,generateMappedEventLookup:oe,generateMappedEventAttributeLookup:se,sendAdBlockMeasurementSignals:le,createAutoRemovedIframe:Y,djb2:ce,setAllowedOriginHashes:h=>{g._allowedOriginHashes=h},ReportingTransport:j,ErrorReportingService:de,LoggingService:he,RateLimiter:ue,ErrorCodes:x,WSDKErrorSeverity:I,resetLauncherAttachState:()=>Te(this._launcherAttachState)},this.attachLauncher(c,f),"Successfully initialized: "+d):(O&&(a().Rokt.flushOnShoppableAdsReadyMessageQueue?.(this),ne(Me,te(p),{onLoad:()=>{this._isThankYouElementLoaded=!0,this._thankYouElementOnLoadCallback&&this._thankYouElementOnLoadCallback()},onError:h=>{console.error("Error loading Rokt Thank You Element script:",h)}})),this.isLauncherReadyToAttach()?this.attachLauncher(c,f,P):(ne(Ce,ee(p,G),{onLoad:()=>{this.isLauncherReadyToAttach()?this.attachLauncher(c,f,P):console.error("Rokt object is not available after script load.")},onError:h=>{console.error("Error loading Rokt launcher script:",h)}}),this.captureTiming(g.PERFORMANCE_MARKS.RoktScriptAppended)),"Successfully initialized: "+d)}process(e){if(this.isTargetingDisabled()||(e.EventDataType===Fe&&(Se(this.loggingService),this.capturePageView(e)),e.EventDataType===De&&(Q(),X())),!this.isKitReady())return"Kit not ready for forwarder: "+d;if(v(a().Rokt?.setLocalSessionAttribute)&&(U(this.placementEventAttributeMappingLookup)||this.applyPlacementEventAttributeMapping(e),!U(this.placementEventMappingLookup))){const t=ae(e.EventDataType,e.EventCategory,e.EventName??"");this.placementEventMappingLookup[String(t)]&&a().Rokt.setLocalSessionAttribute?.(this.placementEventMappingLookup[String(t)],!0)}return"Successfully sent to forwarder: "+d}setExtensionData(e){if(!this.isKitReady()){console.error("Rokt Kit: Not initialized");return}window.Rokt.setExtensionData(e)}setUserAttribute(e,t){return W(e)||(this.userAttributes[e]=t),"Successfully set user attribute for forwarder: "+d}removeUserAttribute(e){return delete this.userAttributes[e],"Successfully removed user attribute for forwarder: "+d}handleIdentityComplete(e,t){return this.userAttributes=R(e.getAllUserAttributes()),"Successfully called "+t+" for forwarder: "+d}onUserIdentified(e){const t=e;return this.filters.filteredUser=t,this._workspaceSearchInFlightPromise=this.search(t),this.handleIdentityComplete(e,"onUserIdentified")}search(e){const t=this._workspaceIdSyncApiKey;if(!t)return this.userIdentifiedInWorkspace=!1,this._workspaceLastSearchedIdentitiesKey=void 0,Promise.resolve();const n=a().Identity?.search;if(typeof n!="function")return this.userIdentifiedInWorkspace=!1,this._workspaceLastSearchedIdentitiesKey=void 0,Promise.resolve();const r=e.getUserIdentities?e.getUserIdentities().userIdentities:null,o={};if(r)for(const u of Object.keys(r)){const l=r[u];E(l)&&l.length>0&&(o[u]=l)}const s=Object.keys(o);if(s.length===0)return this.userIdentifiedInWorkspace=!1,this._workspaceLastSearchedIdentitiesKey=void 0,Promise.resolve();const c=s.sort().map(u=>`${u}=${o[u]}`).join("&");return c===this._workspaceLastSearchedIdentitiesKey?this._workspaceSearchInFlightPromise||Promise.resolve():(this.userIdentifiedInWorkspace=!1,this._workspaceLastSearchedIdentitiesKey=c,new Promise(u=>{try{n(t,o,l=>{l?.httpCode===200&&(this.userIdentifiedInWorkspace=!0),u()})}catch(l){console.error("Rokt Kit: Workspace IDSync search failed",l),this._workspaceLastSearchedIdentitiesKey=void 0,u()}}))}onLoginComplete(e,t){return this.handleIdentityComplete(e,"onLoginComplete")}onLogoutComplete(e,t){return this.userIdentifiedInWorkspace=!1,this._workspaceSearchInFlightPromise=null,this._workspaceLastSearchedIdentitiesKey=void 0,this.handleIdentityComplete(e,"onLogoutComplete")}onModifyComplete(e,t){return this.handleIdentityComplete(e,"onModifyComplete")}selectPlacements(e){const t=this.recreateLauncherIfTerminated();if(t){const n=this._workspaceSearchInFlightPromise,r=n?Promise.race([n,new Promise(o=>setTimeout(o,Z))]):Promise.resolve();return Promise.all([t,r]).then(()=>this._dispatchPlacements(e))}if(this._workspaceSearchInFlightPromise){const n=this._workspaceSearchInFlightPromise;return Promise.race([n,new Promise(r=>setTimeout(r,Z))]).then(()=>this._dispatchPlacements(e))}return this._dispatchPlacements(e)}_dispatchPlacements(e){const t=e&&e.attributes||{},r={...R(this.userAttributes),...t},o=this.filters||{},s=o.userAttributeFilters||[],c=o.filteredUser||null,u=c?c.getMPID():null;let l;o?o.filterUserAttributes?l=o.filterUserAttributes(r,s):l=r:(console.warn("Rokt Kit: No filters available, using user attributes"),l=r),this.userAttributes=R(l);const p=this._onboardingExpProvider==="Optimizely"?this.fetchOptimizely():{},G=this.returnUserIdentities(c),P=this.returnLocalSessionAttributes(),O=Ie(B()),f=ye(),A=this.readMpSessionId(),y=this.readMpDeviceId(),k={...G,...l,...p,...P,...O.length?{[xe]:JSON.stringify(O)}:{},...f?{[Ye]:f}:{},...this.userIdentifiedInWorkspace?{[Ke]:!0}:{},...A?{[je]:A}:{},...y?{[Ge]:y}:{},mpid:u},h={...e,attributes:k},pe=this.launcher.selectPlacements(h),tt=()=>this.logSelectPlacementsEvent(k);return Promise.resolve(pe).then(it=>it?.context?.sessionId?.then(nt=>this.setRoktSessionId(nt))).catch(()=>{}).finally(tt),pe}hashAttributes(e){return this.isKitReady()?this.launcher.hashAttributes(e):(console.error("Rokt Kit: Not initialized"),null)}use(e){return this.isKitReady()?!e||!E(e)?Promise.reject(new Error("Rokt Kit: Invalid extension name")):this.launcher.use(e):(console.error("Rokt Kit: Not initialized"),Promise.reject(new Error("Rokt Kit: Not initialized")))}terminate(){return this.isKitReady()?(we(this._launcherAttachState),this.launcher.terminate()):(console.error("Rokt Kit: Not initialized"),Promise.resolve())}onShoppableAdsReady(e){this._isThankYouElementLoaded?e():this._thankYouElementOnLoadCallback=e}};g._allowedOriginHashes=[-553112570,549508659],g.PERFORMANCE_MARKS={RoktScriptAppended:"mp:RoktScriptAppended"},g.EMAIL_SHA256_KEY="emailsha256";let S=g;function Ze(){return b}function et(i){if(!i){window.console.log("You must pass a config object to register the kit "+d);return}if(!m(i)){window.console.log("'config' must be an object. You passed in a "+typeof i);return}m(i.kits)?i.kits[d]={constructor:S}:(i.kits={},i.kits[d]={constructor:S}),window.console.log("Successfully registered "+d+" to your mParticle configuration")}return typeof window<"u"&&window.mParticle&&a().addForwarder&&a().addForwarder({name:d,constructor:S,getId:Ze}),N.register=et,Object.defineProperty(N,Symbol.toStringTag,{value:"Module"}),N})({}); //# sourceMappingURL=Rokt-Kit.iife.js.map diff --git a/kits/rokt/dist/Rokt-Kit.iife.js.map b/kits/rokt/dist/Rokt-Kit.iife.js.map index 616a6bf33..2efeac55c 100644 --- a/kits/rokt/dist/Rokt-Kit.iife.js.map +++ b/kits/rokt/dist/Rokt-Kit.iife.js.map @@ -1 +1 @@ -{"version":3,"file":"Rokt-Kit.iife.js","sources":["../src/selectPlacementsAttributePersistence.ts","../src/Rokt-Kit.ts"],"sourcesContent":["const SELECT_PLACEMENTS_ATTRIBUTE_PERSISTENCE_DENY_LIST = [\n 'billingaddress1',\n 'billingaddress2',\n 'billingcity',\n 'billingstate',\n 'billingzipcode',\n 'cartitems',\n 'ccbin',\n 'confirmationref',\n 'conversiontype',\n 'country',\n 'couponcode',\n 'currency',\n 'language',\n 'paymentserviceprovider',\n 'paymentserviceproviderattribute',\n 'paymenttype',\n 'shippingaddress1',\n 'shippingcity',\n 'shippingcountry',\n 'shippingmethod',\n 'shippingstate',\n 'shippingzipcode',\n 'totalprice',\n];\nconst SELECT_PLACEMENTS_ATTRIBUTE_PERSISTENCE_DENY_SET = new Set(SELECT_PLACEMENTS_ATTRIBUTE_PERSISTENCE_DENY_LIST);\n\nexport function isSelectPlacementsAttributePersistenceDenied(key: string): boolean {\n return SELECT_PLACEMENTS_ATTRIBUTE_PERSISTENCE_DENY_SET.has(key.toLowerCase());\n}\n\nexport function removeSelectPlacementsAttributePersistenceDeniedAttributes(\n attributes: Record | null | undefined,\n): Record {\n const filteredAttributes: Record = {};\n const sourceAttributes = attributes || {};\n const attributeKeys = Object.keys(sourceAttributes);\n\n for (let i = 0; i < attributeKeys.length; i++) {\n const key = attributeKeys[i];\n if (!isSelectPlacementsAttributePersistenceDenied(key)) {\n filteredAttributes[key] = sourceAttributes[key];\n }\n }\n\n return filteredAttributes;\n}\n","// Copyright 2025 mParticle, Inc.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n// ============================================================\n// Types\n// ============================================================\n\nimport { KitInterface, IMParticleUser, SDKEvent } from '@mparticle/web-sdk/internal';\nimport type { IUserIdentities } from '@mparticle/web-sdk';\n\nimport {\n isSelectPlacementsAttributePersistenceDenied,\n removeSelectPlacementsAttributePersistenceDeniedAttributes,\n} from './selectPlacementsAttributePersistence';\n\ninterface RoktKitSettings {\n accountId: string;\n roktExtensions?: string;\n placementEventMapping?: string;\n placementEventAttributeMapping?: string;\n hashedEmailUserIdentityType?: string;\n onboardingExpProvider?: string;\n loggingUrl?: string;\n errorUrl?: string;\n workspaceIdSyncApiKey?: string;\n}\n\ninterface EventAttributeCondition {\n operator: string;\n attributeValue: string;\n}\n\ninterface PlacementEventRule {\n eventAttributeKey: string;\n conditions: EventAttributeCondition[];\n}\n\ninterface EventAttributeMapping {\n value: string;\n map: string;\n conditions?: EventAttributeCondition[];\n}\n\ninterface PlacementEventMappingEntry {\n jsmap: string;\n value: string;\n}\n\ninterface RoktExtensionEntry {\n value: string;\n}\n\ninterface RoktSelection {\n context?: {\n sessionId?: Promise;\n };\n then?: (callback: (sel: RoktSelection) => void) => Promise;\n catch?: (callback: () => void) => void;\n}\n\ninterface RoktLauncher {\n selectPlacements(options: Record): RoktSelection | Promise;\n hashAttributes(attributes: Record): Promise>;\n use(extensionName: string): Promise;\n}\n\ninterface RoktGlobal {\n createLauncher(options: Record): Promise;\n createLocalLauncher(options: Record): RoktLauncher;\n currentLauncher?: RoktLauncher;\n setExtensionData(data: Record): void;\n}\n\n// FilteredUser is the IMParticleUser shape we receive after kit filtering.\n// `getMPID` and `getUserIdentities` are inherited from the SDK's `User` base type.\ntype FilteredUser = IMParticleUser;\n\n// TODO: Replace with `IIdentitySearchResult` from `@mparticle/web-sdk` once\n// a version that exports it is published (currently on a feature branch in\n// mParticle/mparticle-web-sdk PR #1255). The shape below is intentionally\n// structurally identical so the swap is a one-line import change.\ninterface WorkspaceIdSyncResult {\n httpCode: number;\n body?: {\n context?: string | null;\n mpid?: string;\n matched_identities?: Record;\n is_ephemeral?: boolean;\n is_logged_in?: boolean;\n };\n}\n\n// TODO: Replace with `IdentitySearchCallback`-compatible reference from\n// `@mparticle/web-sdk` once published (mirrors `SDKIdentityApi.search`).\ntype WorkspaceIdSyncSearcher = (\n apiKey: string,\n knownIdentities: IUserIdentities,\n callback: (result: WorkspaceIdSyncResult) => void,\n) => void;\n\ninterface KitFilters {\n userAttributeFilters?: string[];\n filterUserAttributes?: (attributes: Record, filters?: string[]) => Record;\n filteredUser?: FilteredUser | null;\n}\n\ninterface RoktManager {\n attachKit(kit: RoktKit): void | Promise;\n flushOnShoppableAdsReadyMessageQueue?(kit: RoktKit): void;\n filters?: KitFilters;\n domain?: string;\n launcherOptions?: Record;\n getLocalSessionAttributes?(): Record;\n setLocalSessionAttribute?(key: string, value: unknown): void;\n}\n\ninterface MParticleInstance {\n setIntegrationAttribute(moduleId: number, attrs: Record): void;\n}\n\ninterface OptimizelyState {\n getActiveExperimentIds(): string[];\n getVariationMap(): Record;\n}\n\ninterface OptimizelyGlobal {\n get(key: 'state'): OptimizelyState;\n}\n\n// Our view of the mParticle global with Rokt-specific extensions.\n// We access window.mParticle via an explicit cast (see `mp()` helper below)\n// rather than augmenting Window to avoid conflicts with @mparticle/web-sdk declarations.\ninterface MParticleExtended {\n Rokt: RoktManager;\n addForwarder(config: ForwarderRegistration): void;\n getVersion(): string;\n generateHash(value: string): string | number;\n logEvent(name: string, type: number, attrs?: Record): void;\n EventType: { Other: number };\n getInstance(): MParticleInstance;\n sessionManager?: { getSession(): string };\n _getActiveForwarders(): Array<{ name: string }>;\n config?: { isLocalLauncherEnabled?: boolean; isLoggingEnabled?: boolean };\n captureTiming?(metricName: string): void;\n forwarder?: RoktKit;\n loggedEvents?: Array>;\n _registerErrorReportingService?(service: ErrorReportingService): void;\n _registerLoggingService?(service: LoggingService): void;\n Identity?: { search?: WorkspaceIdSyncSearcher };\n}\n\ninterface TestHelpers {\n generateLauncherScript: (domain: string | undefined, extensions: string[]) => string;\n generateThankYouElementScript: (domain: string | undefined) => string;\n extractRoktExtensionConfig: (settingsString?: string) => RoktExtensionConfig;\n hashEventMessage: (messageType: number, eventType: number, eventName: string) => string | number;\n parseSettingsString: (settingsString?: string) => T[];\n generateMappedEventLookup: (placementEventMapping: PlacementEventMappingEntry[]) => Record;\n generateMappedEventAttributeLookup: (mapping: EventAttributeMapping[]) => Record;\n sendAdBlockMeasurementSignals: (domain: string | undefined, version: string | null) => void;\n createAutoRemovedIframe: (src: string) => void;\n djb2: (str: string) => number;\n setAllowedOriginHashes: (hashes: number[]) => void;\n ReportingTransport: typeof ReportingTransport;\n ErrorReportingService: typeof ErrorReportingService;\n LoggingService: typeof LoggingService;\n RateLimiter: typeof RateLimiter;\n ErrorCodes: typeof ErrorCodes;\n WSDKErrorSeverity: typeof WSDKErrorSeverity;\n}\n\ninterface ForwarderRegistration {\n name: string;\n constructor: new () => RoktKit;\n getId: () => number;\n}\n\ninterface ReportingConfig {\n loggingUrl?: string;\n errorUrl?: string;\n integrationDomain?: string;\n isLoggingEnabled: boolean;\n}\n\ninterface ErrorReport {\n message: string;\n code?: string;\n severity?: string;\n stackTrace?: string;\n}\n\n// A log-delivery failure. statusCode is set when the request reached the server\n// and returned a non-2xx status (server-side); it is absent for network-level\n// failures such as ad-blockers, offline, or CORS rejections (client-side).\ninterface DeliveryError extends Error {\n statusCode?: number;\n}\n\ninterface LogEntry {\n message: string;\n code?: string;\n}\n\ninterface RoktExtensionConfig {\n roktExtensionsQueryParams: string[];\n legacyRoktExtensions: string[];\n loadThankYouElement: boolean;\n}\n\ndeclare global {\n interface Window {\n Rokt?: RoktGlobal;\n __rokt_li_guid__?: string;\n optimizely?: OptimizelyGlobal;\n // mParticle is declared as any to avoid conflicts with @mparticle/web-sdk type declarations.\n // We use the typed mp() accessor for all internal accesses.\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n mParticle: any;\n }\n}\n\n// ============================================================\n// Module-level constants\n// ============================================================\n\nconst name = 'Rokt';\nconst moduleId = 181;\nconst EVENT_NAME_SELECT_PLACEMENTS = 'selectPlacements';\nconst ADBLOCK_CONTROL_DOMAIN = 'apps.roktecommerce.com';\nconst INIT_LOG_SAMPLING_RATE = 0.1;\nconst ROKT_THANK_YOU_JOURNEY_EXTENSION = 'ThankYouPageJourney';\nconst ROKT_INTEGRATION_SCRIPT_ID = 'rokt-launcher';\nconst ROKT_THANK_YOU_ELEMENT_SCRIPT_ID = 'rokt-thank-you-element';\nconst USER_IDENTIFIED_IN_WORKSPACE_KEY = 'userIdentifiedInWorkspace';\n\n// Bound on how long selectPlacements will wait for an in-flight Workspace\n// IDSync search before proceeding without the userIdentifiedInWorkspace flag.\n// Long enough to cover the typical /v1/search round-trip (~50ms); short enough that a\n// stalled search never blocks placement rendering on a thank-you page.\nconst WORKSPACE_SEARCH_SELECT_TIMEOUT_MS = 500;\n\n// ============================================================\n// Reporting service constants\n// ============================================================\n\nconst ErrorCodes = {\n UNKNOWN_ERROR: 'UNKNOWN_ERROR',\n UNHANDLED_EXCEPTION: 'UNHANDLED_EXCEPTION',\n IDENTITY_REQUEST: 'IDENTITY_REQUEST',\n LOG_DELIVERY_FAILURE: 'LOG_DELIVERY_FAILURE',\n} as const;\n\nconst WSDKErrorSeverity = {\n ERROR: 'ERROR',\n INFO: 'INFO',\n WARNING: 'WARNING',\n} as const;\n\nconst DEFAULT_ROKT_DOMAIN = 'apps.rokt-api.com';\nconst LOGGING_ENDPOINT = '/v1/log';\nconst ERROR_ENDPOINT = '/v1/errors';\nconst RATE_LIMIT_PER_SEVERITY = 10;\n\n// ============================================================\n// Helper: typed accessor for window.mParticle\n// We use an explicit cast here to avoid conflicts with @mparticle/web-sdk\n// type declarations while still providing full type safety for our usages.\n// ============================================================\n\nfunction mp(): MParticleExtended {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n return (window as any).mParticle as MParticleExtended;\n}\n\n// ============================================================\n// Module-level utility functions\n// ============================================================\n\nfunction generateLauncherScript(domain: string | undefined, extensions: string[]): string {\n const launcherPath = '/wsdk/integrations/launcher.js';\n const baseUrl = [generateBaseUrl(domain), launcherPath].join('');\n\n if (!extensions || extensions.length === 0) {\n return baseUrl;\n }\n return baseUrl + '?extensions=' + extensions.join(',');\n}\n\nfunction generateThankYouElementScript(domain: string | undefined) {\n const thankYouElementPath = '/rokt-elements/rokt-element-thank-you.js';\n return [generateBaseUrl(domain), thankYouElementPath].join('');\n}\n\nfunction generateBaseUrl(domain: string | undefined) {\n const resolvedDomain = typeof domain !== 'undefined' ? domain : DEFAULT_ROKT_DOMAIN;\n const protocol = 'https://';\n\n return [protocol, resolvedDomain].join('');\n}\n\nfunction generateReportingUrl(configuredUrl: string | undefined, domain: string | undefined, endpoint: string): string {\n if (configuredUrl) {\n if (configuredUrl.startsWith('http://') || configuredUrl.startsWith('https://')) {\n return configuredUrl;\n }\n return 'https://' + configuredUrl;\n }\n\n return generateBaseUrl(domain) + endpoint;\n}\n\nfunction loadRoktScript(\n scriptId: string,\n source: string,\n handlers?: { onLoad?: () => void; onError?: (e: Event | string) => void },\n): void {\n if (document.getElementById(scriptId)) return; // resolves the preexisting script issue\n\n const target = document.head || document.body;\n const script = document.createElement('script');\n script.id = scriptId;\n script.type = 'text/javascript';\n script.src = source;\n script.async = true;\n script.crossOrigin = 'anonymous';\n (script as HTMLScriptElement & { fetchPriority: string }).fetchPriority = 'high';\n if (handlers?.onLoad) script.onload = handlers.onLoad;\n if (handlers?.onError) script.onerror = handlers.onError;\n target.appendChild(script);\n}\n\nfunction isObject(val: unknown): val is Record {\n return val != null && typeof val === 'object' && Array.isArray(val) === false;\n}\n\nfunction parseSettingsString(settingsString?: string): T[] {\n if (!settingsString) {\n return [];\n }\n try {\n return JSON.parse(settingsString.replace(/"/g, '\"')) as T[];\n } catch (_error) {\n console.error('Settings string contains invalid JSON');\n }\n return [];\n}\n\nfunction extractRoktExtensionConfig(settingsString?: string): RoktExtensionConfig {\n const settings = settingsString ? parseSettingsString(settingsString) : [];\n const roktExtensionsQueryParams: string[] = [];\n const legacyRoktExtensions: string[] = [];\n let loadThankYouElement = false;\n\n for (let i = 0; i < settings.length; i++) {\n const extensionName = settings[i].value;\n if (extensionName === 'thank-you-journey') {\n loadThankYouElement = true;\n legacyRoktExtensions.push(ROKT_THANK_YOU_JOURNEY_EXTENSION);\n } else {\n roktExtensionsQueryParams.push(extensionName);\n }\n }\n\n return {\n roktExtensionsQueryParams,\n legacyRoktExtensions,\n loadThankYouElement,\n };\n}\n\nasync function registerLegacyExtensions(legacyExtensions: string[], launcher: RoktLauncher | null) {\n const extensions: Promise[] = [];\n if (launcher) {\n for (const extension of legacyExtensions) {\n extensions.push(launcher.use(extension));\n }\n }\n\n return Promise.all(extensions);\n}\n\nfunction generateMappedEventLookup(placementEventMapping: PlacementEventMappingEntry[]): Record {\n if (!placementEventMapping) {\n return {};\n }\n\n const mappedEvents: Record = {};\n for (let i = 0; i < placementEventMapping.length; i++) {\n const mapping = placementEventMapping[i];\n mappedEvents[mapping.jsmap] = mapping.value;\n }\n return mappedEvents;\n}\n\nfunction generateMappedEventAttributeLookup(\n placementEventAttributeMapping: EventAttributeMapping[],\n): Record {\n const mappedAttributeKeys: Record = {};\n if (!Array.isArray(placementEventAttributeMapping)) {\n return mappedAttributeKeys;\n }\n for (let i = 0; i < placementEventAttributeMapping.length; i++) {\n const mapping = placementEventAttributeMapping[i];\n if (!mapping || !isString(mapping.value) || !isString(mapping.map)) {\n continue;\n }\n\n const mappedAttributeKey = mapping.value;\n const eventAttributeKey = mapping.map;\n\n if (!mappedAttributeKeys[mappedAttributeKey]) {\n mappedAttributeKeys[mappedAttributeKey] = [];\n }\n\n mappedAttributeKeys[mappedAttributeKey].push({\n eventAttributeKey: eventAttributeKey,\n conditions: Array.isArray(mapping.conditions) ? mapping.conditions : [],\n });\n }\n return mappedAttributeKeys;\n}\n\nfunction hashEventMessage(messageType: number, eventType: number, eventName: string): string | number {\n return mp().generateHash([messageType, eventType, eventName].join(''));\n}\n\nfunction isEmpty(value: unknown): boolean {\n if (value == null) return true;\n if (typeof value === 'object') {\n return Object.keys(value as object).length === 0;\n }\n if (Array.isArray(value)) {\n return (value as unknown[]).length === 0;\n }\n return false;\n}\n\nfunction isString(value: unknown): value is string {\n return typeof value === 'string';\n}\n\nfunction generateIntegrationName(customIntegrationName?: string): string {\n const coreSdkVersion = mp().getVersion();\n const kitVersion = process.env.PACKAGE_VERSION;\n let integrationName = 'mParticle_' + 'wsdkv_' + coreSdkVersion + '_kitv_' + kitVersion;\n\n if (customIntegrationName) {\n integrationName += '_' + customIntegrationName;\n }\n return integrationName;\n}\n\nfunction djb2(str: string): number {\n let hash = 5381;\n for (let i = 0; i < str.length; i++) {\n hash = (hash << 5) + hash + str.charCodeAt(i);\n hash = hash & hash;\n }\n return hash;\n}\n\nfunction createAutoRemovedIframe(src: string): void {\n const iframe = document.createElement('iframe');\n iframe.style.display = 'none';\n iframe.setAttribute('sandbox', 'allow-scripts allow-same-origin');\n iframe.src = src;\n iframe.onload = function () {\n iframe.onload = null;\n if (iframe.parentNode) {\n iframe.parentNode.removeChild(iframe);\n }\n };\n const target = document.body || document.head;\n if (target) {\n target.appendChild(iframe);\n }\n}\n\nfunction sendAdBlockMeasurementSignals(domain: string | undefined, version: string | null): void {\n const originHash = djb2(window.location.origin);\n const allowedOriginHashes = RoktKit._allowedOriginHashes;\n if (allowedOriginHashes.indexOf(originHash) === -1) {\n return;\n }\n\n if (Math.random() >= INIT_LOG_SAMPLING_RATE) {\n return;\n }\n\n const guid = window.__rokt_li_guid__;\n if (!guid) {\n return;\n }\n\n const pageUrl = window.location.href.split('?')[0].split('#')[0];\n const params =\n 'version=' +\n encodeURIComponent(version ?? '') +\n '&launcherInstanceGuid=' +\n encodeURIComponent(guid) +\n '&pageUrl=' +\n encodeURIComponent(pageUrl);\n\n const existingDomain = domain || 'apps.rokt.com';\n createAutoRemovedIframe('https://' + existingDomain + '/v1/wsdk-init/index.html?' + params);\n\n createAutoRemovedIframe(\n 'https://' + ADBLOCK_CONTROL_DOMAIN + '/v1/wsdk-init/index.html?' + params + '&isControl=true',\n );\n}\n\n// ============================================================\n// Reporting helpers\n// ============================================================\n\nfunction _isDebugModeEnabled(): boolean {\n return typeof window !== 'undefined' && !!window.location?.search?.toLowerCase().includes('mp_enable_logging=true');\n}\n\nfunction _getReportingUrl(): string | undefined {\n return typeof window !== 'undefined' ? window.location?.href : undefined;\n}\n\nfunction _getUserAgent(): string | undefined {\n return typeof window !== 'undefined' ? window.navigator?.userAgent : undefined;\n}\n\nclass RateLimiter {\n private _logCount: Record = {};\n\n incrementAndCheck(severity: string): boolean {\n const count = this._logCount[severity] || 0;\n const newCount = count + 1;\n this._logCount[severity] = newCount;\n return newCount > RATE_LIMIT_PER_SEVERITY;\n }\n}\n\nclass ReportingTransport {\n private _isEnabled: boolean;\n private _integrationName: string;\n private _launcherInstanceGuid: string | undefined;\n private _accountId: string | null;\n private _rateLimiter: RateLimiter;\n private readonly _reporter = 'mp-wsdk';\n\n constructor(\n config: ReportingConfig,\n integrationName: string | null | undefined,\n launcherInstanceGuid: string | undefined,\n accountId: string | null | undefined,\n rateLimiter?: RateLimiter,\n ) {\n const isLoggingEnabled = config.isLoggingEnabled;\n this._integrationName = integrationName || '';\n this._launcherInstanceGuid = launcherInstanceGuid;\n this._accountId = accountId || null;\n this._rateLimiter = rateLimiter || new RateLimiter();\n this._isEnabled = _isDebugModeEnabled() || isLoggingEnabled;\n }\n\n send(\n url: string,\n severity: string,\n msg: string,\n code?: string,\n stackTrace?: string,\n onError?: (error: DeliveryError) => void,\n ): void {\n if (!this._isEnabled || this._rateLimiter.incrementAndCheck(severity)) {\n return;\n }\n\n try {\n const logRequest = {\n additionalInformation: {\n message: msg,\n version: this._integrationName,\n },\n severity,\n code: code || ErrorCodes.UNKNOWN_ERROR,\n url: _getReportingUrl(),\n deviceInfo: _getUserAgent(),\n stackTrace,\n reporter: this._reporter,\n integration: this._integrationName,\n };\n\n const headers: Record = {\n Accept: 'text/plain;charset=UTF-8',\n 'Content-Type': 'application/json',\n 'rokt-launcher-version': this._integrationName,\n 'rokt-wsdk-version': 'joint',\n };\n\n if (this._launcherInstanceGuid) {\n headers['rokt-launcher-instance-guid'] = this._launcherInstanceGuid;\n }\n if (this._accountId) {\n headers['rokt-account-id'] = this._accountId;\n }\n\n fetch(url, {\n method: 'POST',\n headers,\n body: JSON.stringify(logRequest),\n })\n .then((response: Response) => {\n // fetch only rejects on network failures; an HTTP 5xx resolves with\n // ok === false. Surface server-side failures so they are not swallowed.\n if (!response.ok) {\n const serverError: DeliveryError = new Error('HTTP ' + response.status + ' from log endpoint');\n serverError.statusCode = response.status;\n throw serverError;\n }\n })\n .catch((error: DeliveryError) => {\n console.error('ReportingTransport: Failed to send log', error);\n if (onError) onError(error);\n });\n } catch (error) {\n console.error('ReportingTransport: Failed to send log', error);\n if (onError) onError(error as DeliveryError);\n }\n }\n}\n\nclass ErrorReportingService {\n private _transport: ReportingTransport;\n private _errorUrl: string;\n\n constructor(\n config: ReportingConfig,\n integrationName: string | null | undefined,\n launcherInstanceGuid?: string,\n accountId?: string | null,\n rateLimiter?: RateLimiter,\n ) {\n this._transport = new ReportingTransport(config, integrationName, launcherInstanceGuid, accountId, rateLimiter);\n this._errorUrl = generateReportingUrl(config?.errorUrl, config?.integrationDomain, ERROR_ENDPOINT);\n }\n\n report(error: ErrorReport | null | undefined): void {\n if (!error) return;\n const severity = error.severity || WSDKErrorSeverity.ERROR;\n this._transport.send(this._errorUrl, severity, error.message, error.code, error.stackTrace);\n }\n}\n\nclass LoggingService {\n private _transport: ReportingTransport;\n private _loggingUrl: string;\n private _errorReportingService: { report: (e: ErrorReport) => void };\n\n constructor(\n config: ReportingConfig,\n errorReportingService: { report: (e: ErrorReport) => void },\n integrationName: string | null | undefined,\n launcherInstanceGuid?: string,\n accountId?: string | null,\n rateLimiter?: RateLimiter,\n ) {\n this._transport = new ReportingTransport(config, integrationName, launcherInstanceGuid, accountId, rateLimiter);\n this._loggingUrl = generateReportingUrl(config?.loggingUrl, config?.integrationDomain, LOGGING_ENDPOINT);\n this._errorReportingService = errorReportingService;\n }\n\n log(entry: LogEntry | null | undefined): void {\n if (!entry) return;\n this._transport.send(\n this._loggingUrl,\n WSDKErrorSeverity.INFO,\n entry.message,\n entry.code,\n undefined,\n (error: DeliveryError) => {\n if (this._errorReportingService) {\n // A failed log POST is not itself an SDK error. Network-level failures\n // (ad-blockers, offline, CORS) are client-side noise and reported as a\n // WARNING; only a server-side non-2xx response stays at ERROR severity.\n const isServerSide = typeof error.statusCode === 'number';\n this._errorReportingService.report({\n message: 'LoggingService: Failed to send log: ' + error.message,\n code: ErrorCodes.LOG_DELIVERY_FAILURE,\n severity: isServerSide ? WSDKErrorSeverity.ERROR : WSDKErrorSeverity.WARNING,\n });\n }\n },\n );\n }\n}\n\n// ============================================================\n// RoktKit class\n// ============================================================\n\nclass RoktKit implements KitInterface {\n // Static field for allowed origin hashes (mutable by testHelpers)\n public static _allowedOriginHashes: number[] = [-553112570, 549508659];\n\n private static readonly PERFORMANCE_MARKS = {\n RoktScriptAppended: 'mp:RoktScriptAppended',\n };\n\n private static readonly EMAIL_SHA256_KEY = 'emailsha256';\n\n // Public fields (accessed by tests and the mParticle framework)\n public name = name;\n public id = moduleId;\n public moduleId = moduleId;\n public isInitialized = false;\n public launcher: RoktLauncher | null = null;\n public filters: KitFilters = {};\n public userAttributes: Record = {};\n // Flag set by the Workspace IDSync flow on a 200 response. Stored on the\n // kit instance and merged into placement attributes inside selectPlacements.\n public userIdentifiedInWorkspace = false;\n public testHelpers: TestHelpers | null = null;\n public placementEventMappingLookup: Record = {};\n public placementEventAttributeMappingLookup: Record = {};\n public integrationName: string | null = null;\n public domain?: string;\n public errorReportingService: ErrorReportingService | null = null;\n public loggingService: LoggingService | null = null;\n\n // Private fields\n private _mappedEmailSha256Key?: string;\n private _onboardingExpProvider?: string;\n private _thankYouElementOnLoadCallback: (() => void) | null = null;\n private _isThankYouElementLoaded = false;\n private _workspaceIdSyncApiKey?: string;\n\n // Held during a search dispatch so the next selectPlacements call;\n // can wait for the HTTP response before reading userIdentifiedInWorkspace;\n // — otherwise the first placement call ships without the flag.\n private _workspaceSearchInFlightPromise: Promise | null = null;\n // Stable serialization of the identifier set sent in the most recent\n // successful search dispatch. If a subsequent identification arrives with\n // an identical set, we skip the network call (the flag is still correct\n // from the prior search). Keyed over the full IUserIdentities map — not\n // just email — so partners passing hashed email through `other`/`other2-10`\n // or any other identifier benefit from the same dedupe. Cleared on logout\n // so a re-login re-evaluates fresh.\n private _workspaceLastSearchedIdentitiesKey?: string;\n\n // ---- Private helpers ----\n\n private getEventAttributeValue(event: SDKEvent, eventAttributeKey: string): unknown {\n const attributes = event && event.EventAttributes;\n if (!attributes) {\n return null;\n }\n\n if (typeof attributes[eventAttributeKey] === 'undefined') {\n return null;\n }\n\n return attributes[eventAttributeKey];\n }\n\n private doesEventAttributeConditionMatch(condition: EventAttributeCondition, actualValue: unknown): boolean {\n if (!condition || !isString(condition.operator)) {\n return false;\n }\n\n const operator = condition.operator.toLowerCase();\n const expectedValue = condition.attributeValue;\n\n if (operator === 'exists') {\n return actualValue !== null;\n }\n\n if (actualValue == null) {\n return false;\n }\n\n if (operator === 'equals') {\n return String(actualValue) === String(expectedValue);\n }\n\n if (operator === 'contains') {\n return String(actualValue).indexOf(String(expectedValue)) !== -1;\n }\n\n return false;\n }\n\n private doesEventMatchRule(event: SDKEvent, rule: PlacementEventRule): boolean {\n if (!rule || !isString(rule.eventAttributeKey)) {\n return false;\n }\n\n const conditions = rule.conditions;\n if (!Array.isArray(conditions)) {\n return false;\n }\n\n const actualValue = this.getEventAttributeValue(event, rule.eventAttributeKey);\n\n if (conditions.length === 0) {\n return actualValue !== null;\n }\n for (let i = 0; i < conditions.length; i++) {\n if (!this.doesEventAttributeConditionMatch(conditions[i], actualValue)) {\n return false;\n }\n }\n\n return true;\n }\n\n private applyPlacementEventAttributeMapping(event: SDKEvent): void {\n const mappedAttributeKeys = Object.keys(this.placementEventAttributeMappingLookup);\n for (let i = 0; i < mappedAttributeKeys.length; i++) {\n const mappedAttributeKey = mappedAttributeKeys[i];\n const rulesForMappedAttributeKey = this.placementEventAttributeMappingLookup[mappedAttributeKey];\n if (isEmpty(rulesForMappedAttributeKey)) {\n continue;\n }\n\n // Require ALL rules for the same key to match (AND).\n let allMatch = true;\n for (let j = 0; j < rulesForMappedAttributeKey.length; j++) {\n if (!this.doesEventMatchRule(event, rulesForMappedAttributeKey[j])) {\n allMatch = false;\n break;\n }\n }\n if (!allMatch) {\n continue;\n }\n\n mp().Rokt.setLocalSessionAttribute?.(mappedAttributeKey, true);\n }\n }\n\n private isLauncherReadyToAttach(): boolean {\n return !!window.Rokt && typeof window.Rokt.createLauncher === 'function';\n }\n\n /**\n * Returns the user identities from the filtered user, if any.\n */\n private returnUserIdentities(filteredUser: FilteredUser | null | undefined): Record {\n if (!filteredUser || !filteredUser.getUserIdentities) {\n return {};\n }\n\n const userIdentities: IUserIdentities = filteredUser.getUserIdentities().userIdentities;\n\n return this.replaceOtherIdentityWithEmailsha256(userIdentities);\n }\n\n private returnLocalSessionAttributes(): Record {\n if (!mp().Rokt || typeof mp().Rokt.getLocalSessionAttributes !== 'function') {\n return {};\n }\n if (isEmpty(this.placementEventMappingLookup) && isEmpty(this.placementEventAttributeMappingLookup)) {\n return {};\n }\n return mp().Rokt.getLocalSessionAttributes!();\n }\n\n private replaceOtherIdentityWithEmailsha256(userIdentities: IUserIdentities): Record {\n const newUserIdentities: Record = { ...(userIdentities || {}) };\n const key = this._mappedEmailSha256Key;\n if (key && userIdentities[key as keyof IUserIdentities]) {\n newUserIdentities[RoktKit.EMAIL_SHA256_KEY] = userIdentities[key as keyof IUserIdentities] as string;\n }\n if (key) {\n delete newUserIdentities[key];\n }\n\n return newUserIdentities;\n }\n\n private logSelectPlacementsEvent(attributes: unknown): void {\n if (!window.mParticle || typeof mp().logEvent !== 'function') {\n return;\n }\n\n if (!isObject(attributes)) {\n return;\n }\n\n const EVENT_TYPE_OTHER = mp().EventType.Other;\n\n mp().logEvent(EVENT_NAME_SELECT_PLACEMENTS, EVENT_TYPE_OTHER, attributes as Record);\n }\n\n private setRoktSessionId(sessionId: string): void {\n if (!sessionId || typeof sessionId !== 'string') {\n return;\n }\n try {\n const mpInstance = mp().getInstance();\n if (mpInstance && typeof mpInstance.setIntegrationAttribute === 'function') {\n mpInstance.setIntegrationAttribute(moduleId, {\n roktSessionId: sessionId,\n });\n }\n } catch (_e) {\n // Best effort — never let this break the partner page\n }\n }\n\n private attachLauncher(\n accountId: string,\n launcherOptions: Record,\n legacyRoktExtensions: string[] = [],\n ): void {\n const mpSessionId =\n mp() && mp().sessionManager && typeof mp().sessionManager!.getSession === 'function'\n ? mp().sessionManager!.getSession()\n : undefined;\n\n const options: Record = {\n accountId,\n ...(launcherOptions || {}),\n ...(mpSessionId ? { mpSessionId } : {}),\n };\n\n let launcherPromise: Promise;\n if (this.isPartnerInLocalLauncherTestGroup()) {\n launcherPromise = Promise.resolve(window.Rokt!.createLocalLauncher(options));\n } else {\n launcherPromise = window.Rokt!.createLauncher(options);\n }\n\n launcherPromise\n .then(async (launcher) => {\n await registerLegacyExtensions(legacyRoktExtensions, launcher);\n this.initRoktLauncher(launcher);\n })\n .catch((err: unknown) => {\n console.error('Error creating Rokt launcher:', err);\n });\n }\n\n private initRoktLauncher(launcher: RoktLauncher): void {\n // Assign the launcher to a global variable for later access\n if (window.Rokt) {\n window.Rokt.currentLauncher = launcher;\n }\n // Locally cache the launcher and filters\n this.launcher = launcher;\n\n const roktFilters = mp().Rokt?.filters;\n\n if (!roktFilters) {\n console.warn('Rokt Kit: No filters have been set.');\n } else {\n this.filters = roktFilters;\n if (!roktFilters.filteredUser) {\n console.warn('Rokt Kit: No filtered user has been set.');\n } else {\n this._workspaceSearchInFlightPromise = this.search(roktFilters.filteredUser);\n }\n }\n\n // Kit must be initialized before attaching to the Rokt manager\n this.isInitialized = true;\n\n sendAdBlockMeasurementSignals(this.domain, this.integrationName);\n\n // Attaches the kit to the Rokt manager\n mp().Rokt.attachKit(this);\n }\n\n private fetchOptimizely(): Record {\n const forwarders = mp()\n ._getActiveForwarders()\n .filter((forwarder) => forwarder.name === 'Optimizely');\n\n try {\n if (forwarders.length > 0 && window.optimizely) {\n const optimizelyState = window.optimizely.get('state');\n if (!optimizelyState || !optimizelyState.getActiveExperimentIds) {\n return {};\n }\n const activeExperimentIds = optimizelyState.getActiveExperimentIds();\n const activeExperiments = activeExperimentIds.reduce((acc: Record, expId: string) => {\n acc['rokt.custom.optimizely.experiment.' + expId + '.variationId'] =\n optimizelyState.getVariationMap()[expId].id;\n return acc;\n }, {});\n return activeExperiments;\n }\n } catch (error) {\n console.error('Error fetching Optimizely attributes:', error);\n }\n return {};\n }\n\n private isKitReady(): boolean {\n return !!(this.isInitialized && this.launcher);\n }\n\n private isPartnerInLocalLauncherTestGroup(): boolean {\n return !!(mp().config && mp().config!.isLocalLauncherEnabled && this.isAssignedToSampleGroup());\n }\n\n private isAssignedToSampleGroup(): boolean {\n const LOCAL_LAUNCHER_TEST_GROUP_THRESHOLD = 0.5;\n return Math.random() > LOCAL_LAUNCHER_TEST_GROUP_THRESHOLD;\n }\n\n private captureTiming(metricName: string): void {\n if (window && mp() && mp().captureTiming && metricName) {\n mp().captureTiming!(metricName);\n }\n }\n\n // ---- Public methods (mParticle Kit Callbacks) ----\n\n /**\n * Initializes the Rokt forwarder with settings from the mParticle server.\n */\n public init(\n settings: Record,\n _service: unknown,\n testMode: boolean,\n _trackerId: unknown,\n filteredUserAttributes?: Record,\n ): string {\n const kitSettings = settings as unknown as RoktKitSettings;\n const accountId = kitSettings.accountId;\n this.userAttributes = removeSelectPlacementsAttributePersistenceDeniedAttributes(filteredUserAttributes);\n this._onboardingExpProvider = kitSettings.onboardingExpProvider;\n\n const placementEventMapping = parseSettingsString(kitSettings.placementEventMapping);\n this.placementEventMappingLookup = generateMappedEventLookup(placementEventMapping);\n\n const placementEventAttributeMapping = parseSettingsString(\n kitSettings.placementEventAttributeMapping,\n );\n this.placementEventAttributeMappingLookup = generateMappedEventAttributeLookup(placementEventAttributeMapping);\n\n // Set dynamic OTHER_IDENTITY based on server settings\n if (kitSettings.hashedEmailUserIdentityType) {\n this._mappedEmailSha256Key = kitSettings.hashedEmailUserIdentityType.toLowerCase();\n }\n\n this._workspaceIdSyncApiKey = isString(kitSettings.workspaceIdSyncApiKey)\n ? kitSettings.workspaceIdSyncApiKey\n : undefined;\n\n const domain = mp().Rokt?.domain;\n const { roktExtensionsQueryParams, legacyRoktExtensions, loadThankYouElement } = extractRoktExtensionConfig(\n kitSettings.roktExtensions,\n );\n const launcherOptions: Record = {\n ...((mp().Rokt?.launcherOptions as Record) || {}),\n };\n this.integrationName = generateIntegrationName(launcherOptions.integrationName as string | undefined);\n launcherOptions.integrationName = this.integrationName;\n\n this.domain = domain;\n\n const reportingConfig: ReportingConfig = {\n loggingUrl: kitSettings.loggingUrl,\n errorUrl: kitSettings.errorUrl,\n integrationDomain: domain,\n isLoggingEnabled: mp().config?.isLoggingEnabled === true,\n };\n const errorReportingService = new ErrorReportingService(\n reportingConfig,\n this.integrationName,\n window.__rokt_li_guid__,\n kitSettings.accountId,\n );\n const loggingService = new LoggingService(\n reportingConfig,\n errorReportingService,\n this.integrationName,\n window.__rokt_li_guid__,\n kitSettings.accountId,\n );\n\n this.errorReportingService = errorReportingService;\n this.loggingService = loggingService;\n\n if (mp()._registerErrorReportingService) {\n mp()._registerErrorReportingService!(errorReportingService);\n }\n if (mp()._registerLoggingService) {\n mp()._registerLoggingService!(loggingService);\n }\n\n if (testMode) {\n this.testHelpers = {\n generateLauncherScript: generateLauncherScript,\n generateThankYouElementScript: generateThankYouElementScript,\n extractRoktExtensionConfig: extractRoktExtensionConfig,\n hashEventMessage: hashEventMessage,\n parseSettingsString: parseSettingsString,\n generateMappedEventLookup: generateMappedEventLookup,\n generateMappedEventAttributeLookup: generateMappedEventAttributeLookup,\n sendAdBlockMeasurementSignals: sendAdBlockMeasurementSignals,\n createAutoRemovedIframe: createAutoRemovedIframe,\n djb2: djb2,\n setAllowedOriginHashes: (hashes: number[]) => {\n RoktKit._allowedOriginHashes = hashes;\n },\n ReportingTransport: ReportingTransport,\n ErrorReportingService: ErrorReportingService,\n LoggingService: LoggingService,\n RateLimiter: RateLimiter,\n ErrorCodes: ErrorCodes,\n WSDKErrorSeverity: WSDKErrorSeverity,\n };\n this.attachLauncher(accountId, launcherOptions);\n return 'Successfully initialized: ' + name;\n }\n\n if (loadThankYouElement) {\n mp().Rokt.flushOnShoppableAdsReadyMessageQueue?.(this);\n loadRoktScript(ROKT_THANK_YOU_ELEMENT_SCRIPT_ID, generateThankYouElementScript(domain), {\n onLoad: () => {\n this._isThankYouElementLoaded = true;\n if (this._thankYouElementOnLoadCallback) {\n this._thankYouElementOnLoadCallback();\n }\n },\n onError: (error) => {\n console.error('Error loading Rokt Thank You Element script:', error);\n },\n });\n }\n\n if (this.isLauncherReadyToAttach()) {\n this.attachLauncher(accountId, launcherOptions, legacyRoktExtensions);\n } else {\n loadRoktScript(ROKT_INTEGRATION_SCRIPT_ID, generateLauncherScript(domain, roktExtensionsQueryParams), {\n onLoad: () => {\n if (this.isLauncherReadyToAttach()) {\n this.attachLauncher(accountId, launcherOptions, legacyRoktExtensions);\n } else {\n console.error('Rokt object is not available after script load.');\n }\n },\n onError: (error) => {\n console.error('Error loading Rokt launcher script:', error);\n },\n });\n\n this.captureTiming(RoktKit.PERFORMANCE_MARKS.RoktScriptAppended);\n }\n\n return 'Successfully initialized: ' + name;\n }\n\n public process(event: SDKEvent): string {\n if (!this.isKitReady()) {\n return 'Kit not ready for forwarder: ' + name;\n }\n if (typeof mp().Rokt?.setLocalSessionAttribute === 'function') {\n if (!isEmpty(this.placementEventAttributeMappingLookup)) {\n this.applyPlacementEventAttributeMapping(event);\n }\n\n if (!isEmpty(this.placementEventMappingLookup)) {\n const hashedEvent = hashEventMessage(event.EventDataType, event.EventCategory, event.EventName ?? '');\n if (this.placementEventMappingLookup[String(hashedEvent)]) {\n mp().Rokt.setLocalSessionAttribute?.(this.placementEventMappingLookup[String(hashedEvent)], true);\n }\n }\n }\n\n return 'Successfully sent to forwarder: ' + name;\n }\n\n public setExtensionData(partnerExtensionData: Record): void {\n if (!this.isKitReady()) {\n console.error('Rokt Kit: Not initialized');\n return;\n }\n\n window.Rokt!.setExtensionData(partnerExtensionData);\n }\n\n public setUserAttribute(key: string, value: unknown): string {\n if (!isSelectPlacementsAttributePersistenceDenied(key)) {\n this.userAttributes[key] = value;\n }\n return 'Successfully set user attribute for forwarder: ' + name;\n }\n\n public removeUserAttribute(key: string): string {\n delete this.userAttributes[key];\n return 'Successfully removed user attribute for forwarder: ' + name;\n }\n\n private handleIdentityComplete(user: IMParticleUser, callbackName: string): string {\n this.userAttributes = removeSelectPlacementsAttributePersistenceDeniedAttributes(user.getAllUserAttributes());\n return 'Successfully called ' + callbackName + ' for forwarder: ' + name;\n }\n\n public onUserIdentified(user: IMParticleUser): string {\n const filteredUser = user as FilteredUser;\n this.filters.filteredUser = filteredUser;\n this._workspaceSearchInFlightPromise = this.search(filteredUser);\n return this.handleIdentityComplete(user, 'onUserIdentified');\n }\n\n private search(filteredUser: FilteredUser): Promise {\n const apiKey = this._workspaceIdSyncApiKey;\n if (!apiKey) {\n this.userIdentifiedInWorkspace = false;\n this._workspaceLastSearchedIdentitiesKey = undefined;\n return Promise.resolve();\n }\n const search = mp().Identity?.search;\n if (typeof search !== 'function') {\n this.userIdentifiedInWorkspace = false;\n this._workspaceLastSearchedIdentitiesKey = undefined;\n return Promise.resolve();\n }\n\n const userIdentities: IUserIdentities | null = filteredUser.getUserIdentities\n ? filteredUser.getUserIdentities().userIdentities\n : null;\n\n // Forward every non-empty string identifier the user has — email,\n // customerid, other/other2-10 (commonly used for hashed email),\n // mobile_number, facebook, etc. The host SDK's Identity.search accepts\n // the full IUserIdentities surface and the server validates it.\n const knownIdentities: Record = {};\n if (userIdentities) {\n for (const key of Object.keys(userIdentities) as Array) {\n const value = userIdentities[key];\n if (isString(value) && value.length > 0) {\n knownIdentities[key] = value;\n }\n }\n }\n\n const identityKeys = Object.keys(knownIdentities);\n if (identityKeys.length === 0) {\n this.userIdentifiedInWorkspace = false;\n this._workspaceLastSearchedIdentitiesKey = undefined;\n return Promise.resolve();\n }\n\n // Stable cache key: sort keys so insertion-order differences don't\n // cause false misses. The values are partner-supplied strings; no\n // hashing needed — equality on this serialization is sufficient.\n const identitiesKey = identityKeys\n .sort()\n .map((k) => `${k}=${knownIdentities[k]}`)\n .join('&');\n\n // Same identifier set as the last successful dispatch → skip the\n // network call. The current flag value still reflects the correct\n // match status.\n if (identitiesKey === this._workspaceLastSearchedIdentitiesKey) {\n return this._workspaceSearchInFlightPromise || Promise.resolve();\n }\n\n // New / different identifier set → reset and re-search. Cache the key\n // up front so a second concurrent invocation with the same set also\n // dedupes.\n this.userIdentifiedInWorkspace = false;\n this._workspaceLastSearchedIdentitiesKey = identitiesKey;\n\n return new Promise((resolve) => {\n try {\n search(apiKey, knownIdentities as IUserIdentities, (result: WorkspaceIdSyncResult) => {\n if (result?.httpCode === 200) {\n this.userIdentifiedInWorkspace = true;\n }\n resolve();\n });\n } catch (err) {\n console.error('Rokt Kit: Workspace IDSync search failed', err);\n // Dispatch failed — clear the cache so the same identifier set\n // can retry on the next identification rather than being stuck\n // behind a poisoned entry that short-circuits future searches.\n this._workspaceLastSearchedIdentitiesKey = undefined;\n resolve();\n }\n });\n }\n\n public onLoginComplete(user: IMParticleUser, _filteredIdentityRequest: unknown): string {\n return this.handleIdentityComplete(user, 'onLoginComplete');\n }\n\n public onLogoutComplete(user: IMParticleUser, _filteredIdentityRequest: unknown): string {\n // Anonymous sessions must not carry the previous user's match forward.\n // Clear the flag explicitly here. Also clear the identities cache so a\n // re-login (possibly with the same identifiers) dispatches a fresh\n // search rather than reusing a stale answer.\n this.userIdentifiedInWorkspace = false;\n this._workspaceSearchInFlightPromise = null;\n this._workspaceLastSearchedIdentitiesKey = undefined;\n return this.handleIdentityComplete(user, 'onLogoutComplete');\n }\n\n public onModifyComplete(user: IMParticleUser, _filteredIdentityRequest: unknown): string {\n return this.handleIdentityComplete(user, 'onModifyComplete');\n }\n\n /**\n * Selects placements for Rokt Web SDK with merged attributes, filters, and experimentation options.\n *\n * If a Workspace IDSync search is in flight from a recent onUserIdentified\n * call, this method waits up to `WORKSPACE_SEARCH_SELECT_TIMEOUT_MS` for it\n * to settle so the first placement call can include the\n * `userIdentifiedInWorkspace` flag without racing the network response.\n * The timeout protects against a stalled or slow search blocking placement\n * rendering — if it fires, selectPlacements proceeds without the flag.\n *\n * Implementation note: this method stays non-async deliberately. First,\n * the public return type is `RoktSelection | Promise |\n * undefined` — a superset of the `RoktSelection | Promise`\n * shape declared for `RoktLauncher.selectPlacements` above (line ~70).\n * Marking this `async` would narrow it to `Promise` and silently change the contract for callers that read\n * the result synchronously. Second, `RoktSelection` has an optional\n * `then?` member, so TS treats it as ambiguously promise-like and\n * rejects it as the awaited return of an async function (TS1058) —\n * working around that would require a cast or wrapping every return in\n * `Promise.resolve(...)`. The inner work runs in `_dispatchPlacements`;\n * this wrapper just gates it on the in-flight search via `Promise.race`.\n */\n public selectPlacements(options: Record): RoktSelection | Promise | undefined {\n if (this._workspaceSearchInFlightPromise) {\n const inFlight = this._workspaceSearchInFlightPromise;\n return Promise.race([\n inFlight,\n new Promise((resolve) => setTimeout(resolve, WORKSPACE_SEARCH_SELECT_TIMEOUT_MS)),\n ]).then(() => this._dispatchPlacements(options)) as Promise;\n }\n return this._dispatchPlacements(options);\n }\n\n private _dispatchPlacements(options: Record): RoktSelection | Promise | undefined {\n const attributes = ((options && (options.attributes as Record)) || {}) as Record;\n const cachedUserAttributes = removeSelectPlacementsAttributePersistenceDeniedAttributes(this.userAttributes);\n const placementAttributes: Record = { ...cachedUserAttributes, ...attributes };\n\n const filters = this.filters || {};\n const userAttributeFilters = (filters.userAttributeFilters as string[]) || [];\n const filteredUser = filters.filteredUser || null;\n const mpid = filteredUser ? filteredUser.getMPID() : null;\n\n let filteredAttributes: Record;\n\n if (!filters) {\n console.warn('Rokt Kit: No filters available, using user attributes');\n filteredAttributes = placementAttributes;\n } else if (filters.filterUserAttributes) {\n filteredAttributes = filters.filterUserAttributes(placementAttributes, userAttributeFilters);\n } else {\n filteredAttributes = placementAttributes;\n }\n\n this.userAttributes = removeSelectPlacementsAttributePersistenceDeniedAttributes(filteredAttributes);\n\n const optimizelyAttributes = this._onboardingExpProvider === 'Optimizely' ? this.fetchOptimizely() : {};\n\n const filteredUserIdentities = this.returnUserIdentities(filteredUser);\n\n const localSessionAttributes = this.returnLocalSessionAttributes();\n\n const selectPlacementsAttributes: Record = {\n ...(filteredUserIdentities as Record),\n ...filteredAttributes,\n ...optimizelyAttributes,\n ...localSessionAttributes,\n ...(this.userIdentifiedInWorkspace ? { [USER_IDENTIFIED_IN_WORKSPACE_KEY]: true } : {}),\n mpid,\n };\n\n const selectPlacementsOptions: Record = { ...options, attributes: selectPlacementsAttributes };\n\n const selection = this.launcher!.selectPlacements(selectPlacementsOptions);\n\n // After selection resolves, sync the Rokt session ID back to mParticle, then log\n const logSelection = () => this.logSelectPlacementsEvent(selectPlacementsAttributes);\n\n void Promise.resolve(selection)\n .then((sel) => sel?.context?.sessionId?.then((sessionId) => this.setRoktSessionId(sessionId)))\n .catch(() => undefined)\n .finally(logSelection);\n\n return selection;\n }\n\n /**\n * Passes attributes to the Rokt Web SDK for client-side hashing.\n */\n public hashAttributes(attributes: Record): Promise> | null {\n if (!this.isKitReady()) {\n console.error('Rokt Kit: Not initialized');\n return null;\n }\n return this.launcher!.hashAttributes(attributes);\n }\n\n /**\n * Enables optional Integration Launcher extensions before selecting placements.\n *\n * @deprecated This functionality has been internalized and will be removed in a future release.\n */\n public use(extensionName: string): Promise {\n if (!this.isKitReady()) {\n console.error('Rokt Kit: Not initialized');\n return Promise.reject(new Error('Rokt Kit: Not initialized'));\n }\n if (!extensionName || !isString(extensionName)) {\n return Promise.reject(new Error('Rokt Kit: Invalid extension name'));\n }\n return this.launcher!.use(extensionName);\n }\n\n /**\n * Registers a callback to be invoked once rokt-thank-you-element.js becomes available.\n */\n public onShoppableAdsReady(callback: () => void) {\n if (this._isThankYouElementLoaded) {\n callback();\n } else {\n this._thankYouElementOnLoadCallback = callback;\n }\n }\n}\n\n// ============================================================\n// Kit registration\n// ============================================================\n\nfunction getId(): number {\n return moduleId;\n}\n\nfunction register(config: { kits?: Record }): void {\n if (!config) {\n window.console.log('You must pass a config object to register the kit ' + name);\n return;\n }\n if (!isObject(config)) {\n window.console.log(\"'config' must be an object. You passed in a \" + typeof config);\n return;\n }\n\n if (isObject(config.kits)) {\n (config.kits as Record)[name] = {\n constructor: RoktKit,\n };\n } else {\n config.kits = {};\n config.kits[name] = {\n constructor: RoktKit,\n };\n }\n window.console.log('Successfully registered ' + name + ' to your mParticle configuration');\n}\n\nif (typeof window !== 'undefined' && window.mParticle && mp().addForwarder) {\n mp().addForwarder({\n name: name,\n constructor: RoktKit,\n getId: getId,\n });\n}\n\nexport { register };\n"],"names":["SELECT_PLACEMENTS_ATTRIBUTE_PERSISTENCE_DENY_LIST","SELECT_PLACEMENTS_ATTRIBUTE_PERSISTENCE_DENY_SET","isSelectPlacementsAttributePersistenceDenied","key","removeSelectPlacementsAttributePersistenceDeniedAttributes","attributes","filteredAttributes","sourceAttributes","attributeKeys","i","name","moduleId","EVENT_NAME_SELECT_PLACEMENTS","ADBLOCK_CONTROL_DOMAIN","INIT_LOG_SAMPLING_RATE","ROKT_THANK_YOU_JOURNEY_EXTENSION","ROKT_INTEGRATION_SCRIPT_ID","ROKT_THANK_YOU_ELEMENT_SCRIPT_ID","USER_IDENTIFIED_IN_WORKSPACE_KEY","WORKSPACE_SEARCH_SELECT_TIMEOUT_MS","ErrorCodes","WSDKErrorSeverity","DEFAULT_ROKT_DOMAIN","LOGGING_ENDPOINT","ERROR_ENDPOINT","RATE_LIMIT_PER_SEVERITY","mp","generateLauncherScript","domain","extensions","baseUrl","generateBaseUrl","generateThankYouElementScript","generateReportingUrl","configuredUrl","endpoint","loadRoktScript","scriptId","source","handlers","target","script","isObject","val","parseSettingsString","settingsString","extractRoktExtensionConfig","settings","roktExtensionsQueryParams","legacyRoktExtensions","loadThankYouElement","extensionName","registerLegacyExtensions","legacyExtensions","launcher","extension","generateMappedEventLookup","placementEventMapping","mappedEvents","mapping","generateMappedEventAttributeLookup","placementEventAttributeMapping","mappedAttributeKeys","isString","mappedAttributeKey","eventAttributeKey","hashEventMessage","messageType","eventType","eventName","isEmpty","value","generateIntegrationName","customIntegrationName","integrationName","djb2","str","hash","createAutoRemovedIframe","src","iframe","sendAdBlockMeasurementSignals","version","originHash","RoktKit","guid","pageUrl","params","_isDebugModeEnabled","_getReportingUrl","_getUserAgent","RateLimiter","severity","newCount","ReportingTransport","config","launcherInstanceGuid","accountId","rateLimiter","isLoggingEnabled","url","msg","code","stackTrace","onError","logRequest","headers","response","serverError","error","ErrorReportingService","LoggingService","errorReportingService","entry","isServerSide","_RoktKit","event","condition","actualValue","operator","expectedValue","rule","conditions","rulesForMappedAttributeKey","allMatch","j","filteredUser","userIdentities","newUserIdentities","EVENT_TYPE_OTHER","sessionId","mpInstance","launcherOptions","mpSessionId","options","launcherPromise","err","roktFilters","forwarders","forwarder","optimizelyState","acc","expId","metricName","_service","testMode","_trackerId","filteredUserAttributes","kitSettings","reportingConfig","loggingService","hashes","hashedEvent","partnerExtensionData","user","callbackName","apiKey","search","knownIdentities","identityKeys","identitiesKey","k","resolve","result","_filteredIdentityRequest","inFlight","placementAttributes","filters","userAttributeFilters","mpid","optimizelyAttributes","filteredUserIdentities","localSessionAttributes","selectPlacementsAttributes","selectPlacementsOptions","selection","logSelection","sel","callback","getId","register"],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"Rokt-Kit.iife.js","sources":["../src/selectPlacementsAttributePersistence.ts","../src/utils.ts","../src/storage.ts","../src/pageViewStorage.ts","../src/launcherAttachState.ts","../src/Rokt-Kit.ts"],"sourcesContent":["const SELECT_PLACEMENTS_ATTRIBUTE_PERSISTENCE_DENY_LIST = [\n 'active_time_on_site_ms',\n 'billingaddress1',\n 'billingaddress2',\n 'billingcity',\n 'billingstate',\n 'billingzipcode',\n 'cartitems',\n 'ccbin',\n 'confirmationref',\n 'conversiontype',\n 'country',\n 'couponcode',\n 'currency',\n 'language',\n 'paymentserviceprovider',\n 'paymentserviceproviderattribute',\n 'paymenttype',\n 'shippingaddress1',\n 'shippingcity',\n 'shippingcountry',\n 'shippingmethod',\n 'shippingstate',\n 'shippingzipcode',\n 'totalprice',\n];\nconst SELECT_PLACEMENTS_ATTRIBUTE_PERSISTENCE_DENY_SET = new Set(SELECT_PLACEMENTS_ATTRIBUTE_PERSISTENCE_DENY_LIST);\n\nexport function isSelectPlacementsAttributePersistenceDenied(key: string): boolean {\n return SELECT_PLACEMENTS_ATTRIBUTE_PERSISTENCE_DENY_SET.has(key.toLowerCase());\n}\n\nexport function removeSelectPlacementsAttributePersistenceDeniedAttributes(\n attributes: Record | null | undefined,\n): Record {\n const filteredAttributes: Record = {};\n const sourceAttributes = attributes || {};\n const attributeKeys = Object.keys(sourceAttributes);\n\n for (let i = 0; i < attributeKeys.length; i++) {\n const key = attributeKeys[i];\n if (!isSelectPlacementsAttributePersistenceDenied(key)) {\n filteredAttributes[key] = sourceAttributes[key];\n }\n }\n\n return filteredAttributes;\n}\n","export function isObject(value: unknown): value is Record {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nexport function isString(value: unknown): value is string {\n return typeof value === 'string';\n}\n\nexport function isFunction(value: unknown): value is (...args: Array) => unknown {\n return typeof value === 'function';\n}\n\nexport function isEmpty(value: unknown): boolean {\n if (value == null) return true;\n if (typeof value === 'object') {\n return Object.keys(value as object).length === 0;\n }\n return false;\n}\n\n// Strips the query string from a URL before it is persisted and sent to Rokt,\n// since query params commonly carry PII (emails, tokens, order refs).\n// Returns the input unchanged if it can't be parsed as a URL.\nexport function sanitizeUrl(href: string): string {\n try {\n const url = new URL(href);\n url.search = '';\n return url.toString();\n } catch {\n return href;\n }\n}\n","import { isObject } from './utils';\n\nconst LS_PROBE_KEY = '__rokt_ls_probe__';\n\nexport function isLocalStorageAvailable(): boolean {\n try {\n window.localStorage.setItem(LS_PROBE_KEY, '1');\n window.localStorage.removeItem(LS_PROBE_KEY);\n return true;\n } catch {\n return false;\n }\n}\n\nexport function readJSON(key: string): unknown {\n try {\n const stored = window.localStorage.getItem(key);\n return stored === null ? null : JSON.parse(stored);\n } catch {\n return null;\n }\n}\n\nexport function writeJSON(key: string, value: unknown): boolean {\n try {\n window.localStorage.setItem(key, JSON.stringify(value));\n return true;\n } catch {\n return false;\n }\n}\n\nexport function removeKey(key: string): void {\n try {\n window.localStorage.removeItem(key);\n } catch {\n /* empty */\n }\n}\n\nexport function readNamespacedField(namespaceKey: string, field: string): unknown {\n const blob = readJSON(namespaceKey);\n return isObject(blob) ? blob[field] : undefined;\n}\n\nexport function writeNamespacedField(namespaceKey: string, field: string, value: unknown): boolean {\n const blob = readJSON(namespaceKey);\n const next = isObject(blob) ? { ...blob } : {};\n next[field] = value;\n return writeJSON(namespaceKey, next);\n}\n\nexport function removeNamespacedField(namespaceKey: string, field: string): void {\n const blob = readJSON(namespaceKey);\n if (!isObject(blob) || !(field in blob)) {\n return;\n }\n const next = { ...blob };\n delete next[field];\n if (Object.keys(next).length === 0) {\n removeKey(namespaceKey);\n } else {\n writeJSON(namespaceKey, next);\n }\n}\n","import type { LoggingService } from './Rokt-Kit';\nimport { readNamespacedField, writeNamespacedField, removeNamespacedField, isLocalStorageAvailable } from './storage';\nimport { sanitizeUrl, isObject } from './utils';\n\nconst LS_NAMESPACE_KEY = 'mp-rokt-kit';\nconst LS_PAGE_VIEWS_FIELD = 'pageViews';\nconst LS_UTM_PARAMS_FIELD = 'utmParams';\nexport const PAGE_VIEWS_MAX_COUNT = 25;\n\nconst UTM_KEYS = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content'] as const;\ntype UtmKey = (typeof UTM_KEYS)[number];\nexport type UtmParams = Partial>;\n\nexport interface PageEvent {\n pageUrl: string;\n sourceMessageId: string;\n timestamp: number;\n pageTitle?: string;\n canonicalUrl?: string;\n activeTimeOnSite?: number;\n activeTimeOnPage?: number;\n}\n\nfunction capPageViews(views: PageEvent[]): PageEvent[] {\n return views.slice(-PAGE_VIEWS_MAX_COUNT);\n}\n\nexport function loadPageViews(): PageEvent[] {\n const stored = readNamespacedField(LS_NAMESPACE_KEY, LS_PAGE_VIEWS_FIELD);\n return Array.isArray(stored) ? (stored as PageEvent[]) : [];\n}\n\nexport function writePageViews(pageViews: PageEvent[]): number {\n const views = capPageViews(pageViews);\n for (let i = 0; i < views.length; i++) {\n const toWrite = views.slice(i);\n if (writeNamespacedField(LS_NAMESPACE_KEY, LS_PAGE_VIEWS_FIELD, toWrite)) {\n return toWrite.length;\n }\n }\n return 0;\n}\n\nexport function clearPageViews(): void {\n removeNamespacedField(LS_NAMESPACE_KEY, LS_PAGE_VIEWS_FIELD);\n}\n\nexport function buildPageEvents(pageViews: PageEvent[]): PageEvent[] {\n const views = capPageViews(pageViews);\n return views.map((pageView, index) => {\n const activeTimeOnSite = pageView.activeTimeOnSite;\n const hasActiveTime = activeTimeOnSite !== undefined && Number.isFinite(activeTimeOnSite);\n\n const next = views[index + 1];\n const nextActiveTimeOnSite = next?.activeTimeOnSite;\n const hasNextActiveTimeOnSite = nextActiveTimeOnSite !== undefined && Number.isFinite(nextActiveTimeOnSite);\n\n const diff = hasActiveTime && hasNextActiveTimeOnSite ? nextActiveTimeOnSite - activeTimeOnSite : undefined;\n\n return {\n pageUrl: pageView.pageUrl,\n sourceMessageId: pageView.sourceMessageId,\n timestamp: pageView.timestamp,\n ...(pageView.pageTitle !== undefined ? { pageTitle: pageView.pageTitle } : {}),\n ...(pageView.canonicalUrl !== undefined ? { canonicalUrl: pageView.canonicalUrl } : {}),\n ...(hasActiveTime ? { activeTimeOnSite } : {}),\n ...(diff !== undefined && diff >= 0 ? { activeTimeOnPage: diff } : {}),\n };\n });\n}\n\nexport function captureUtmParams(loggingService: LoggingService | null): void {\n if (readNamespacedField(LS_NAMESPACE_KEY, LS_UTM_PARAMS_FIELD) !== undefined) {\n return;\n }\n const search = new URLSearchParams(window.location.search);\n const params: UtmParams = {};\n for (const key of UTM_KEYS) {\n const value = search.get(key);\n if (value) params[key] = value;\n }\n if (Object.keys(params).length === 0) {\n return;\n }\n const captured = Object.keys(params).join(', ');\n if (!writeNamespacedField(LS_NAMESPACE_KEY, LS_UTM_PARAMS_FIELD, params)) {\n const reason = isLocalStorageAvailable() ? 'quota' : 'ls_unavailable';\n loggingService?.log({\n message: `Rokt Kit: Failed to persist UTM params [reason: ${reason}]`,\n code: 'UTM_CAPTURE_FAILED',\n });\n return;\n }\n loggingService?.log({\n message: `Rokt Kit: Captured UTM params [${captured}]`,\n code: 'UTM_CAPTURE_SUCCESS',\n });\n}\n\nexport function loadUtmParams(): UtmParams | null {\n const stored = readNamespacedField(LS_NAMESPACE_KEY, LS_UTM_PARAMS_FIELD);\n return isObject(stored) ? (stored as UtmParams) : null;\n}\n\nexport function clearUtmParams(): void {\n removeNamespacedField(LS_NAMESPACE_KEY, LS_UTM_PARAMS_FIELD);\n}\n\nexport function readCanonicalUrl(): string | undefined {\n const link = document.querySelector('link[rel=\"canonical\"]');\n const href = link?.href;\n if (!href) {\n return undefined;\n }\n return sanitizeUrl(href);\n}\n","export type RoktLauncherOptions = Record;\n\nexport interface LauncherAttachContext {\n accountId: string;\n launcherOptions: RoktLauncherOptions;\n legacyRoktExtensions: readonly string[];\n}\n\nexport type LauncherLifecycle = 'idle' | 'attached' | 'terminated' | 'recreating';\n\nexport interface LauncherAttachState {\n context: LauncherAttachContext | null;\n lifecycle: LauncherLifecycle;\n recreateInFlight: Promise | null;\n}\n\nexport type AttachLauncher = (context: LauncherAttachContext) => Promise;\n\nexport function createLauncherAttachState(): LauncherAttachState {\n return {\n context: null,\n lifecycle: 'idle',\n recreateInFlight: null,\n };\n}\n\nexport function rememberAttachContext(state: LauncherAttachState, context: LauncherAttachContext): void {\n state.context = {\n accountId: context.accountId,\n launcherOptions: { ...context.launcherOptions },\n legacyRoktExtensions: [...context.legacyRoktExtensions],\n };\n}\n\nexport function markLauncherAttached(state: LauncherAttachState): void {\n state.lifecycle = 'attached';\n}\n\nexport function markLauncherTerminated(state: LauncherAttachState): void {\n if (state.lifecycle === 'idle') {\n return;\n }\n state.lifecycle = 'terminated';\n}\n\nexport function markLauncherAttachFailed(state: LauncherAttachState): void {\n state.lifecycle = 'terminated';\n}\n\nexport function resetLauncherAttachState(state: LauncherAttachState): void {\n state.context = null;\n state.lifecycle = 'idle';\n state.recreateInFlight = null;\n}\n\nexport function recreateIfTerminated(\n state: LauncherAttachState,\n canAttach: boolean,\n attach: AttachLauncher,\n): Promise | undefined {\n if (state.recreateInFlight) {\n return state.recreateInFlight;\n }\n if (state.lifecycle !== 'terminated' || !state.context || !canAttach) {\n return undefined;\n }\n\n state.lifecycle = 'recreating';\n const context = state.context;\n state.recreateInFlight = attach(context).finally(() => {\n state.recreateInFlight = null;\n });\n return state.recreateInFlight;\n}\n","// Copyright 2025 mParticle, Inc.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n// ============================================================\n// Types\n// ============================================================\n\nimport { KitInterface, IMParticleUser, SDKEvent } from '@mparticle/web-sdk/internal';\nimport type { IUserIdentities } from '@mparticle/web-sdk';\n\nimport {\n isSelectPlacementsAttributePersistenceDenied,\n removeSelectPlacementsAttributePersistenceDeniedAttributes,\n} from './selectPlacementsAttributePersistence';\n\nimport {\n PageEvent,\n PAGE_VIEWS_MAX_COUNT,\n buildPageEvents,\n loadPageViews,\n writePageViews,\n clearPageViews,\n readCanonicalUrl,\n captureUtmParams,\n loadUtmParams,\n clearUtmParams,\n} from './pageViewStorage';\nimport { isLocalStorageAvailable } from './storage';\n\nimport { isObject, isString, isEmpty, isFunction, sanitizeUrl } from './utils';\nimport {\n createLauncherAttachState,\n markLauncherAttached,\n markLauncherAttachFailed,\n markLauncherTerminated,\n rememberAttachContext,\n recreateIfTerminated,\n resetLauncherAttachState,\n type LauncherAttachState,\n type RoktLauncherOptions,\n} from './launcherAttachState';\n\ninterface RoktKitSettings {\n accountId: string;\n roktExtensions?: string;\n placementEventMapping?: string;\n placementEventAttributeMapping?: string;\n hashedEmailUserIdentityType?: string;\n onboardingExpProvider?: string;\n loggingUrl?: string;\n errorUrl?: string;\n workspaceIdSyncApiKey?: string;\n}\n\ninterface EventAttributeCondition {\n operator: string;\n attributeValue: string;\n}\n\ninterface PlacementEventRule {\n eventAttributeKey: string;\n conditions: EventAttributeCondition[];\n}\n\ninterface EventAttributeMapping {\n value: string;\n map: string;\n conditions?: EventAttributeCondition[];\n}\n\ninterface PlacementEventMappingEntry {\n jsmap: string;\n value: string;\n}\n\ninterface RoktExtensionEntry {\n value: string;\n}\n\ninterface RoktSelection {\n context?: {\n sessionId?: Promise;\n };\n then?: (callback: (sel: RoktSelection) => void) => Promise;\n catch?: (callback: () => void) => void;\n}\n\ninterface RoktLauncher {\n selectPlacements(options: Record): RoktSelection | Promise;\n hashAttributes(attributes: Record): Promise>;\n use(extensionName: string): Promise;\n terminate(): Promise;\n}\n\ninterface RoktGlobal {\n createLauncher(options: RoktLauncherOptions): Promise;\n createLocalLauncher(options: RoktLauncherOptions): RoktLauncher;\n currentLauncher?: RoktLauncher;\n setExtensionData(data: Record): void;\n}\n\n// FilteredUser is the IMParticleUser shape we receive after kit filtering.\n// `getMPID` and `getUserIdentities` are inherited from the SDK's `User` base type.\ntype FilteredUser = IMParticleUser;\n\n// TODO: Replace with `IIdentitySearchResult` from `@mparticle/web-sdk` once\n// a version that exports it is published (currently on a feature branch in\n// mParticle/mparticle-web-sdk PR #1255). The shape below is intentionally\n// structurally identical so the swap is a one-line import change.\ninterface WorkspaceIdSyncResult {\n httpCode: number;\n body?: {\n context?: string | null;\n mpid?: string;\n matched_identities?: Record;\n is_ephemeral?: boolean;\n is_logged_in?: boolean;\n };\n}\n\n// TODO: Replace with `IdentitySearchCallback`-compatible reference from\n// `@mparticle/web-sdk` once published (mirrors `SDKIdentityApi.search`).\ntype WorkspaceIdSyncSearcher = (\n apiKey: string,\n knownIdentities: IUserIdentities,\n callback: (result: WorkspaceIdSyncResult) => void,\n) => void;\n\ninterface KitFilters {\n userAttributeFilters?: string[];\n filterUserAttributes?: (attributes: Record, filters?: string[]) => Record;\n filteredUser?: FilteredUser | null;\n}\n\ninterface RoktManager {\n attachKit(kit: RoktKit): void | Promise;\n flushOnShoppableAdsReadyMessageQueue?(kit: RoktKit): void;\n filters?: KitFilters;\n domain?: string;\n launcherOptions?: Record;\n getLocalSessionAttributes?(): Record;\n setLocalSessionAttribute?(key: string, value: unknown): void;\n}\n\ninterface MParticleInstance {\n setIntegrationAttribute(moduleId: number, attrs: Record): void;\n}\n\ninterface OptimizelyState {\n getActiveExperimentIds(): string[];\n getVariationMap(): Record;\n}\n\ninterface OptimizelyGlobal {\n get(key: 'state'): OptimizelyState;\n}\n\n// Our view of the mParticle global with Rokt-specific extensions.\n// We access window.mParticle via an explicit cast (see `mp()` helper below)\n// rather than augmenting Window to avoid conflicts with @mparticle/web-sdk declarations.\ninterface MParticleExtended {\n Rokt: RoktManager;\n addForwarder(config: ForwarderRegistration): void;\n getVersion(): string;\n generateHash(value: string): string | number;\n logEvent(name: string, type: number, attrs?: Record): void;\n EventType: { Other: number };\n getInstance(): MParticleInstance;\n getDeviceId?(): string;\n sessionManager?: { getSession?(): string; getSessionId?(): string };\n _getActiveForwarders(): Array<{ name: string }>;\n config?: { isLocalLauncherEnabled?: boolean; isLoggingEnabled?: boolean };\n captureTiming?(metricName: string): void;\n forwarder?: RoktKit;\n loggedEvents?: Array>;\n _registerErrorReportingService?(service: ErrorReportingService): void;\n _registerLoggingService?(service: LoggingService): void;\n Identity?: { search?: WorkspaceIdSyncSearcher };\n}\n\ninterface TestHelpers {\n generateLauncherScript: (domain: string | undefined, extensions: string[]) => string;\n generateThankYouElementScript: (domain: string | undefined) => string;\n extractRoktExtensionConfig: (settingsString?: string) => RoktExtensionConfig;\n hashEventMessage: (messageType: number, eventType: number, eventName: string) => string | number;\n parseSettingsString: (settingsString?: string) => T[];\n generateMappedEventLookup: (placementEventMapping: PlacementEventMappingEntry[]) => Record;\n generateMappedEventAttributeLookup: (mapping: EventAttributeMapping[]) => Record;\n sendAdBlockMeasurementSignals: (domain: string | undefined, version: string | null) => void;\n createAutoRemovedIframe: (src: string) => void;\n djb2: (str: string) => number;\n setAllowedOriginHashes: (hashes: number[]) => void;\n ReportingTransport: typeof ReportingTransport;\n ErrorReportingService: typeof ErrorReportingService;\n LoggingService: typeof LoggingService;\n RateLimiter: typeof RateLimiter;\n ErrorCodes: typeof ErrorCodes;\n WSDKErrorSeverity: typeof WSDKErrorSeverity;\n resetLauncherAttachState: () => void;\n}\n\ninterface ForwarderRegistration {\n name: string;\n constructor: new () => RoktKit;\n getId: () => number;\n}\n\ninterface ReportingConfig {\n loggingUrl?: string;\n errorUrl?: string;\n integrationDomain?: string;\n isLoggingEnabled: boolean;\n}\n\ninterface ErrorReport {\n message: string;\n code?: string;\n severity?: string;\n stackTrace?: string;\n}\n\n// A log-delivery failure. statusCode is set when the request reached the server\n// and returned a non-2xx status (server-side); it is absent for network-level\n// failures such as ad-blockers, offline, or CORS rejections (client-side).\ninterface DeliveryError extends Error {\n statusCode?: number;\n}\n\ninterface LogEntry {\n message: string;\n code?: string;\n}\n\ninterface RoktExtensionConfig {\n roktExtensionsQueryParams: string[];\n legacyRoktExtensions: string[];\n loadThankYouElement: boolean;\n}\n\ndeclare global {\n interface Window {\n Rokt?: RoktGlobal;\n __rokt_li_guid__?: string;\n optimizely?: OptimizelyGlobal;\n // mParticle is declared as any to avoid conflicts with @mparticle/web-sdk type declarations.\n // We use the typed mp() accessor for all internal accesses.\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n mParticle: any;\n }\n}\n\n// ============================================================\n// Module-level constants\n// ============================================================\n\nconst name = 'Rokt';\nconst moduleId = 181;\nconst EVENT_NAME_SELECT_PLACEMENTS = 'selectPlacements';\nconst ADBLOCK_CONTROL_DOMAIN = 'apps.roktecommerce.com';\nconst INIT_LOG_SAMPLING_RATE = 0.1;\nconst ROKT_THANK_YOU_JOURNEY_EXTENSION = 'ThankYouPageJourney';\nconst ROKT_INTEGRATION_SCRIPT_ID = 'rokt-launcher';\nconst ROKT_THANK_YOU_ELEMENT_SCRIPT_ID = 'rokt-thank-you-element';\nconst USER_IDENTIFIED_IN_WORKSPACE_KEY = 'userIdentifiedInWorkspace';\n\nconst MESSAGE_TYPE_PAGE_VIEW = 3; // mParticle MessageType.PageView\nconst MESSAGE_TYPE_SESSION_END = 2; // mParticle MessageType.SessionEnd\nconst PAGE_EVENTS_KEY = 'page_events';\nconst PAGE_VIEW_ATTRIBUTES_KEY = 'page_view_attributes';\nconst MPARTICLE_SESSION_ID_KEY = 'mparticle_session_id';\nconst MPARTICLE_DEVICE_ID_KEY = 'mparticle_device_id';\n\n// Bound on how long selectPlacements will wait for an in-flight Workspace\n// IDSync search before proceeding without the userIdentifiedInWorkspace flag.\n// Long enough to cover the typical /v1/search round-trip (~50ms); short enough that a\n// stalled search never blocks placement rendering on a thank-you page.\nconst WORKSPACE_SEARCH_SELECT_TIMEOUT_MS = 500;\n\n// ============================================================\n// Reporting service constants\n// ============================================================\n\nconst ErrorCodes = {\n UNKNOWN_ERROR: 'UNKNOWN_ERROR',\n UNHANDLED_EXCEPTION: 'UNHANDLED_EXCEPTION',\n IDENTITY_REQUEST: 'IDENTITY_REQUEST',\n LOG_DELIVERY_FAILURE: 'LOG_DELIVERY_FAILURE',\n} as const;\n\nconst WSDKErrorSeverity = {\n ERROR: 'ERROR',\n INFO: 'INFO',\n WARNING: 'WARNING',\n} as const;\n\nconst DEFAULT_ROKT_DOMAIN = 'apps.rokt-api.com';\nconst LOGGING_ENDPOINT = '/v1/log';\nconst ERROR_ENDPOINT = '/v1/errors';\nconst RATE_LIMIT_PER_SEVERITY = 10;\n\n// ============================================================\n// Helper: typed accessor for window.mParticle\n// We use an explicit cast here to avoid conflicts with @mparticle/web-sdk\n// type declarations while still providing full type safety for our usages.\n// ============================================================\n\nfunction mp(): MParticleExtended {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n return (window as any).mParticle as MParticleExtended;\n}\n\n// ============================================================\n// Module-level utility functions\n// ============================================================\n\nfunction generateLauncherScript(domain: string | undefined, extensions: string[]): string {\n const launcherPath = '/wsdk/integrations/launcher.js';\n const baseUrl = [generateBaseUrl(domain), launcherPath].join('');\n\n if (!extensions || extensions.length === 0) {\n return baseUrl;\n }\n return baseUrl + '?extensions=' + extensions.join(',');\n}\n\nfunction generateThankYouElementScript(domain: string | undefined) {\n const thankYouElementPath = '/rokt-elements/rokt-element-thank-you.js';\n return [generateBaseUrl(domain), thankYouElementPath].join('');\n}\n\nfunction generateBaseUrl(domain: string | undefined) {\n const resolvedDomain = typeof domain !== 'undefined' ? domain : DEFAULT_ROKT_DOMAIN;\n\n if (resolvedDomain.includes('://')) {\n return resolvedDomain.replace(/\\/+$/, '');\n }\n\n const protocol = 'https://';\n\n return [protocol, resolvedDomain].join('');\n}\n\nfunction generateReportingUrl(configuredUrl: string | undefined, domain: string | undefined, endpoint: string): string {\n if (configuredUrl) {\n if (configuredUrl.startsWith('http://') || configuredUrl.startsWith('https://')) {\n return configuredUrl;\n }\n return 'https://' + configuredUrl;\n }\n\n const hasNonHttpScheme = domain?.includes('://') && !/^https?:\\/\\//i.test(domain);\n const reportingDomain = hasNonHttpScheme ? undefined : domain;\n\n return generateBaseUrl(reportingDomain) + endpoint;\n}\n\nfunction loadRoktScript(\n scriptId: string,\n source: string,\n handlers?: { onLoad?: () => void; onError?: (e: Event | string) => void },\n): void {\n if (document.getElementById(scriptId)) return; // resolves the preexisting script issue\n\n const target = document.head || document.body;\n const script = document.createElement('script');\n script.id = scriptId;\n script.type = 'text/javascript';\n script.src = source;\n script.async = true;\n script.crossOrigin = 'anonymous';\n (script as HTMLScriptElement & { fetchPriority: string }).fetchPriority = 'high';\n if (handlers?.onLoad) script.onload = handlers.onLoad;\n if (handlers?.onError) script.onerror = handlers.onError;\n target.appendChild(script);\n}\n\nfunction parseSettingsString(settingsString?: string): T[] {\n if (!settingsString) {\n return [];\n }\n try {\n return JSON.parse(settingsString.replace(/"/g, '\"')) as T[];\n } catch (_error) {\n console.error('Settings string contains invalid JSON');\n }\n return [];\n}\n\nfunction extractRoktExtensionConfig(settingsString?: string): RoktExtensionConfig {\n const settings = settingsString ? parseSettingsString(settingsString) : [];\n const roktExtensionsQueryParams: string[] = [];\n const legacyRoktExtensions: string[] = [];\n let loadThankYouElement = false;\n\n for (let i = 0; i < settings.length; i++) {\n const extensionName = settings[i].value;\n if (extensionName === 'thank-you-journey') {\n loadThankYouElement = true;\n legacyRoktExtensions.push(ROKT_THANK_YOU_JOURNEY_EXTENSION);\n } else {\n roktExtensionsQueryParams.push(extensionName);\n }\n }\n\n return {\n roktExtensionsQueryParams,\n legacyRoktExtensions,\n loadThankYouElement,\n };\n}\n\nasync function registerLegacyExtensions(legacyExtensions: string[], launcher: RoktLauncher | null) {\n const extensions: Promise[] = [];\n if (launcher) {\n for (const extension of legacyExtensions) {\n extensions.push(launcher.use(extension));\n }\n }\n\n return Promise.all(extensions);\n}\n\nfunction generateMappedEventLookup(placementEventMapping: PlacementEventMappingEntry[]): Record {\n if (!placementEventMapping) {\n return {};\n }\n\n const mappedEvents: Record = {};\n for (let i = 0; i < placementEventMapping.length; i++) {\n const mapping = placementEventMapping[i];\n mappedEvents[mapping.jsmap] = mapping.value;\n }\n return mappedEvents;\n}\n\nfunction generateMappedEventAttributeLookup(\n placementEventAttributeMapping: EventAttributeMapping[],\n): Record {\n const mappedAttributeKeys: Record = {};\n if (!Array.isArray(placementEventAttributeMapping)) {\n return mappedAttributeKeys;\n }\n for (let i = 0; i < placementEventAttributeMapping.length; i++) {\n const mapping = placementEventAttributeMapping[i];\n if (!mapping || !isString(mapping.value) || !isString(mapping.map)) {\n continue;\n }\n\n const mappedAttributeKey = mapping.value;\n const eventAttributeKey = mapping.map;\n\n if (!mappedAttributeKeys[mappedAttributeKey]) {\n mappedAttributeKeys[mappedAttributeKey] = [];\n }\n\n mappedAttributeKeys[mappedAttributeKey].push({\n eventAttributeKey: eventAttributeKey,\n conditions: Array.isArray(mapping.conditions) ? mapping.conditions : [],\n });\n }\n return mappedAttributeKeys;\n}\n\nfunction hashEventMessage(messageType: number, eventType: number, eventName: string): string | number {\n return mp().generateHash([messageType, eventType, eventName].join(''));\n}\n\nfunction generateIntegrationName(customIntegrationName?: string): string {\n const coreSdkVersion = mp().getVersion();\n const kitVersion = process.env.PACKAGE_VERSION;\n let integrationName = 'mParticle_' + 'wsdkv_' + coreSdkVersion + '_kitv_' + kitVersion;\n\n if (customIntegrationName) {\n integrationName += '_' + customIntegrationName;\n }\n return integrationName;\n}\n\nfunction djb2(str: string): number {\n let hash = 5381;\n for (let i = 0; i < str.length; i++) {\n hash = (hash << 5) + hash + str.charCodeAt(i);\n hash = hash & hash;\n }\n return hash;\n}\n\nfunction createAutoRemovedIframe(src: string): void {\n const iframe = document.createElement('iframe');\n iframe.style.display = 'none';\n iframe.setAttribute('sandbox', 'allow-scripts allow-same-origin');\n iframe.src = src;\n iframe.onload = function () {\n iframe.onload = null;\n if (iframe.parentNode) {\n iframe.parentNode.removeChild(iframe);\n }\n };\n const target = document.body || document.head;\n if (target) {\n target.appendChild(iframe);\n }\n}\n\nfunction sendAdBlockMeasurementSignals(domain: string | undefined, version: string | null): void {\n const originHash = djb2(window.location.origin);\n const allowedOriginHashes = RoktKit._allowedOriginHashes;\n if (allowedOriginHashes.indexOf(originHash) === -1) {\n return;\n }\n\n if (Math.random() >= INIT_LOG_SAMPLING_RATE) {\n return;\n }\n\n const guid = window.__rokt_li_guid__;\n if (!guid) {\n return;\n }\n\n if (domain && domain.includes('://') && !/^https:\\/\\//i.test(domain)) {\n return;\n }\n\n const pageUrl = window.location.href.split('?')[0].split('#')[0];\n const params =\n 'version=' +\n encodeURIComponent(version ?? '') +\n '&launcherInstanceGuid=' +\n encodeURIComponent(guid) +\n '&pageUrl=' +\n encodeURIComponent(pageUrl);\n\n const existingBaseUrl = domain ? generateBaseUrl(domain) : 'https://apps.rokt.com';\n createAutoRemovedIframe(existingBaseUrl + '/v1/wsdk-init/index.html?' + params);\n\n createAutoRemovedIframe(\n 'https://' + ADBLOCK_CONTROL_DOMAIN + '/v1/wsdk-init/index.html?' + params + '&isControl=true',\n );\n}\n\n// ============================================================\n// Reporting helpers\n// ============================================================\n\nfunction _isDebugModeEnabled(): boolean {\n return typeof window !== 'undefined' && !!window.location?.search?.toLowerCase().includes('mp_enable_logging=true');\n}\n\nfunction _getReportingUrl(): string | undefined {\n return typeof window !== 'undefined' ? window.location?.href : undefined;\n}\n\nfunction _getUserAgent(): string | undefined {\n return typeof window !== 'undefined' ? window.navigator?.userAgent : undefined;\n}\n\nclass RateLimiter {\n private _logCount: Record = {};\n\n incrementAndCheck(severity: string): boolean {\n const count = this._logCount[severity] || 0;\n const newCount = count + 1;\n this._logCount[severity] = newCount;\n return newCount > RATE_LIMIT_PER_SEVERITY;\n }\n}\n\nclass ReportingTransport {\n private _isEnabled: boolean;\n private _integrationName: string;\n private _launcherInstanceGuid: string | undefined;\n private _accountId: string | null;\n private _rateLimiter: RateLimiter;\n private readonly _reporter = 'mp-wsdk';\n\n constructor(\n config: ReportingConfig,\n integrationName: string | null | undefined,\n launcherInstanceGuid: string | undefined,\n accountId: string | null | undefined,\n rateLimiter?: RateLimiter,\n ) {\n const isLoggingEnabled = config.isLoggingEnabled;\n this._integrationName = integrationName || '';\n this._launcherInstanceGuid = launcherInstanceGuid;\n this._accountId = accountId || null;\n this._rateLimiter = rateLimiter || new RateLimiter();\n this._isEnabled = _isDebugModeEnabled() || isLoggingEnabled;\n }\n\n send(\n url: string,\n severity: string,\n msg: string,\n code?: string,\n stackTrace?: string,\n onError?: (error: DeliveryError) => void,\n ): void {\n if (!this._isEnabled || this._rateLimiter.incrementAndCheck(severity)) {\n return;\n }\n\n try {\n const logRequest = {\n additionalInformation: {\n message: msg,\n version: this._integrationName,\n },\n severity,\n code: code || ErrorCodes.UNKNOWN_ERROR,\n url: _getReportingUrl(),\n deviceInfo: _getUserAgent(),\n stackTrace,\n reporter: this._reporter,\n integration: this._integrationName,\n };\n\n const headers: Record = {\n Accept: 'text/plain;charset=UTF-8',\n 'Content-Type': 'application/json',\n 'rokt-launcher-version': this._integrationName,\n 'rokt-wsdk-version': 'joint',\n };\n\n if (this._launcherInstanceGuid) {\n headers['rokt-launcher-instance-guid'] = this._launcherInstanceGuid;\n }\n if (this._accountId) {\n headers['rokt-account-id'] = this._accountId;\n }\n\n fetch(url, {\n method: 'POST',\n headers,\n body: JSON.stringify(logRequest),\n })\n .then((response: Response) => {\n // fetch only rejects on network failures; an HTTP 5xx resolves with\n // ok === false. Surface server-side failures so they are not swallowed.\n if (!response.ok) {\n const serverError: DeliveryError = new Error('HTTP ' + response.status + ' from log endpoint');\n serverError.statusCode = response.status;\n throw serverError;\n }\n })\n .catch((error: DeliveryError) => {\n console.error('ReportingTransport: Failed to send log', error);\n if (onError) onError(error);\n });\n } catch (error) {\n console.error('ReportingTransport: Failed to send log', error);\n if (onError) onError(error as DeliveryError);\n }\n }\n}\n\nclass ErrorReportingService {\n private _transport: ReportingTransport;\n private _errorUrl: string;\n\n constructor(\n config: ReportingConfig,\n integrationName: string | null | undefined,\n launcherInstanceGuid?: string,\n accountId?: string | null,\n rateLimiter?: RateLimiter,\n ) {\n this._transport = new ReportingTransport(config, integrationName, launcherInstanceGuid, accountId, rateLimiter);\n this._errorUrl = generateReportingUrl(config?.errorUrl, config?.integrationDomain, ERROR_ENDPOINT);\n }\n\n report(error: ErrorReport | null | undefined): void {\n if (!error) return;\n const severity = error.severity || WSDKErrorSeverity.ERROR;\n this._transport.send(this._errorUrl, severity, error.message, error.code, error.stackTrace);\n }\n}\n\nclass LoggingService {\n private _transport: ReportingTransport;\n private _loggingUrl: string;\n private _errorReportingService: { report: (e: ErrorReport) => void };\n\n constructor(\n config: ReportingConfig,\n errorReportingService: { report: (e: ErrorReport) => void },\n integrationName: string | null | undefined,\n launcherInstanceGuid?: string,\n accountId?: string | null,\n rateLimiter?: RateLimiter,\n ) {\n this._transport = new ReportingTransport(config, integrationName, launcherInstanceGuid, accountId, rateLimiter);\n this._loggingUrl = generateReportingUrl(config?.loggingUrl, config?.integrationDomain, LOGGING_ENDPOINT);\n this._errorReportingService = errorReportingService;\n }\n\n log(entry: LogEntry | null | undefined): void {\n if (!entry) return;\n this._transport.send(\n this._loggingUrl,\n WSDKErrorSeverity.INFO,\n entry.message,\n entry.code,\n undefined,\n (error: DeliveryError) => {\n if (this._errorReportingService) {\n // A failed log POST is not itself an SDK error. Network-level failures\n // (ad-blockers, offline, CORS) are client-side noise and reported as a\n // WARNING; only a server-side non-2xx response stays at ERROR severity.\n const isServerSide = typeof error.statusCode === 'number';\n this._errorReportingService.report({\n message: 'LoggingService: Failed to send log: ' + error.message,\n code: ErrorCodes.LOG_DELIVERY_FAILURE,\n severity: isServerSide ? WSDKErrorSeverity.ERROR : WSDKErrorSeverity.WARNING,\n });\n }\n },\n );\n }\n}\n\nfunction buildPageEvent(event: SDKEvent): PageEvent {\n const pageUrl = sanitizeUrl(window.location.href);\n const pageTitle = event.EventAttributes?.title || document.title;\n const canonicalUrl = readCanonicalUrl();\n const activeTimeOnSite = event.ActiveTimeOnSite;\n\n return {\n pageUrl,\n sourceMessageId: event.SourceMessageId,\n timestamp: event.Timestamp,\n ...(pageTitle ? { pageTitle } : {}),\n ...(canonicalUrl !== undefined ? { canonicalUrl } : {}),\n ...(Number.isFinite(activeTimeOnSite) ? { activeTimeOnSite } : {}),\n };\n}\n\n// ============================================================\n// RoktKit class\n// ============================================================\n\nclass RoktKit implements KitInterface {\n // Static field for allowed origin hashes (mutable by testHelpers)\n public static _allowedOriginHashes: number[] = [-553112570, 549508659];\n\n private static readonly PERFORMANCE_MARKS = {\n RoktScriptAppended: 'mp:RoktScriptAppended',\n };\n\n private static readonly EMAIL_SHA256_KEY = 'emailsha256';\n\n // Public fields (accessed by tests and the mParticle framework)\n public name = name;\n public id = moduleId;\n public moduleId = moduleId;\n public isInitialized = false;\n public launcher: RoktLauncher | null = null;\n public filters: KitFilters = {};\n public userAttributes: Record = {};\n // Flag set by the Workspace IDSync flow on a 200 response. Stored on the\n // kit instance and merged into placement attributes inside selectPlacements.\n public userIdentifiedInWorkspace = false;\n public testHelpers: TestHelpers | null = null;\n public placementEventMappingLookup: Record = {};\n public placementEventAttributeMappingLookup: Record = {};\n public integrationName: string | null = null;\n public domain?: string;\n public errorReportingService: ErrorReportingService | null = null;\n public loggingService: LoggingService | null = null;\n\n // Private fields\n private _mappedEmailSha256Key?: string;\n private _onboardingExpProvider?: string;\n private _thankYouElementOnLoadCallback: (() => void) | null = null;\n private _isThankYouElementLoaded = false;\n private _workspaceIdSyncApiKey?: string;\n\n // Held during a search dispatch so the next selectPlacements call;\n // can wait for the HTTP response before reading userIdentifiedInWorkspace;\n // — otherwise the first placement call ships without the flag.\n private _workspaceSearchInFlightPromise: Promise | null = null;\n // Stable serialization of the identifier set sent in the most recent\n // successful search dispatch. If a subsequent identification arrives with\n // an identical set, we skip the network call (the flag is still correct\n // from the prior search). Keyed over the full IUserIdentities map — not\n // just email — so partners passing hashed email through `other`/`other2-10`\n // or any other identifier benefit from the same dedupe. Cleared on logout\n // so a re-login re-evaluates fresh.\n private _workspaceLastSearchedIdentitiesKey?: string;\n\n private _launcherAttachState: LauncherAttachState = createLauncherAttachState();\n\n // ---- Private helpers ----\n\n private getEventAttributeValue(event: SDKEvent, eventAttributeKey: string): unknown {\n const attributes = event && event.EventAttributes;\n if (!attributes) {\n return null;\n }\n\n if (typeof attributes[eventAttributeKey] === 'undefined') {\n return null;\n }\n\n return attributes[eventAttributeKey];\n }\n\n private doesEventAttributeConditionMatch(condition: EventAttributeCondition, actualValue: unknown): boolean {\n if (!condition || !isString(condition.operator)) {\n return false;\n }\n\n const operator = condition.operator.toLowerCase();\n const expectedValue = condition.attributeValue;\n\n if (operator === 'exists') {\n return actualValue !== null;\n }\n\n if (actualValue == null) {\n return false;\n }\n\n if (operator === 'equals') {\n return String(actualValue) === String(expectedValue);\n }\n\n if (operator === 'contains') {\n return String(actualValue).indexOf(String(expectedValue)) !== -1;\n }\n\n return false;\n }\n\n private doesEventMatchRule(event: SDKEvent, rule: PlacementEventRule): boolean {\n if (!rule || !isString(rule.eventAttributeKey)) {\n return false;\n }\n\n const conditions = rule.conditions;\n if (!Array.isArray(conditions)) {\n return false;\n }\n\n const actualValue = this.getEventAttributeValue(event, rule.eventAttributeKey);\n\n if (conditions.length === 0) {\n return actualValue !== null;\n }\n for (let i = 0; i < conditions.length; i++) {\n if (!this.doesEventAttributeConditionMatch(conditions[i], actualValue)) {\n return false;\n }\n }\n\n return true;\n }\n\n private applyPlacementEventAttributeMapping(event: SDKEvent): void {\n const mappedAttributeKeys = Object.keys(this.placementEventAttributeMappingLookup);\n for (let i = 0; i < mappedAttributeKeys.length; i++) {\n const mappedAttributeKey = mappedAttributeKeys[i];\n const rulesForMappedAttributeKey = this.placementEventAttributeMappingLookup[mappedAttributeKey];\n if (isEmpty(rulesForMappedAttributeKey)) {\n continue;\n }\n\n // Require ALL rules for the same key to match (AND).\n let allMatch = true;\n for (let j = 0; j < rulesForMappedAttributeKey.length; j++) {\n if (!this.doesEventMatchRule(event, rulesForMappedAttributeKey[j])) {\n allMatch = false;\n break;\n }\n }\n if (!allMatch) {\n continue;\n }\n\n mp().Rokt.setLocalSessionAttribute?.(mappedAttributeKey, true);\n }\n }\n\n private capturePageView(event: SDKEvent): void {\n let pageUrl: string | undefined;\n\n try {\n pageUrl = sanitizeUrl(window.location.href);\n\n const pageViews = loadPageViews();\n const pageView = buildPageEvent(event);\n pageViews.push(pageView);\n\n const requested = Math.min(pageViews.length, PAGE_VIEWS_MAX_COUNT);\n const stored = writePageViews(pageViews);\n if (stored === 0) {\n const reason = isLocalStorageAvailable() ? 'quota' : 'ls_unavailable';\n this.loggingService?.log({\n message: `Rokt Kit: Failed to persist page view for ${pageUrl} [reason: ${reason}]`,\n code: 'PAGE_VIEW_CAPTURE_FAILED',\n });\n } else if (stored < requested) {\n this.loggingService?.log({\n message: `Rokt Kit: Page view storage reduced from ${requested} to ${stored} record(s) under quota pressure [reason: quota_eviction]`,\n code: 'PAGE_VIEW_QUOTA_EVICTION',\n });\n }\n } catch (err) {\n const reason = isLocalStorageAvailable() ? 'exception' : 'ls_unavailable';\n const errMessage = err instanceof Error ? err.message : String(err);\n this.loggingService?.log({\n message: `Rokt Kit: Failed to capture page view for ${pageUrl}: ${errMessage} [reason: ${reason}]`,\n code: 'PAGE_VIEW_CAPTURE_FAILED',\n });\n }\n }\n\n private isLauncherReadyToAttach(): boolean {\n return !!window.Rokt && isFunction(window.Rokt.createLauncher);\n }\n\n /**\n * Returns the user identities from the filtered user, if any.\n */\n private returnUserIdentities(filteredUser: FilteredUser | null | undefined): Record {\n if (!filteredUser || !filteredUser.getUserIdentities) {\n return {};\n }\n\n const userIdentities: IUserIdentities = filteredUser.getUserIdentities().userIdentities;\n\n return this.replaceOtherIdentityWithEmailsha256(userIdentities);\n }\n\n private returnLocalSessionAttributes(): Record {\n if (!mp().Rokt || typeof mp().Rokt.getLocalSessionAttributes !== 'function') {\n return {};\n }\n return mp().Rokt.getLocalSessionAttributes!();\n }\n\n private replaceOtherIdentityWithEmailsha256(userIdentities: IUserIdentities): Record {\n const newUserIdentities: Record = { ...(userIdentities || {}) };\n const key = this._mappedEmailSha256Key;\n if (key && userIdentities[key as keyof IUserIdentities]) {\n newUserIdentities[RoktKit.EMAIL_SHA256_KEY] = userIdentities[key as keyof IUserIdentities] as string;\n }\n if (key) {\n delete newUserIdentities[key];\n }\n\n return newUserIdentities;\n }\n\n private logSelectPlacementsEvent(attributes: unknown): void {\n if (!window.mParticle || typeof mp().logEvent !== 'function') {\n return;\n }\n\n if (!isObject(attributes)) {\n return;\n }\n\n const EVENT_TYPE_OTHER = mp().EventType.Other;\n\n mp().logEvent(EVENT_NAME_SELECT_PLACEMENTS, EVENT_TYPE_OTHER, attributes as Record);\n }\n\n private setRoktSessionId(sessionId: string): void {\n if (!sessionId || typeof sessionId !== 'string') {\n return;\n }\n try {\n const mpInstance = mp().getInstance();\n if (mpInstance && isFunction(mpInstance.setIntegrationAttribute)) {\n mpInstance.setIntegrationAttribute(moduleId, {\n roktSessionId: sessionId,\n });\n }\n } catch (_e) {\n // Best effort — never let this break the partner page\n }\n }\n\n private readMpSessionId(): string | undefined {\n // The public mParticle.sessionManager facade exposes only getSession(), which already returns\n // the session id. getSessionId() lives on the internal _SessionManager and has never been\n // re-exported, so prefer it if a future core adds it and fall back to getSession() until then.\n const sessionManager = mp()?.sessionManager;\n const readSessionId = sessionManager?.getSessionId ?? sessionManager?.getSession;\n if (!isFunction(readSessionId)) {\n return undefined;\n }\n\n return readSessionId.call(sessionManager) || undefined;\n }\n\n private readMpDeviceId(): string | undefined {\n // The device application stamp (`das`) outlives the session id: core clears the session on\n // timeout, cross-tab rotation and endSession(), but never the device id, which lives in\n // localStorage/cookie for cookieExpiration days (365 by default) and survives login/logout.\n // Read it per call anyway — a partner can reassign it at any time via setDeviceId().\n return mp()?.getDeviceId?.() || undefined;\n }\n\n private attachLauncher(\n accountId: string,\n launcherOptions: RoktLauncherOptions,\n legacyRoktExtensions: readonly string[] = [],\n ): Promise {\n rememberAttachContext(this._launcherAttachState, {\n accountId,\n launcherOptions: launcherOptions || {},\n legacyRoktExtensions,\n });\n\n const options: RoktLauncherOptions = {\n accountId,\n ...(launcherOptions || {}),\n };\n\n let launcherPromise: Promise;\n if (this.isPartnerInLocalLauncherTestGroup()) {\n launcherPromise = Promise.resolve(window.Rokt!.createLocalLauncher(options));\n } else {\n launcherPromise = window.Rokt!.createLauncher(options);\n }\n\n return launcherPromise\n .then(async (launcher) => {\n await registerLegacyExtensions([...legacyRoktExtensions], launcher);\n this.initRoktLauncher(launcher);\n })\n .catch((err: unknown) => {\n markLauncherAttachFailed(this._launcherAttachState);\n console.error('Error creating Rokt launcher:', err);\n });\n }\n\n private recreateLauncherIfTerminated(): Promise | undefined {\n return recreateIfTerminated(this._launcherAttachState, this.isLauncherReadyToAttach(), (context) =>\n this.attachLauncher(context.accountId, context.launcherOptions, context.legacyRoktExtensions),\n );\n }\n\n private initRoktLauncher(launcher: RoktLauncher): void {\n // Assign the launcher to a global variable for later access\n if (window.Rokt) {\n window.Rokt.currentLauncher = launcher;\n }\n // Locally cache the launcher and filters\n this.launcher = launcher;\n markLauncherAttached(this._launcherAttachState);\n\n const roktFilters = mp().Rokt?.filters;\n\n if (!roktFilters) {\n console.warn('Rokt Kit: No filters have been set.');\n } else {\n this.filters = roktFilters;\n if (!roktFilters.filteredUser) {\n console.warn('Rokt Kit: No filtered user has been set.');\n } else {\n this._workspaceSearchInFlightPromise = this.search(roktFilters.filteredUser);\n }\n }\n\n // Kit must be initialized before attaching to the Rokt manager\n this.isInitialized = true;\n\n sendAdBlockMeasurementSignals(this.domain, this.integrationName);\n\n // Attaches the kit to the Rokt manager\n mp().Rokt.attachKit(this);\n }\n\n private fetchOptimizely(): Record {\n const forwarders = mp()\n ._getActiveForwarders()\n .filter((forwarder) => forwarder.name === 'Optimizely');\n\n try {\n if (forwarders.length > 0 && window.optimizely) {\n const optimizelyState = window.optimizely.get('state');\n if (!optimizelyState || !optimizelyState.getActiveExperimentIds) {\n return {};\n }\n const activeExperimentIds = optimizelyState.getActiveExperimentIds();\n const activeExperiments = activeExperimentIds.reduce((acc: Record, expId: string) => {\n acc['rokt.custom.optimizely.experiment.' + expId + '.variationId'] =\n optimizelyState.getVariationMap()[expId].id;\n return acc;\n }, {});\n return activeExperiments;\n }\n } catch (error) {\n console.error('Error fetching Optimizely attributes:', error);\n }\n return {};\n }\n\n private isKitReady(): boolean {\n return !!(this.isInitialized && this.launcher);\n }\n\n // When the partner has opted out of targeting (noTargeting launcher option),\n // the kit must not collect behavioral targeting signals such as page views.\n private isTargetingDisabled(): boolean {\n return (mp().Rokt?.launcherOptions as Record | undefined)?.noTargeting === true;\n }\n\n private isPartnerInLocalLauncherTestGroup(): boolean {\n return !!(mp().config && mp().config!.isLocalLauncherEnabled && this.isAssignedToSampleGroup());\n }\n\n private isAssignedToSampleGroup(): boolean {\n const LOCAL_LAUNCHER_TEST_GROUP_THRESHOLD = 0.5;\n return Math.random() > LOCAL_LAUNCHER_TEST_GROUP_THRESHOLD;\n }\n\n private captureTiming(metricName: string): void {\n if (window && mp() && mp().captureTiming && metricName) {\n mp().captureTiming!(metricName);\n }\n }\n\n // ---- Public methods (mParticle Kit Callbacks) ----\n\n /**\n * Initializes the Rokt forwarder with settings from the mParticle server.\n */\n public init(\n settings: Record,\n _service: unknown,\n testMode: boolean,\n _trackerId: unknown,\n filteredUserAttributes?: Record,\n ): string {\n const kitSettings = settings as unknown as RoktKitSettings;\n const accountId = kitSettings.accountId;\n this.userAttributes = removeSelectPlacementsAttributePersistenceDeniedAttributes(filteredUserAttributes);\n this._onboardingExpProvider = kitSettings.onboardingExpProvider;\n\n const placementEventMapping = parseSettingsString(kitSettings.placementEventMapping);\n this.placementEventMappingLookup = generateMappedEventLookup(placementEventMapping);\n\n const placementEventAttributeMapping = parseSettingsString(\n kitSettings.placementEventAttributeMapping,\n );\n this.placementEventAttributeMappingLookup = generateMappedEventAttributeLookup(placementEventAttributeMapping);\n\n // Set dynamic OTHER_IDENTITY based on server settings\n if (kitSettings.hashedEmailUserIdentityType) {\n this._mappedEmailSha256Key = kitSettings.hashedEmailUserIdentityType.toLowerCase();\n }\n\n this._workspaceIdSyncApiKey = isString(kitSettings.workspaceIdSyncApiKey)\n ? kitSettings.workspaceIdSyncApiKey\n : undefined;\n\n const domain = mp().Rokt?.domain;\n const { roktExtensionsQueryParams, legacyRoktExtensions, loadThankYouElement } = extractRoktExtensionConfig(\n kitSettings.roktExtensions,\n );\n const launcherOptions: Record = {\n ...((mp().Rokt?.launcherOptions as Record) || {}),\n };\n this.integrationName = generateIntegrationName(launcherOptions.integrationName as string | undefined);\n launcherOptions.integrationName = this.integrationName;\n\n this.domain = domain;\n\n const reportingConfig: ReportingConfig = {\n loggingUrl: kitSettings.loggingUrl,\n errorUrl: kitSettings.errorUrl,\n integrationDomain: domain,\n isLoggingEnabled: mp().config?.isLoggingEnabled === true,\n };\n const errorReportingService = new ErrorReportingService(\n reportingConfig,\n this.integrationName,\n window.__rokt_li_guid__,\n kitSettings.accountId,\n );\n const loggingService = new LoggingService(\n reportingConfig,\n errorReportingService,\n this.integrationName,\n window.__rokt_li_guid__,\n kitSettings.accountId,\n );\n\n this.errorReportingService = errorReportingService;\n this.loggingService = loggingService;\n\n if (this.isTargetingDisabled()) {\n try {\n clearPageViews();\n clearUtmParams();\n } catch (err) {\n this.errorReportingService?.report({\n message: 'Rokt Kit: Failed to clear page views when targeting is disabled',\n code: 'PAGE_VIEW_CAPTURE_FAILED',\n severity: WSDKErrorSeverity.INFO,\n stackTrace: err instanceof Error ? err.stack : undefined,\n });\n }\n }\n\n if (mp()._registerErrorReportingService) {\n mp()._registerErrorReportingService!(errorReportingService);\n }\n if (mp()._registerLoggingService) {\n mp()._registerLoggingService!(loggingService);\n }\n\n if (testMode) {\n this.testHelpers = {\n generateLauncherScript: generateLauncherScript,\n generateThankYouElementScript: generateThankYouElementScript,\n extractRoktExtensionConfig: extractRoktExtensionConfig,\n hashEventMessage: hashEventMessage,\n parseSettingsString: parseSettingsString,\n generateMappedEventLookup: generateMappedEventLookup,\n generateMappedEventAttributeLookup: generateMappedEventAttributeLookup,\n sendAdBlockMeasurementSignals: sendAdBlockMeasurementSignals,\n createAutoRemovedIframe: createAutoRemovedIframe,\n djb2: djb2,\n setAllowedOriginHashes: (hashes: number[]) => {\n RoktKit._allowedOriginHashes = hashes;\n },\n ReportingTransport: ReportingTransport,\n ErrorReportingService: ErrorReportingService,\n LoggingService: LoggingService,\n RateLimiter: RateLimiter,\n ErrorCodes: ErrorCodes,\n WSDKErrorSeverity: WSDKErrorSeverity,\n resetLauncherAttachState: () => resetLauncherAttachState(this._launcherAttachState),\n };\n this.attachLauncher(accountId, launcherOptions);\n return 'Successfully initialized: ' + name;\n }\n\n if (loadThankYouElement) {\n mp().Rokt.flushOnShoppableAdsReadyMessageQueue?.(this);\n loadRoktScript(ROKT_THANK_YOU_ELEMENT_SCRIPT_ID, generateThankYouElementScript(domain), {\n onLoad: () => {\n this._isThankYouElementLoaded = true;\n if (this._thankYouElementOnLoadCallback) {\n this._thankYouElementOnLoadCallback();\n }\n },\n onError: (error) => {\n console.error('Error loading Rokt Thank You Element script:', error);\n },\n });\n }\n\n if (this.isLauncherReadyToAttach()) {\n this.attachLauncher(accountId, launcherOptions, legacyRoktExtensions);\n } else {\n loadRoktScript(ROKT_INTEGRATION_SCRIPT_ID, generateLauncherScript(domain, roktExtensionsQueryParams), {\n onLoad: () => {\n if (this.isLauncherReadyToAttach()) {\n this.attachLauncher(accountId, launcherOptions, legacyRoktExtensions);\n } else {\n console.error('Rokt object is not available after script load.');\n }\n },\n onError: (error) => {\n console.error('Error loading Rokt launcher script:', error);\n },\n });\n\n this.captureTiming(RoktKit.PERFORMANCE_MARKS.RoktScriptAppended);\n }\n\n return 'Successfully initialized: ' + name;\n }\n\n public process(event: SDKEvent): string {\n if (!this.isTargetingDisabled()) {\n if (event.EventDataType === MESSAGE_TYPE_PAGE_VIEW) {\n captureUtmParams(this.loggingService);\n this.capturePageView(event);\n }\n\n if (event.EventDataType === MESSAGE_TYPE_SESSION_END) {\n clearPageViews();\n clearUtmParams();\n }\n }\n\n // The forwarding work below (LSA mapping) depends on the launcher, so guard\n // it here and surface the not-ready signal to the core SDK.\n if (!this.isKitReady()) {\n return 'Kit not ready for forwarder: ' + name;\n }\n\n if (isFunction(mp().Rokt?.setLocalSessionAttribute)) {\n if (!isEmpty(this.placementEventAttributeMappingLookup)) {\n this.applyPlacementEventAttributeMapping(event);\n }\n\n if (!isEmpty(this.placementEventMappingLookup)) {\n const hashedEvent = hashEventMessage(event.EventDataType, event.EventCategory, event.EventName ?? '');\n if (this.placementEventMappingLookup[String(hashedEvent)]) {\n mp().Rokt.setLocalSessionAttribute?.(this.placementEventMappingLookup[String(hashedEvent)], true);\n }\n }\n }\n\n return 'Successfully sent to forwarder: ' + name;\n }\n\n public setExtensionData(partnerExtensionData: Record): void {\n if (!this.isKitReady()) {\n console.error('Rokt Kit: Not initialized');\n return;\n }\n\n window.Rokt!.setExtensionData(partnerExtensionData);\n }\n\n public setUserAttribute(key: string, value: unknown): string {\n if (!isSelectPlacementsAttributePersistenceDenied(key)) {\n this.userAttributes[key] = value;\n }\n return 'Successfully set user attribute for forwarder: ' + name;\n }\n\n public removeUserAttribute(key: string): string {\n delete this.userAttributes[key];\n return 'Successfully removed user attribute for forwarder: ' + name;\n }\n\n private handleIdentityComplete(user: IMParticleUser, callbackName: string): string {\n this.userAttributes = removeSelectPlacementsAttributePersistenceDeniedAttributes(user.getAllUserAttributes());\n return 'Successfully called ' + callbackName + ' for forwarder: ' + name;\n }\n\n public onUserIdentified(user: IMParticleUser): string {\n const filteredUser = user as FilteredUser;\n this.filters.filteredUser = filteredUser;\n this._workspaceSearchInFlightPromise = this.search(filteredUser);\n return this.handleIdentityComplete(user, 'onUserIdentified');\n }\n\n private search(filteredUser: FilteredUser): Promise {\n const apiKey = this._workspaceIdSyncApiKey;\n if (!apiKey) {\n this.userIdentifiedInWorkspace = false;\n this._workspaceLastSearchedIdentitiesKey = undefined;\n return Promise.resolve();\n }\n const search = mp().Identity?.search;\n if (typeof search !== 'function') {\n this.userIdentifiedInWorkspace = false;\n this._workspaceLastSearchedIdentitiesKey = undefined;\n return Promise.resolve();\n }\n\n const userIdentities: IUserIdentities | null = filteredUser.getUserIdentities\n ? filteredUser.getUserIdentities().userIdentities\n : null;\n\n // Forward every non-empty string identifier the user has — email,\n // customerid, other/other2-10 (commonly used for hashed email),\n // mobile_number, facebook, etc. The host SDK's Identity.search accepts\n // the full IUserIdentities surface and the server validates it.\n const knownIdentities: Record = {};\n if (userIdentities) {\n for (const key of Object.keys(userIdentities) as Array) {\n const value = userIdentities[key];\n if (isString(value) && value.length > 0) {\n knownIdentities[key] = value;\n }\n }\n }\n\n const identityKeys = Object.keys(knownIdentities);\n if (identityKeys.length === 0) {\n this.userIdentifiedInWorkspace = false;\n this._workspaceLastSearchedIdentitiesKey = undefined;\n return Promise.resolve();\n }\n\n // Stable cache key: sort keys so insertion-order differences don't\n // cause false misses. The values are partner-supplied strings; no\n // hashing needed — equality on this serialization is sufficient.\n const identitiesKey = identityKeys\n .sort()\n .map((k) => `${k}=${knownIdentities[k]}`)\n .join('&');\n\n // Same identifier set as the last successful dispatch → skip the\n // network call. The current flag value still reflects the correct\n // match status.\n if (identitiesKey === this._workspaceLastSearchedIdentitiesKey) {\n return this._workspaceSearchInFlightPromise || Promise.resolve();\n }\n\n // New / different identifier set → reset and re-search. Cache the key\n // up front so a second concurrent invocation with the same set also\n // dedupes.\n this.userIdentifiedInWorkspace = false;\n this._workspaceLastSearchedIdentitiesKey = identitiesKey;\n\n return new Promise((resolve) => {\n try {\n search(apiKey, knownIdentities as IUserIdentities, (result: WorkspaceIdSyncResult) => {\n if (result?.httpCode === 200) {\n this.userIdentifiedInWorkspace = true;\n }\n resolve();\n });\n } catch (err) {\n console.error('Rokt Kit: Workspace IDSync search failed', err);\n // Dispatch failed — clear the cache so the same identifier set\n // can retry on the next identification rather than being stuck\n // behind a poisoned entry that short-circuits future searches.\n this._workspaceLastSearchedIdentitiesKey = undefined;\n resolve();\n }\n });\n }\n\n public onLoginComplete(user: IMParticleUser, _filteredIdentityRequest: unknown): string {\n return this.handleIdentityComplete(user, 'onLoginComplete');\n }\n\n public onLogoutComplete(user: IMParticleUser, _filteredIdentityRequest: unknown): string {\n // Anonymous sessions must not carry the previous user's match forward.\n // Clear the flag explicitly here. Also clear the identities cache so a\n // re-login (possibly with the same identifiers) dispatches a fresh\n // search rather than reusing a stale answer.\n this.userIdentifiedInWorkspace = false;\n this._workspaceSearchInFlightPromise = null;\n this._workspaceLastSearchedIdentitiesKey = undefined;\n return this.handleIdentityComplete(user, 'onLogoutComplete');\n }\n\n public onModifyComplete(user: IMParticleUser, _filteredIdentityRequest: unknown): string {\n return this.handleIdentityComplete(user, 'onModifyComplete');\n }\n\n /**\n * Selects placements for Rokt Web SDK with merged attributes, filters, and experimentation options.\n *\n * If a Workspace IDSync search is in flight from a recent onUserIdentified\n * call, this method waits up to `WORKSPACE_SEARCH_SELECT_TIMEOUT_MS` for it\n * to settle so the first placement call can include the\n * `userIdentifiedInWorkspace` flag without racing the network response.\n * The timeout protects against a stalled or slow search blocking placement\n * rendering — if it fires, selectPlacements proceeds without the flag.\n *\n * Implementation note: this method stays non-async deliberately. First,\n * the public return type is `RoktSelection | Promise |\n * undefined` — a superset of the `RoktSelection | Promise`\n * shape declared for `RoktLauncher.selectPlacements` above (line ~70).\n * Marking this `async` would narrow it to `Promise` and silently change the contract for callers that read\n * the result synchronously. Second, `RoktSelection` has an optional\n * `then?` member, so TS treats it as ambiguously promise-like and\n * rejects it as the awaited return of an async function (TS1058) —\n * working around that would require a cast or wrapping every return in\n * `Promise.resolve(...)`. The inner work runs in `_dispatchPlacements`;\n * this wrapper just gates it on the in-flight search via `Promise.race`,\n * and on a post-terminate createLauncher when the SPA needs a new instance.\n */\n public selectPlacements(options: Record): RoktSelection | Promise | undefined {\n const recreate = this.recreateLauncherIfTerminated();\n if (recreate) {\n const inFlight = this._workspaceSearchInFlightPromise;\n const waitForSearch = inFlight\n ? Promise.race([\n inFlight,\n new Promise((resolve) => setTimeout(resolve, WORKSPACE_SEARCH_SELECT_TIMEOUT_MS)),\n ])\n : Promise.resolve();\n return Promise.all([recreate, waitForSearch]).then(() =>\n this._dispatchPlacements(options),\n ) as Promise;\n }\n if (this._workspaceSearchInFlightPromise) {\n const inFlight = this._workspaceSearchInFlightPromise;\n return Promise.race([\n inFlight,\n new Promise((resolve) => setTimeout(resolve, WORKSPACE_SEARCH_SELECT_TIMEOUT_MS)),\n ]).then(() => this._dispatchPlacements(options)) as Promise;\n }\n return this._dispatchPlacements(options);\n }\n\n private _dispatchPlacements(options: Record): RoktSelection | Promise | undefined {\n const attributes = ((options && (options.attributes as Record)) || {}) as Record;\n const cachedUserAttributes = removeSelectPlacementsAttributePersistenceDeniedAttributes(this.userAttributes);\n const placementAttributes: Record = { ...cachedUserAttributes, ...attributes };\n\n const filters = this.filters || {};\n const userAttributeFilters = (filters.userAttributeFilters as string[]) || [];\n const filteredUser = filters.filteredUser || null;\n const mpid = filteredUser ? filteredUser.getMPID() : null;\n\n let filteredAttributes: Record;\n\n if (!filters) {\n console.warn('Rokt Kit: No filters available, using user attributes');\n filteredAttributes = placementAttributes;\n } else if (filters.filterUserAttributes) {\n filteredAttributes = filters.filterUserAttributes(placementAttributes, userAttributeFilters);\n } else {\n filteredAttributes = placementAttributes;\n }\n\n this.userAttributes = removeSelectPlacementsAttributePersistenceDeniedAttributes(filteredAttributes);\n\n const optimizelyAttributes = this._onboardingExpProvider === 'Optimizely' ? this.fetchOptimizely() : {};\n\n const filteredUserIdentities = this.returnUserIdentities(filteredUser);\n\n const sessionAttributes = this.returnLocalSessionAttributes();\n const pageEvents = buildPageEvents(loadPageViews());\n const utmParams = loadUtmParams();\n const mpSessionId = this.readMpSessionId();\n const mpDeviceId = this.readMpDeviceId();\n\n const selectPlacementsAttributes: Record = {\n ...(filteredUserIdentities as Record),\n ...filteredAttributes,\n ...optimizelyAttributes,\n ...sessionAttributes,\n ...(pageEvents.length ? { [PAGE_EVENTS_KEY]: JSON.stringify(pageEvents) } : {}),\n ...(utmParams ? { [PAGE_VIEW_ATTRIBUTES_KEY]: utmParams } : {}),\n ...(this.userIdentifiedInWorkspace ? { [USER_IDENTIFIED_IN_WORKSPACE_KEY]: true } : {}),\n ...(mpSessionId ? { [MPARTICLE_SESSION_ID_KEY]: mpSessionId } : {}),\n ...(mpDeviceId ? { [MPARTICLE_DEVICE_ID_KEY]: mpDeviceId } : {}),\n mpid,\n };\n\n const selectPlacementsOptions: Record = { ...options, attributes: selectPlacementsAttributes };\n\n const selection = this.launcher!.selectPlacements(selectPlacementsOptions);\n\n // After selection resolves, sync the Rokt session ID back to mParticle, then log\n const logSelection = () => this.logSelectPlacementsEvent(selectPlacementsAttributes);\n\n void Promise.resolve(selection)\n .then((sel) => sel?.context?.sessionId?.then((sessionId) => this.setRoktSessionId(sessionId)))\n .catch(() => undefined)\n .finally(logSelection);\n\n return selection;\n }\n\n /**\n * Passes attributes to the Rokt Web SDK for client-side hashing.\n */\n public hashAttributes(attributes: Record): Promise> | null {\n if (!this.isKitReady()) {\n console.error('Rokt Kit: Not initialized');\n return null;\n }\n return this.launcher!.hashAttributes(attributes);\n }\n\n /**\n * Enables optional Integration Launcher extensions before selecting placements.\n *\n * @deprecated This functionality has been internalized and will be removed in a future release.\n */\n public use(extensionName: string): Promise {\n if (!this.isKitReady()) {\n console.error('Rokt Kit: Not initialized');\n return Promise.reject(new Error('Rokt Kit: Not initialized'));\n }\n if (!extensionName || !isString(extensionName)) {\n return Promise.reject(new Error('Rokt Kit: Invalid extension name'));\n }\n return this.launcher!.use(extensionName);\n }\n\n /**\n * Tears down the Rokt launcher and the placements it rendered.\n *\n * The kit's launcher reference is left in place so isKitReady() stays true.\n * The Web SDK clears its memoized launcher on terminate, so a later\n * createLauncher (SPA navigation) produces a new instance. The next\n * selectPlacements call re-attaches that instance. Nulling the reference\n * here would flip the kit to not-ready with no drain path for queued calls.\n */\n public terminate(): Promise {\n if (!this.isKitReady()) {\n console.error('Rokt Kit: Not initialized');\n return Promise.resolve();\n }\n markLauncherTerminated(this._launcherAttachState);\n return this.launcher!.terminate();\n }\n\n /**\n * Registers a callback to be invoked once rokt-thank-you-element.js becomes available.\n */\n public onShoppableAdsReady(callback: () => void) {\n if (this._isThankYouElementLoaded) {\n callback();\n } else {\n this._thankYouElementOnLoadCallback = callback;\n }\n }\n}\n\n// ============================================================\n// Kit registration\n// ============================================================\n\nfunction getId(): number {\n return moduleId;\n}\n\nfunction register(config: { kits?: Record }): void {\n if (!config) {\n window.console.log('You must pass a config object to register the kit ' + name);\n return;\n }\n if (!isObject(config)) {\n window.console.log(\"'config' must be an object. You passed in a \" + typeof config);\n return;\n }\n\n if (isObject(config.kits)) {\n (config.kits as Record)[name] = {\n constructor: RoktKit,\n };\n } else {\n config.kits = {};\n config.kits[name] = {\n constructor: RoktKit,\n };\n }\n window.console.log('Successfully registered ' + name + ' to your mParticle configuration');\n}\n\nif (typeof window !== 'undefined' && window.mParticle && mp().addForwarder) {\n mp().addForwarder({\n name: name,\n constructor: RoktKit,\n getId: getId,\n });\n}\n\nexport { register };\nexport type { LoggingService };\n"],"names":["SELECT_PLACEMENTS_ATTRIBUTE_PERSISTENCE_DENY_LIST","SELECT_PLACEMENTS_ATTRIBUTE_PERSISTENCE_DENY_SET","isSelectPlacementsAttributePersistenceDenied","key","removeSelectPlacementsAttributePersistenceDeniedAttributes","attributes","filteredAttributes","sourceAttributes","attributeKeys","i","isObject","value","isString","isFunction","isEmpty","sanitizeUrl","href","url","LS_PROBE_KEY","isLocalStorageAvailable","readJSON","stored","writeJSON","removeKey","readNamespacedField","namespaceKey","field","blob","writeNamespacedField","next","removeNamespacedField","LS_NAMESPACE_KEY","LS_PAGE_VIEWS_FIELD","LS_UTM_PARAMS_FIELD","PAGE_VIEWS_MAX_COUNT","UTM_KEYS","capPageViews","views","loadPageViews","writePageViews","pageViews","toWrite","clearPageViews","buildPageEvents","pageView","index","activeTimeOnSite","hasActiveTime","nextActiveTimeOnSite","hasNextActiveTimeOnSite","diff","captureUtmParams","loggingService","search","params","captured","reason","loadUtmParams","clearUtmParams","readCanonicalUrl","createLauncherAttachState","rememberAttachContext","state","context","markLauncherAttached","markLauncherTerminated","markLauncherAttachFailed","resetLauncherAttachState","recreateIfTerminated","canAttach","attach","name","moduleId","EVENT_NAME_SELECT_PLACEMENTS","ADBLOCK_CONTROL_DOMAIN","INIT_LOG_SAMPLING_RATE","ROKT_THANK_YOU_JOURNEY_EXTENSION","ROKT_INTEGRATION_SCRIPT_ID","ROKT_THANK_YOU_ELEMENT_SCRIPT_ID","USER_IDENTIFIED_IN_WORKSPACE_KEY","MESSAGE_TYPE_PAGE_VIEW","MESSAGE_TYPE_SESSION_END","PAGE_EVENTS_KEY","PAGE_VIEW_ATTRIBUTES_KEY","MPARTICLE_SESSION_ID_KEY","MPARTICLE_DEVICE_ID_KEY","WORKSPACE_SEARCH_SELECT_TIMEOUT_MS","ErrorCodes","WSDKErrorSeverity","DEFAULT_ROKT_DOMAIN","LOGGING_ENDPOINT","ERROR_ENDPOINT","RATE_LIMIT_PER_SEVERITY","mp","generateLauncherScript","domain","extensions","baseUrl","generateBaseUrl","generateThankYouElementScript","resolvedDomain","generateReportingUrl","configuredUrl","endpoint","reportingDomain","loadRoktScript","scriptId","source","handlers","target","script","parseSettingsString","settingsString","extractRoktExtensionConfig","settings","roktExtensionsQueryParams","legacyRoktExtensions","loadThankYouElement","extensionName","registerLegacyExtensions","legacyExtensions","launcher","extension","generateMappedEventLookup","placementEventMapping","mappedEvents","mapping","generateMappedEventAttributeLookup","placementEventAttributeMapping","mappedAttributeKeys","mappedAttributeKey","eventAttributeKey","hashEventMessage","messageType","eventType","eventName","generateIntegrationName","customIntegrationName","integrationName","djb2","str","hash","createAutoRemovedIframe","src","iframe","sendAdBlockMeasurementSignals","version","originHash","RoktKit","guid","pageUrl","existingBaseUrl","_isDebugModeEnabled","_getReportingUrl","_getUserAgent","RateLimiter","severity","newCount","ReportingTransport","config","launcherInstanceGuid","accountId","rateLimiter","isLoggingEnabled","msg","code","stackTrace","onError","logRequest","headers","response","serverError","error","ErrorReportingService","LoggingService","errorReportingService","entry","isServerSide","buildPageEvent","event","pageTitle","canonicalUrl","_RoktKit","condition","actualValue","operator","expectedValue","rule","conditions","rulesForMappedAttributeKey","allMatch","j","requested","err","errMessage","filteredUser","userIdentities","newUserIdentities","EVENT_TYPE_OTHER","sessionId","mpInstance","sessionManager","readSessionId","launcherOptions","options","launcherPromise","roktFilters","forwarders","forwarder","optimizelyState","acc","expId","metricName","_service","testMode","_trackerId","filteredUserAttributes","kitSettings","reportingConfig","hashes","hashedEvent","partnerExtensionData","user","callbackName","apiKey","knownIdentities","identityKeys","identitiesKey","k","resolve","result","_filteredIdentityRequest","recreate","inFlight","waitForSearch","placementAttributes","filters","userAttributeFilters","mpid","optimizelyAttributes","filteredUserIdentities","sessionAttributes","pageEvents","utmParams","mpSessionId","mpDeviceId","selectPlacementsAttributes","selectPlacementsOptions","selection","logSelection","sel","callback","getId","register"],"mappings":"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"} \ No newline at end of file