@sentientui/core 0.16.8 → 0.16.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,2 +1,2 @@
1
- import{a as b,d as v}from"./chunk-CD2A55US.mjs";import{a as T,i as N,k as A}from"./chunk-DM2GHMYU.mjs";import{d as $,e as k,f as U,g as L,h as j}from"./chunk-L5TA3FAB.mjs";import{a as y,b as I}from"./chunk-TMCGHANO.mjs";var x="_snt_graph_edges",K={pricing:["features","faq"],features:["pricing"],faq:["pricing"],social_proof:["cta"],cta:["social_proof","hero","trust"],hero:["cta"],comparison:["pricing"],trust:["cta"]};function z(e){var t;return(t=K[e])!=null?t:[]}function F(e,t){try{let n=localStorage.getItem(e);return n?JSON.parse(n):t}catch(n){return t}}function q(e,t){try{localStorage.setItem(e,JSON.stringify(t))}catch(n){}}var B=new Set(["pricing","hero","social_proof","cta","features","faq","comparison","trust","navigation","generic"]);function H(e){return B.has(e)?e:"generic"}function _(e){try{let t=new URL(e);return`${t.origin}${t.pathname}`}catch(t){return"/"}}function J(e,t,n){let d=`${e}:${t}:${n.join(",")}`,p=5381;for(let m=0;m<d.length;m++)p=(p<<5)+p+d.charCodeAt(m)&4294967295;return(p>>>0).toString(16).padStart(8,"0")}function M(e){let t=new Map,n=new Map,d=`_snt_graph_nodes${T(e==null?void 0:e.apiKey)}`,p=()=>{typeof window!="undefined"&&q(d,[...t.values()])},m=o=>{var a;try{let i=JSON.parse(o);t.clear();for(let c of(a=i.pageNodes)!=null?a:[])t.set(c.componentId,c)}catch(i){}};if(typeof window!="undefined"){let o=F(d,[]);for(let a of o)t.set(a.componentId,a);try{localStorage.removeItem(x)}catch(a){}}return{addPageNode(o){t.set(o.componentId,o),p()},addStructuralEdge(o){let a=`${o.fromComponentId}->${o.toComponentId}`;n.set(a,o)},syncOnce(){var a,i;if(!(e!=null&&e.syncUrl)||typeof window=="undefined")return;let o=[...t.values()];if(o.length!==0)try{let c=new Map;for(let s of o){let f=(a=c.get(s.semanticType))!=null?a:[];f.push(s),c.set(s.semanticType,f)}let u=[],l=new Set;for(let s of o)for(let f of z(s.semanticType)){let S=(i=c.get(f))!=null?i:[];for(let h of S){if(h.componentId===s.componentId)continue;let w=`semantic:${s.componentId}->${h.componentId}`;l.has(w)||(l.add(w),u.push({fromComponentId:s.componentId,toComponentId:h.componentId,type:"semantic",weight:.4,confidence:.9}))}}let g=new Set(o.map(s=>s.componentId));for(let s of n.values()){if(!g.has(s.fromComponentId)||!g.has(s.toComponentId))continue;let f=`structural:${s.fromComponentId}->${s.toComponentId}`;l.has(f)||(l.add(f),u.push({fromComponentId:s.fromComponentId,toComponentId:s.toComponentId,type:"structural",weight:s.weight,confidence:1}))}let r=I(y(y({pageUrl:_(window.location.href)},e.sessionId?{sessionId:e.sessionId}:{}),e.projectId?{projectId:e.projectId}:{}),{nodes:o.map(s=>{let f=H(s.semanticType);return{componentId:s.componentId,semanticType:f,answers:s.answers,contentHash:J(s.componentId,f,s.answers),prominenceScore:s.prominenceScore,depthInPage:s.depth}}),edges:u});fetch(e.syncUrl,{method:"POST",keepalive:!0,headers:y({"Content-Type":"application/json"},e.apiKey?{Authorization:`Bearer ${e.apiKey}`}:{}),body:JSON.stringify(r)}).catch(()=>{})}catch(c){}},snapshot(){return{pageNodes:[...t.values()],capturedAt:Date.now()}},serialize(){return JSON.stringify({pageNodes:[...t.values()]})},restore:m,destroy(){if(typeof window!="undefined")try{localStorage.removeItem(d),localStorage.removeItem(x)}catch(o){}}}}var V=new Set(["SECTION","ARTICLE","MAIN","DIV"]),W="h1, h2, h3",O=30,Y=1500,Q={scan:async()=>({nodes:[],edges:[],scannedAt:0}),observe:()=>{},getProminenceScore:()=>0,destroy:()=>{}};function R(e,t,n){return n<=t?0:Math.max(0,Math.min(1,(e-t)/(n-t)))}function X(e){var t,n,d;try{let p=e;for(let m of Object.keys(p)){if(!m.startsWith("__reactFiber")&&!m.startsWith("__reactInternalInstance"))continue;let o=p[m],a=(d=(t=o==null?void 0:o.type)==null?void 0:t.displayName)!=null?d:(n=o==null?void 0:o.type)==null?void 0:n.name;if(a&&a.length>1)return a}}catch(p){}}function Z(e){let t={};for(let n of Array.from(e.attributes))n.name.startsWith("data-")&&(t[n.name]=n.value);return t}var P=new Set(b);function ee(e){let t=e.getAttribute("data-sentient-type");if(t&&P.has(t))return t;let n=e.getAttribute("role");return n&&P.has(n)?n:v(e)}function te(e){let t=5381;for(let n=0;n<e.length;n++)t=(t<<5)+t+e.charCodeAt(n)&4294967295;return(t>>>0).toString(16).padStart(8,"0")}function ne(e){let t=[],n=e;for(;n;){let d=n.parentElement;if(!d){t.push(n.tagName.toLowerCase());break}let p=Array.prototype.indexOf.call(d.children,n);t.push(`${n.tagName.toLowerCase()}[${p}]`),n=d}return t.reverse().join("/")}function oe(e){var n;let t=(n=e.getAttribute("data-sentient-id"))!=null?n:e.getAttribute("id");return t||`${e.tagName.toLowerCase()}-${te(ne(e))}`}function re(e){let t=0,n=e.parentElement;for(;n;)t++,n=n.parentElement;return t}function C(e,t){var d,p,m;let n=e.querySelector(W);return{componentId:oe(e),semanticType:ee(e),ariaLabel:(d=e.getAttribute("aria-label"))!=null?d:void 0,headingText:(m=(p=n==null?void 0:n.textContent)==null?void 0:p.trim())!=null?m:void 0,isAboveFold:e.getBoundingClientRect().top<window.innerHeight,prominenceScore:t(e),depth:re(e),reactComponentName:X(e),dataAttributes:Z(e)}}function D(e){var m;let t=[],n=new Set,d="__root__",p=new Map;for(let[o,a]of e){let i=o.parentElement,c=d;for(;i;){if(e.has(i)){c=e.get(i);let l=e.get(o),g=`${c}->${l}`;!n.has(g)&&c!==l&&(n.add(g),t.push({fromComponentId:c,toComponentId:l,weight:.6}));break}i=i.parentElement}let u=(m=p.get(c))!=null?m:[];u.push(o),p.set(c,u)}for(let o of p.values()){if(o.length<2)continue;let a=o.length>O?o.slice(0,O):o;for(let i=0;i<a.length;i++)for(let c=i+1;c<a.length;c++){if(t.length>=Y)return t;let u=e.get(a[i]),l=e.get(a[c]);if(u===l)continue;let g=`${u}->${l}::sib`,r=`${l}->${u}::sib`;n.has(g)||(n.add(g),t.push({fromComponentId:u,toComponentId:l,weight:.3})),n.has(r)||(n.add(r),t.push({fromComponentId:l,toComponentId:u,weight:.3}))}}return t}function se(e){let t=[],n=new Set,d=new Map;return document.querySelectorAll("[data-sentient-id]").forEach(o=>{if(o instanceof Element&&!n.has(o)){n.add(o);let a=C(o,e);t.push(a),d.set(o,a.componentId)}}),document.querySelectorAll("section, article, main, aside").forEach(o=>{if(!(o instanceof Element)||n.has(o))return;let a=o.hasAttribute("aria-label"),i=o.hasAttribute("data-sentient-id");if(!a&&!i)return;n.add(o);let c=C(o,e);t.push(c),d.set(o,c.componentId)}),{nodes:t,edges:D(d),elementToId:d}}function G(){if(typeof window=="undefined")return Q;let e=null,t=0,n=null,d=new Map,p=i=>{try{let c=window.getComputedStyle(i),u=parseFloat(c.fontSize)||12,l=parseFloat(c.zIndex)||0,g=i.getBoundingClientRect(),r=Math.max(g.top,0),s=window.innerHeight||1,f=1/(r/s+1),S=R(u,12,48)*.4+f*.4+R(l,0,100)*.2;return Math.max(0,Math.min(1,S))}catch(c){return .5}};return{scan:()=>new Promise(i=>{let c=()=>{let{nodes:u,edges:l,elementToId:g}=se(p);d.clear();for(let[r,s]of g)d.set(r,s);i({nodes:u,edges:l,scannedAt:Date.now()})};try{typeof requestIdleCallback=="function"?t=requestIdleCallback(c,{timeout:100}):c()}catch(u){c()}}),observe:i=>{n=i;try{e=new MutationObserver(c=>{let u=[],l=new Set;for(let r of c)r.type==="childList"&&r.addedNodes.forEach(s=>{if(!(s instanceof Element)||!V.has(s.tagName))return;let f=s.hasAttribute("data-sentient-id"),S=s.hasAttribute("aria-label");if(!f&&!S)return;let h=C(s,p);u.push(h),l.add(h.componentId),d.set(s,h.componentId)});if(u.length===0||!n)return;for(let r of[...d.keys()])r.isConnected||d.delete(r);let g=D(d).filter(r=>l.has(r.fromComponentId)||l.has(r.toComponentId));n({nodes:u,edges:g,addedAt:Date.now()})}),e.observe(document.body,{childList:!0,subtree:!0})}catch(c){}},getProminenceScore:p,destroy:()=>{if(e&&(e.disconnect(),e=null),t&&typeof cancelIdleCallback=="function")try{cancelIdleCallback(t)}catch(i){}t=0,n=null,d.clear()}}}var ae="https://api.sentient-ui.com/v1/events";function ie(){try{let e=document.cookie.match(/(?:^|; )_snt_uid=([^;]*)/);return e?decodeURIComponent(e[1]):void 0}catch(e){return}}var E=new Map;function he(e){var l;let t=A(e),n=e.respectDoNotTrack!==!1&&N(),d=e.consent===!1||n;if(!e.graph||!e.apiKey||d||typeof window=="undefined")return t;let p=E.get(e.apiKey);if(p)try{p()}catch(g){}let m=G(),o=(l=e.ingestUrl)!=null?l:ae,a=M({syncUrl:o.replace(/\/events\/?$/,"/graph/sync"),apiKey:e.apiKey,projectId:e.apiKey,sessionId:ie()});m.scan().then(g=>{for(let r of g.nodes)a.addPageNode({id:r.componentId,componentId:r.componentId,semanticType:r.semanticType,answers:e.captureDomText&&r.headingText?[r.headingText]:[],prominenceScore:r.prominenceScore,depth:r.depth});for(let r of g.edges)a.addStructuralEdge(r);a.syncOnce()});let i=null,c=()=>{i!==null&&clearTimeout(i),i=setTimeout(()=>{i=null,a.syncOnce()},500)};m.observe(g=>{for(let r of g.nodes)a.addPageNode({id:r.componentId,componentId:r.componentId,semanticType:r.semanticType,answers:e.captureDomText&&r.headingText?[r.headingText]:[],prominenceScore:r.prominenceScore,depth:r.depth});for(let r of g.edges)a.addStructuralEdge(r);c()});let u=()=>{i!==null&&(clearTimeout(i),i=null),m.destroy(),a.destroy(),E.get(e.apiKey)===u&&E.delete(e.apiKey)};return E.set(e.apiKey,u),I(y({},t),{getGraph:()=>a.snapshot(),dispose:()=>{u(),t.dispose()},destroy:()=>{u(),t.destroy()}})}export{j as deriveSessionSegment,$ as detectDeviceClass,L as detectTimeOfDay,k as detectTrafficSource,he as init,U as referrerDomainFromReferer,_ as sanitizePageUrl};
1
+ import{a as b,d as v}from"./chunk-CD2A55US.mjs";import{a as T,i as N,k as A}from"./chunk-Q7L7OPE4.mjs";import{g as $,h as k,i as U,j as L,k as j}from"./chunk-MYT7OJBV.mjs";import{a as y,b as I}from"./chunk-TMCGHANO.mjs";var x="_snt_graph_edges",K={pricing:["features","faq"],features:["pricing"],faq:["pricing"],social_proof:["cta"],cta:["social_proof","hero","trust"],hero:["cta"],comparison:["pricing"],trust:["cta"]};function z(e){var t;return(t=K[e])!=null?t:[]}function F(e,t){try{let n=localStorage.getItem(e);return n?JSON.parse(n):t}catch(n){return t}}function q(e,t){try{localStorage.setItem(e,JSON.stringify(t))}catch(n){}}var B=new Set(["pricing","hero","social_proof","cta","features","faq","comparison","trust","navigation","generic"]);function H(e){return B.has(e)?e:"generic"}function _(e){try{let t=new URL(e);return`${t.origin}${t.pathname}`}catch(t){return"/"}}function J(e,t,n){let d=`${e}:${t}:${n.join(",")}`,p=5381;for(let m=0;m<d.length;m++)p=(p<<5)+p+d.charCodeAt(m)&4294967295;return(p>>>0).toString(16).padStart(8,"0")}function M(e){let t=new Map,n=new Map,d=`_snt_graph_nodes${T(e==null?void 0:e.apiKey)}`,p=()=>{typeof window!="undefined"&&q(d,[...t.values()])},m=o=>{var a;try{let i=JSON.parse(o);t.clear();for(let c of(a=i.pageNodes)!=null?a:[])t.set(c.componentId,c)}catch(i){}};if(typeof window!="undefined"){let o=F(d,[]);for(let a of o)t.set(a.componentId,a);try{localStorage.removeItem(x)}catch(a){}}return{addPageNode(o){t.set(o.componentId,o),p()},addStructuralEdge(o){let a=`${o.fromComponentId}->${o.toComponentId}`;n.set(a,o)},syncOnce(){var a,i;if(!(e!=null&&e.syncUrl)||typeof window=="undefined")return;let o=[...t.values()];if(o.length!==0)try{let c=new Map;for(let s of o){let f=(a=c.get(s.semanticType))!=null?a:[];f.push(s),c.set(s.semanticType,f)}let u=[],l=new Set;for(let s of o)for(let f of z(s.semanticType)){let S=(i=c.get(f))!=null?i:[];for(let h of S){if(h.componentId===s.componentId)continue;let w=`semantic:${s.componentId}->${h.componentId}`;l.has(w)||(l.add(w),u.push({fromComponentId:s.componentId,toComponentId:h.componentId,type:"semantic",weight:.4,confidence:.9}))}}let g=new Set(o.map(s=>s.componentId));for(let s of n.values()){if(!g.has(s.fromComponentId)||!g.has(s.toComponentId))continue;let f=`structural:${s.fromComponentId}->${s.toComponentId}`;l.has(f)||(l.add(f),u.push({fromComponentId:s.fromComponentId,toComponentId:s.toComponentId,type:"structural",weight:s.weight,confidence:1}))}let r=I(y(y({pageUrl:_(window.location.href)},e.sessionId?{sessionId:e.sessionId}:{}),e.projectId?{projectId:e.projectId}:{}),{nodes:o.map(s=>{let f=H(s.semanticType);return{componentId:s.componentId,semanticType:f,answers:s.answers,contentHash:J(s.componentId,f,s.answers),prominenceScore:s.prominenceScore,depthInPage:s.depth}}),edges:u});fetch(e.syncUrl,{method:"POST",keepalive:!0,headers:y({"Content-Type":"application/json"},e.apiKey?{Authorization:`Bearer ${e.apiKey}`}:{}),body:JSON.stringify(r)}).catch(()=>{})}catch(c){}},snapshot(){return{pageNodes:[...t.values()],capturedAt:Date.now()}},serialize(){return JSON.stringify({pageNodes:[...t.values()]})},restore:m,destroy(){if(typeof window!="undefined")try{localStorage.removeItem(d),localStorage.removeItem(x)}catch(o){}}}}var V=new Set(["SECTION","ARTICLE","MAIN","DIV"]),W="h1, h2, h3",O=30,Y=1500,Q={scan:async()=>({nodes:[],edges:[],scannedAt:0}),observe:()=>{},getProminenceScore:()=>0,destroy:()=>{}};function R(e,t,n){return n<=t?0:Math.max(0,Math.min(1,(e-t)/(n-t)))}function X(e){var t,n,d;try{let p=e;for(let m of Object.keys(p)){if(!m.startsWith("__reactFiber")&&!m.startsWith("__reactInternalInstance"))continue;let o=p[m],a=(d=(t=o==null?void 0:o.type)==null?void 0:t.displayName)!=null?d:(n=o==null?void 0:o.type)==null?void 0:n.name;if(a&&a.length>1)return a}}catch(p){}}function Z(e){let t={};for(let n of Array.from(e.attributes))n.name.startsWith("data-")&&(t[n.name]=n.value);return t}var P=new Set(b);function ee(e){let t=e.getAttribute("data-sentient-type");if(t&&P.has(t))return t;let n=e.getAttribute("role");return n&&P.has(n)?n:v(e)}function te(e){let t=5381;for(let n=0;n<e.length;n++)t=(t<<5)+t+e.charCodeAt(n)&4294967295;return(t>>>0).toString(16).padStart(8,"0")}function ne(e){let t=[],n=e;for(;n;){let d=n.parentElement;if(!d){t.push(n.tagName.toLowerCase());break}let p=Array.prototype.indexOf.call(d.children,n);t.push(`${n.tagName.toLowerCase()}[${p}]`),n=d}return t.reverse().join("/")}function oe(e){var n;let t=(n=e.getAttribute("data-sentient-id"))!=null?n:e.getAttribute("id");return t||`${e.tagName.toLowerCase()}-${te(ne(e))}`}function re(e){let t=0,n=e.parentElement;for(;n;)t++,n=n.parentElement;return t}function C(e,t){var d,p,m;let n=e.querySelector(W);return{componentId:oe(e),semanticType:ee(e),ariaLabel:(d=e.getAttribute("aria-label"))!=null?d:void 0,headingText:(m=(p=n==null?void 0:n.textContent)==null?void 0:p.trim())!=null?m:void 0,isAboveFold:e.getBoundingClientRect().top<window.innerHeight,prominenceScore:t(e),depth:re(e),reactComponentName:X(e),dataAttributes:Z(e)}}function D(e){var m;let t=[],n=new Set,d="__root__",p=new Map;for(let[o,a]of e){let i=o.parentElement,c=d;for(;i;){if(e.has(i)){c=e.get(i);let l=e.get(o),g=`${c}->${l}`;!n.has(g)&&c!==l&&(n.add(g),t.push({fromComponentId:c,toComponentId:l,weight:.6}));break}i=i.parentElement}let u=(m=p.get(c))!=null?m:[];u.push(o),p.set(c,u)}for(let o of p.values()){if(o.length<2)continue;let a=o.length>O?o.slice(0,O):o;for(let i=0;i<a.length;i++)for(let c=i+1;c<a.length;c++){if(t.length>=Y)return t;let u=e.get(a[i]),l=e.get(a[c]);if(u===l)continue;let g=`${u}->${l}::sib`,r=`${l}->${u}::sib`;n.has(g)||(n.add(g),t.push({fromComponentId:u,toComponentId:l,weight:.3})),n.has(r)||(n.add(r),t.push({fromComponentId:l,toComponentId:u,weight:.3}))}}return t}function se(e){let t=[],n=new Set,d=new Map;return document.querySelectorAll("[data-sentient-id]").forEach(o=>{if(o instanceof Element&&!n.has(o)){n.add(o);let a=C(o,e);t.push(a),d.set(o,a.componentId)}}),document.querySelectorAll("section, article, main, aside").forEach(o=>{if(!(o instanceof Element)||n.has(o))return;let a=o.hasAttribute("aria-label"),i=o.hasAttribute("data-sentient-id");if(!a&&!i)return;n.add(o);let c=C(o,e);t.push(c),d.set(o,c.componentId)}),{nodes:t,edges:D(d),elementToId:d}}function G(){if(typeof window=="undefined")return Q;let e=null,t=0,n=null,d=new Map,p=i=>{try{let c=window.getComputedStyle(i),u=parseFloat(c.fontSize)||12,l=parseFloat(c.zIndex)||0,g=i.getBoundingClientRect(),r=Math.max(g.top,0),s=window.innerHeight||1,f=1/(r/s+1),S=R(u,12,48)*.4+f*.4+R(l,0,100)*.2;return Math.max(0,Math.min(1,S))}catch(c){return .5}};return{scan:()=>new Promise(i=>{let c=()=>{let{nodes:u,edges:l,elementToId:g}=se(p);d.clear();for(let[r,s]of g)d.set(r,s);i({nodes:u,edges:l,scannedAt:Date.now()})};try{typeof requestIdleCallback=="function"?t=requestIdleCallback(c,{timeout:100}):c()}catch(u){c()}}),observe:i=>{n=i;try{e=new MutationObserver(c=>{let u=[],l=new Set;for(let r of c)r.type==="childList"&&r.addedNodes.forEach(s=>{if(!(s instanceof Element)||!V.has(s.tagName))return;let f=s.hasAttribute("data-sentient-id"),S=s.hasAttribute("aria-label");if(!f&&!S)return;let h=C(s,p);u.push(h),l.add(h.componentId),d.set(s,h.componentId)});if(u.length===0||!n)return;for(let r of[...d.keys()])r.isConnected||d.delete(r);let g=D(d).filter(r=>l.has(r.fromComponentId)||l.has(r.toComponentId));n({nodes:u,edges:g,addedAt:Date.now()})}),e.observe(document.body,{childList:!0,subtree:!0})}catch(c){}},getProminenceScore:p,destroy:()=>{if(e&&(e.disconnect(),e=null),t&&typeof cancelIdleCallback=="function")try{cancelIdleCallback(t)}catch(i){}t=0,n=null,d.clear()}}}var ae="https://api.sentient-ui.com/v1/events";function ie(){try{let e=document.cookie.match(/(?:^|; )_snt_uid=([^;]*)/);return e?decodeURIComponent(e[1]):void 0}catch(e){return}}var E=new Map;function he(e){var l;let t=A(e),n=e.respectDoNotTrack!==!1&&N(),d=e.consent===!1||n;if(!e.graph||!e.apiKey||d||typeof window=="undefined")return t;let p=E.get(e.apiKey);if(p)try{p()}catch(g){}let m=G(),o=(l=e.ingestUrl)!=null?l:ae,a=M({syncUrl:o.replace(/\/events\/?$/,"/graph/sync"),apiKey:e.apiKey,projectId:e.apiKey,sessionId:ie()});m.scan().then(g=>{for(let r of g.nodes)a.addPageNode({id:r.componentId,componentId:r.componentId,semanticType:r.semanticType,answers:e.captureDomText&&r.headingText?[r.headingText]:[],prominenceScore:r.prominenceScore,depth:r.depth});for(let r of g.edges)a.addStructuralEdge(r);a.syncOnce()});let i=null,c=()=>{i!==null&&clearTimeout(i),i=setTimeout(()=>{i=null,a.syncOnce()},500)};m.observe(g=>{for(let r of g.nodes)a.addPageNode({id:r.componentId,componentId:r.componentId,semanticType:r.semanticType,answers:e.captureDomText&&r.headingText?[r.headingText]:[],prominenceScore:r.prominenceScore,depth:r.depth});for(let r of g.edges)a.addStructuralEdge(r);c()});let u=()=>{i!==null&&(clearTimeout(i),i=null),m.destroy(),a.destroy(),E.get(e.apiKey)===u&&E.delete(e.apiKey)};return E.set(e.apiKey,u),I(y({},t),{getGraph:()=>a.snapshot(),dispose:()=>{u(),t.dispose()},destroy:()=>{u(),t.destroy()}})}export{j as deriveSessionSegment,$ as detectDeviceClass,L as detectTimeOfDay,k as detectTrafficSource,he as init,U as referrerDomainFromReferer,_ as sanitizePageUrl};
2
2
  //# sourceMappingURL=index-graph.mjs.map
@@ -1,5 +1,5 @@
1
- import { e as DecideOutcome } from './index-DCP2qgno.cjs';
2
- import { a as SlotDeclInput } from './session-meta-DU_3mY7U.cjs';
1
+ import { e as DecideOutcome } from './index-a8WMLbpe.cjs';
2
+ import { b as SlotDeclInput } from './session-meta-BVvq5RBB.cjs';
3
3
  import '@sentientui/policy';
4
4
 
5
5
  /**
@@ -1,5 +1,5 @@
1
- import { e as DecideOutcome } from './index-Br4jju2S.js';
2
- import { a as SlotDeclInput } from './session-meta-DU_3mY7U.js';
1
+ import { e as DecideOutcome } from './index-sGcvT3pc.js';
2
+ import { b as SlotDeclInput } from './session-meta-BVvq5RBB.js';
3
3
  import '@sentientui/policy';
4
4
 
5
5
  /**
@@ -1,4 +1,4 @@
1
- import { a as SlotDeclInput } from './session-meta-DU_3mY7U.js';
1
+ import { b as SlotDeclInput } from './session-meta-BVvq5RBB.js';
2
2
  import { SlotResult } from '@sentientui/policy';
3
3
 
4
4
  /** Manages anonymous session identity with cookie + localStorage layers. */
@@ -408,8 +408,9 @@ type SentientClient = {
408
408
  */
409
409
  declare function isDoNotTrackEnabled(): boolean;
410
410
  /**
411
- * Upgrades a pre-consent client (created with `consent: false, preConsentBehavior: 'statistical_winner'`)
412
- * to a fully-tracking client. Call this from your consent management platform callback.
411
+ * Upgrades a pre-consent client (any client created with `consent: false`, in
412
+ * either `preConsentBehavior` mode) to a fully-tracking client, in place and
413
+ * with no page reload. Call this from your consent management platform callback.
413
414
  * For React apps, prefer updating the `consent` prop on `<AdaptiveProvider>`.
414
415
  * Pass `apiKey` to target a specific project; omit to upgrade the most-recently-initialized client.
415
416
  */
@@ -1,5 +1,5 @@
1
- import { a as SlotDeclInput } from './session-meta-DU_3mY7U.cjs';
2
- export { S as SessionUpsertPayload, f as buildSessionUpsertPayload, g as deriveSessionSegment, h as detectDeviceClass, i as detectTimeOfDay, j as detectTrafficSource, r as referrerDomainFromReferer } from './session-meta-DU_3mY7U.cjs';
1
+ import { b as SlotDeclInput } from './session-meta-BVvq5RBB.cjs';
2
+ export { S as SessionUpsertPayload, h as buildSessionUpsertPayload, j as deriveSessionSegment, k as detectDeviceClass, l as detectTimeOfDay, m as detectTrafficSource, r as referrerDomainFromReferer } from './session-meta-BVvq5RBB.cjs';
3
3
  import { SlotResult } from '@sentientui/policy';
4
4
  export { SlotResult } from '@sentientui/policy';
5
5
 
@@ -1,5 +1,5 @@
1
- import { a as SlotDeclInput } from './session-meta-DU_3mY7U.js';
2
- export { S as SessionUpsertPayload, f as buildSessionUpsertPayload, g as deriveSessionSegment, h as detectDeviceClass, i as detectTimeOfDay, j as detectTrafficSource, r as referrerDomainFromReferer } from './session-meta-DU_3mY7U.js';
1
+ import { b as SlotDeclInput } from './session-meta-BVvq5RBB.js';
2
+ export { S as SessionUpsertPayload, h as buildSessionUpsertPayload, j as deriveSessionSegment, k as detectDeviceClass, l as detectTimeOfDay, m as detectTrafficSource, r as referrerDomainFromReferer } from './session-meta-BVvq5RBB.js';
3
3
  import { SlotResult } from '@sentientui/policy';
4
4
  export { SlotResult } from '@sentientui/policy';
5
5
 
@@ -1,2 +1,2 @@
1
- "use strict";var R=Object.defineProperty,z=Object.defineProperties,G=Object.getOwnPropertyDescriptor,K=Object.getOwnPropertyDescriptors,q=Object.getOwnPropertyNames,j=Object.getOwnPropertySymbols;var M=Object.prototype.hasOwnProperty,H=Object.prototype.propertyIsEnumerable;var B=(t,e,r)=>e in t?R(t,e,{enumerable:!0,configurable:!0,writable:!0,value:r}):t[e]=r,p=(t,e)=>{for(var r in e||(e={}))M.call(e,r)&&B(t,r,e[r]);if(j)for(var r of j(e))H.call(e,r)&&B(t,r,e[r]);return t},L=(t,e)=>z(t,K(e));var Q=(t,e)=>{for(var r in e)R(t,r,{get:e[r],enumerable:!0})},V=(t,e,r,s)=>{if(e&&typeof e=="object"||typeof e=="function")for(let o of q(e))!M.call(t,o)&&o!==r&&R(t,o,{get:()=>e[o],enumerable:!(s=G(e,o))||s.enumerable});return t};var X=t=>V(R({},"__esModule",{value:!0}),t);var te={};Q(te,{buildSessionUpsertPayload:()=>y,deriveSessionSegment:()=>_,detectDeviceClass:()=>A,detectTimeOfDay:()=>v,detectTrafficSource:()=>w,preloadAssignments:()=>F,preloadDecisions:()=>J,readSessionCookie:()=>W,referrerDomainFromReferer:()=>x});module.exports=X(te);var Y=["GPTBot","ChatGPT-User","OAI-SearchBot","ClaudeBot","Claude-User","Claude-SearchBot","PerplexityBot","Perplexity-User","Google-Extended","Applebot-Extended","Meta-ExternalAgent","Bytespider","CCBot","Amazonbot","cohere-ai","Diffbot"];function Z(t){return ee(t)!==null}function ee(t){var r;if(!t)return null;let e=t.toLowerCase();return(r=Y.find(s=>e.includes(s.toLowerCase())))!=null?r:null}function A(t){let e=t.toLowerCase();return/ipad|tablet|playbook|kindle|silk/.test(e)?"tablet":/mobi|iphone|ipod|android.*mobile|phone/.test(e)?"mobile":"desktop"}function w(t,e){if(!t)return"direct";try{let r=new URL(t);if(e)try{if(new URL(e).host===r.host)return"direct"}catch(o){}let s=r.hostname.toLowerCase();return/(^|\.)(google|bing|duckduckgo|yahoo)\./.test(s)?"search":/(^|\.)(twitter\.com|x\.com|facebook\.com|linkedin\.com|reddit\.com|t\.co)$/.test(s)?"social":"referral"}catch(r){return"direct"}}function x(t){if(!t)return null;try{return new URL(t).hostname}catch(e){return null}}function v(t){let e=t.getHours();return e<6?"night":e<12?"morning":e<18?"afternoon":"evening"}function _(t){let e=y("__segment__",t);return`${e.deviceClass}:${e.trafficSource}`}function y(t,e){var c,u,g,d,n,l,a;let r=(u=(c=e==null?void 0:e.userAgent)==null?void 0:c.trim())!=null?u:"",s=(d=(g=e==null?void 0:e.referer)==null?void 0:g.trim())!=null?d:"",o=(n=e==null?void 0:e.now)!=null?n:new Date;return{sessionId:t,ephemeral:!1,utmParams:(l=e==null?void 0:e.utmParams)!=null?l:{},deviceClass:r?A(r):"desktop",trafficSource:s?w(s,e==null?void 0:e.appOrigin):"direct",referrerDomain:x(s),timeOfDay:v(o),dayOfWeek:(a=["sun","mon","tue","wed","thu","fri","sat"][o.getDay()])!=null?a:"sun",automation:(e==null?void 0:e.webdriver)===!0||Z(r)}}var S=require("@sentientui/policy");function O(t){return p(p(p({id:t.id},t.arms?{arms:[...t.arms]}:{}),t.dims?{dims:Object.fromEntries(Object.entries(t.dims).map(([e,r])=>[e,[...r]]))}:{}),t.baseline!==void 0?{baseline:t.baseline}:{})}function U(t){let e=O(t);return(0,S.slotResultFor)(e,(0,S.slotBaselineArm)(e))}function N(t){let e={};for(let r of t)e[r.id]=U(r);return e}var E=1e3;function D(t,e,r){let s=new AbortController,o=setTimeout(()=>s.abort(),r);return fetch(t,L(p({},e),{signal:s.signal})).finally(()=>clearTimeout(o))}async function F(t,e,r){var d;if(r.doNotTrack)return{};let s=(d=r.timeoutMs)!=null?d:E,o={"Content-Type":"application/json",Authorization:`Bearer ${r.apiKey}`};r.origin&&(o.Origin=r.origin);let c=y(e,{userAgent:r.userAgent,referer:r.referer,utmParams:r.utmParams,appOrigin:r.origin});try{let n=await D(`${r.baseUrl}/sessions`,{method:"POST",headers:o,body:JSON.stringify(c)},s);if(n.status===402)console.warn("[SentientUI] Session limit exceeded for this project. The bandit will stop learning until the limit resets. Upgrade at sentient-ui.com/pricing");else if(!n.ok){let l=await n.json().catch(()=>({}));console.error(`[SentientUI] preloadAssignments: session upsert failed (${n.status})`,l)}}catch(n){console.error("[SentientUI] preloadAssignments: session upsert threw",n)}let u=await Promise.allSettled(t.map(async({id:n,variantIds:l})=>{let a=await D(`${r.baseUrl}/assign`,{method:"POST",headers:o,body:JSON.stringify({sessionId:e,componentId:n,variantIds:l})},s);if(!a.ok){let h=await a.json().catch(()=>({}));return console.error(`[SentientUI] preloadAssignments: assign failed for "${n}" (${a.status})`,h),null}let b=await a.json();return{id:n,variantId:b.variantId}})),g={};for(let n of u)n.status==="fulfilled"&&n.value&&(g[n.value.id]=n.value.variantId);return g}function W(t){var e,r;return(r=(e=t.get("_snt_uid"))==null?void 0:e.value)!=null?r:null}async function J(t,e,r){var d,n,l,a,b,h,P,k,I,T,C;let s=(d=r.timeoutMs)!=null?d:E,o=(n=t.slots)!=null?n:[],c={layoutOrder:(l=t.sections)!=null?l:[],assignments:{},slots:N(o),persona:"unknown",confidence:0};if(r.doNotTrack)return c;let u={"Content-Type":"application/json",Authorization:`Bearer ${r.apiKey}`};r.origin&&(u.Origin=r.origin);let g=y(e,{userAgent:r.userAgent,referer:r.referer,utmParams:r.utmParams,appOrigin:r.origin});try{let i=await D(`${r.baseUrl}/sessions`,{method:"POST",headers:u,body:JSON.stringify(g)},s);if(!i.ok){let m=await i.json().catch(()=>({}));console.error(`[SentientUI] preloadDecisions: session upsert failed (${i.status})`,m)}}catch(i){console.error("[SentientUI] preloadDecisions: session upsert threw",i)}try{let i=await D(`${r.baseUrl}/decide`,{method:"POST",headers:u,body:JSON.stringify(p({sessionId:e,sections:((a=t.sections)!=null?a:[]).map(f=>({id:f})),components:t.components},o.length>0?{slots:o.map(O)}:{}))},s);if(!i.ok){let f=await i.json().catch(()=>({}));return console.error(`[SentientUI] preloadDecisions: decide failed (${i.status})`,f),c}let m=await i.json(),$={};for(let f of o)$[f.id]=(h=(b=m.slots)==null?void 0:b[f.id])!=null?h:U(f);return{layoutOrder:(k=(P=m.layoutOrder)!=null?P:t.sections)!=null?k:[],assignments:(I=m.assignments)!=null?I:{},slots:$,persona:(T=m.persona)!=null?T:"unknown",confidence:(C=m.confidence)!=null?C:0}}catch(i){return console.error("[SentientUI] preloadDecisions: decide threw",i),c}}0&&(module.exports={buildSessionUpsertPayload,deriveSessionSegment,detectDeviceClass,detectTimeOfDay,detectTrafficSource,preloadAssignments,preloadDecisions,readSessionCookie,referrerDomainFromReferer});
1
+ "use strict";var R=Object.defineProperty,z=Object.defineProperties,J=Object.getOwnPropertyDescriptor,K=Object.getOwnPropertyDescriptors,q=Object.getOwnPropertyNames,$=Object.getOwnPropertySymbols;var E=Object.prototype.hasOwnProperty,H=Object.prototype.propertyIsEnumerable;var j=(t,e,r)=>e in t?R(t,e,{enumerable:!0,configurable:!0,writable:!0,value:r}):t[e]=r,p=(t,e)=>{for(var r in e||(e={}))E.call(e,r)&&j(t,r,e[r]);if($)for(var r of $(e))H.call(e,r)&&j(t,r,e[r]);return t},L=(t,e)=>z(t,K(e));var Q=(t,e)=>{for(var r in e)R(t,r,{get:e[r],enumerable:!0})},V=(t,e,r,s)=>{if(e&&typeof e=="object"||typeof e=="function")for(let o of q(e))!E.call(t,o)&&o!==r&&R(t,o,{get:()=>e[o],enumerable:!(s=J(e,o))||s.enumerable});return t};var X=t=>V(R({},"__esModule",{value:!0}),t);var te={};Q(te,{buildSessionUpsertPayload:()=>y,deriveSessionSegment:()=>M,detectDeviceClass:()=>x,detectTimeOfDay:()=>I,detectTrafficSource:()=>D,preloadAssignments:()=>G,preloadDecisions:()=>W,readSessionCookie:()=>F,referrerDomainFromReferer:()=>w});module.exports=X(te);var Y=["GPTBot","ChatGPT-User","OAI-SearchBot","ClaudeBot","Claude-User","Claude-SearchBot","PerplexityBot","Perplexity-User","Google-Extended","Applebot-Extended","Meta-ExternalAgent","Bytespider","CCBot","Amazonbot","cohere-ai","Diffbot"];function Z(t){return ee(t)!==null}function ee(t){var r;if(!t)return null;let e=t.toLowerCase();return(r=Y.find(s=>e.includes(s.toLowerCase())))!=null?r:null}function x(t){let e=t.toLowerCase();return/ipad|tablet|playbook|kindle|silk/.test(e)?"tablet":/mobi|iphone|ipod|android.*mobile|phone/.test(e)?"mobile":"desktop"}function D(t,e){if(!t)return"direct";try{let r=new URL(t);if(e)try{if(new URL(e).host===r.host)return"direct"}catch(o){}let s=r.hostname.toLowerCase();return/(^|\.)(google|bing|duckduckgo|yahoo)\./.test(s)?"search":/(^|\.)(twitter\.com|x\.com|facebook\.com|linkedin\.com|reddit\.com|t\.co)$/.test(s)?"social":"referral"}catch(r){return"direct"}}function w(t){if(!t)return null;try{return new URL(t).hostname}catch(e){return null}}function I(t){let e=t.getHours();return e<6?"night":e<12?"morning":e<18?"afternoon":"evening"}function M(t){let e=y("__segment__",t);return`${e.deviceClass}:${e.trafficSource}`}function y(t,e){var c,u,g,d,n,l,a;let r=(u=(c=e==null?void 0:e.userAgent)==null?void 0:c.trim())!=null?u:"",s=(d=(g=e==null?void 0:e.referer)==null?void 0:g.trim())!=null?d:"",o=(n=e==null?void 0:e.now)!=null?n:new Date;return{sessionId:t,ephemeral:!1,utmParams:(l=e==null?void 0:e.utmParams)!=null?l:{},deviceClass:r?x(r):"desktop",trafficSource:s?D(s,e==null?void 0:e.appOrigin):"direct",referrerDomain:w(s),timeOfDay:I(o),dayOfWeek:(a=["sun","mon","tue","wed","thu","fri","sat"][o.getDay()])!=null?a:"sun",automation:(e==null?void 0:e.webdriver)===!0||Z(r)}}var S=require("@sentientui/policy");function U(t){return p(p(p({id:t.id},t.arms?{arms:[...t.arms]}:{}),t.dims?{dims:Object.fromEntries(Object.entries(t.dims).map(([e,r])=>[e,[...r]]))}:{}),t.baseline!==void 0?{baseline:t.baseline}:{})}function C(t){let e=U(t);return(0,S.slotResultFor)(e,(0,S.slotBaselineArm)(e))}function N(t){let e={};for(let r of t)e[r.id]=C(r);return e}var _=1e3;function A(t,e,r){let s=new AbortController,o=setTimeout(()=>s.abort(),r);return fetch(t,L(p({},e),{signal:s.signal})).finally(()=>clearTimeout(o))}async function G(t,e,r){var d;if(r.doNotTrack)return{};let s=(d=r.timeoutMs)!=null?d:_,o={"Content-Type":"application/json",Authorization:`Bearer ${r.apiKey}`};r.origin&&(o.Origin=r.origin);let c=y(e,{userAgent:r.userAgent,referer:r.referer,utmParams:r.utmParams,appOrigin:r.origin});try{let n=await A(`${r.baseUrl}/sessions`,{method:"POST",headers:o,body:JSON.stringify(c)},s);if(n.status===402)console.warn("[SentientUI] Session limit exceeded for this project. The bandit will stop learning until the limit resets. Upgrade at sentient-ui.com/pricing");else if(!n.ok){let l=await n.json().catch(()=>({}));console.error(`[SentientUI] preloadAssignments: session upsert failed (${n.status})`,l)}}catch(n){console.error("[SentientUI] preloadAssignments: session upsert threw",n)}let u=await Promise.allSettled(t.map(async({id:n,variantIds:l})=>{let a=await A(`${r.baseUrl}/assign`,{method:"POST",headers:o,body:JSON.stringify({sessionId:e,componentId:n,variantIds:l})},s);if(!a.ok){let b=await a.json().catch(()=>({}));return console.error(`[SentientUI] preloadAssignments: assign failed for "${n}" (${a.status})`,b),null}let h=await a.json();return{id:n,variantId:h.variantId}})),g={};for(let n of u)n.status==="fulfilled"&&n.value&&(g[n.value.id]=n.value.variantId);return g}function F(t){var e,r;return(r=(e=t.get("_snt_uid"))==null?void 0:e.value)!=null?r:null}async function W(t,e,r){var d,n,l,a,h,b,O,P,v,T,k;let s=(d=r.timeoutMs)!=null?d:_,o=(n=t.slots)!=null?n:[],c={layoutOrder:(l=t.sections)!=null?l:[],assignments:{},slots:N(o),persona:"unknown",confidence:0};if(r.doNotTrack)return c;let u={"Content-Type":"application/json",Authorization:`Bearer ${r.apiKey}`};r.origin&&(u.Origin=r.origin);let g=y(e,{userAgent:r.userAgent,referer:r.referer,utmParams:r.utmParams,appOrigin:r.origin});try{let i=await A(`${r.baseUrl}/sessions`,{method:"POST",headers:u,body:JSON.stringify(g)},s);if(!i.ok){let m=await i.json().catch(()=>({}));console.error(`[SentientUI] preloadDecisions: session upsert failed (${i.status})`,m)}}catch(i){console.error("[SentientUI] preloadDecisions: session upsert threw",i)}try{let i=await A(`${r.baseUrl}/decide`,{method:"POST",headers:u,body:JSON.stringify(p({sessionId:e,sections:((a=t.sections)!=null?a:[]).map(f=>({id:f})),components:t.components},o.length>0?{slots:o.map(U)}:{}))},s);if(!i.ok){let f=await i.json().catch(()=>({}));return console.error(`[SentientUI] preloadDecisions: decide failed (${i.status})`,f),c}let m=await i.json(),B={};for(let f of o)B[f.id]=(b=(h=m.slots)==null?void 0:h[f.id])!=null?b:C(f);return{layoutOrder:(P=(O=m.layoutOrder)!=null?O:t.sections)!=null?P:[],assignments:(v=m.assignments)!=null?v:{},slots:B,persona:(T=m.persona)!=null?T:"unknown",confidence:(k=m.confidence)!=null?k:0}}catch(i){return console.error("[SentientUI] preloadDecisions: decide threw",i),c}}0&&(module.exports={buildSessionUpsertPayload,deriveSessionSegment,detectDeviceClass,detectTimeOfDay,detectTrafficSource,preloadAssignments,preloadDecisions,readSessionCookie,referrerDomainFromReferer});
2
2
  //# sourceMappingURL=index-server.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index-server.ts","../src/session-meta.ts","../src/slots.ts","../src/server.ts"],"sourcesContent":["/**\n * Server-only entry (`@sentientui/core/server`). SSR preload helpers that are\n * never needed in the browser — kept out of the lean client bundle.\n */\n\nexport { preloadAssignments, readSessionCookie, preloadDecisions } from './server.js';\nexport type { ServerAssignConfig, ServerAssignments, DecideResult, SlotDeclInput, SlotResult } from './server.js';\n\nexport {\n deriveSessionSegment,\n buildSessionUpsertPayload,\n detectDeviceClass,\n detectTrafficSource,\n detectTimeOfDay,\n referrerDomainFromReferer,\n} from './session-meta.js';\nexport type { SessionUpsertPayload } from './session-meta.js';\n","/** Session metadata helpers (browser + Node). No DOM APIs. */\n\n/**\n * Known AI-agent / crawler user-agent tokens. Matched case-insensitively as\n * substrings. This is maintained data — bot lists move monthly. Used both to\n * flag automation on sessions (agentic browsers that leak a token) and by the\n * server middleware / agent-feed route to identify crawler HTTP reads.\n */\nexport const agentUaList: readonly string[] = [\n 'GPTBot',\n 'ChatGPT-User',\n 'OAI-SearchBot',\n 'ClaudeBot',\n 'Claude-User',\n 'Claude-SearchBot',\n 'PerplexityBot',\n 'Perplexity-User',\n 'Google-Extended',\n 'Applebot-Extended',\n 'Meta-ExternalAgent',\n 'Bytespider',\n 'CCBot',\n 'Amazonbot',\n 'cohere-ai',\n 'Diffbot',\n];\n\n/** True when the user-agent contains a known AI-agent / crawler token. */\nexport function uaTokenMatch(userAgent: string): boolean {\n return matchedAgentToken(userAgent) !== null;\n}\n\n/** The first known agent token found in the user-agent, or null. */\nexport function matchedAgentToken(userAgent: string): string | null {\n if (!userAgent) return null;\n const s = userAgent.toLowerCase();\n return agentUaList.find((token) => s.includes(token.toLowerCase())) ?? null;\n}\n\nexport function detectDeviceClass(userAgent: string): string {\n const s = userAgent.toLowerCase();\n if (/ipad|tablet|playbook|kindle|silk/.test(s)) return 'tablet';\n if (/mobi|iphone|ipod|android.*mobile|phone/.test(s)) return 'mobile';\n return 'desktop';\n}\n\nexport function detectTrafficSource(referrer: string, appOrigin?: string): string {\n if (!referrer) return 'direct';\n try {\n const refUrl = new URL(referrer);\n if (appOrigin) {\n try {\n if (new URL(appOrigin).host === refUrl.host) return 'direct';\n } catch {\n /* ignore invalid appOrigin */\n }\n }\n const host = refUrl.hostname.toLowerCase();\n if (/(^|\\.)(google|bing|duckduckgo|yahoo)\\./.test(host)) return 'search';\n // Anchor to the registrable domain (exact host or a subdomain of it) so\n // hosts like `x.company.com`, `t.company.io` or `linkedinsights.com` are not\n // misclassified as social by an unbounded substring match.\n if (/(^|\\.)(twitter\\.com|x\\.com|facebook\\.com|linkedin\\.com|reddit\\.com|t\\.co)$/.test(host)) return 'social';\n return 'referral';\n } catch {\n return 'direct';\n }\n}\n\nexport function referrerDomainFromReferer(referrer: string): string | null {\n if (!referrer) return null;\n try {\n return new URL(referrer).hostname;\n } catch {\n return null;\n }\n}\n\nexport function detectTimeOfDay(d: Date): string {\n const h = d.getHours();\n if (h < 6) return 'night';\n if (h < 12) return 'morning';\n if (h < 18) return 'afternoon';\n return 'evening';\n}\n\nexport type SessionUpsertPayload = {\n sessionId: string;\n ephemeral: boolean;\n utmParams: Record<string, string>;\n deviceClass: string;\n trafficSource: string;\n referrerDomain: string | null;\n timeOfDay: string;\n dayOfWeek: string;\n /**\n * True when this session is likely driven by automation — either\n * `navigator.webdriver` was set, or the user-agent carried a known agent\n * token. Probabilistic: a flag for metrics + bandit exclusion, never a gate.\n */\n automation: boolean;\n};\n\n/** Bandit segment key: `<device_class>:<traffic_source>`. */\nexport function deriveSessionSegment(opts?: {\n userAgent?: string;\n referer?: string;\n appOrigin?: string;\n}): string {\n const body = buildSessionUpsertPayload('__segment__', opts);\n return `${body.deviceClass}:${body.trafficSource}`;\n}\n\n/**\n * Builds a session upsert body aligned with the browser SDK so SSR assign uses\n * the same segment key (`device:source`) as the client after hydration.\n */\nexport function buildSessionUpsertPayload(\n sessionId: string,\n opts?: {\n userAgent?: string;\n referer?: string;\n appOrigin?: string;\n utmParams?: Record<string, string>;\n now?: Date;\n /** `navigator.webdriver` value from the browser, when available. */\n webdriver?: boolean;\n },\n): SessionUpsertPayload {\n const ua = opts?.userAgent?.trim() ?? '';\n const referer = opts?.referer?.trim() ?? '';\n const now = opts?.now ?? new Date();\n return {\n sessionId,\n ephemeral: false,\n utmParams: opts?.utmParams ?? {},\n deviceClass: ua ? detectDeviceClass(ua) : 'desktop',\n trafficSource: referer\n ? detectTrafficSource(referer, opts?.appOrigin)\n : 'direct',\n referrerDomain: referrerDomainFromReferer(referer),\n timeOfDay: detectTimeOfDay(now),\n dayOfWeek: ['sun', 'mon', 'tue', 'wed', 'thu', 'fri', 'sat'][now.getDay()] ?? 'sun',\n automation: opts?.webdriver === true || uaTokenMatch(ua),\n };\n}\n","/**\n * Slot declaration helpers shared by the browser client (decide) and the\n * server preload path. Pure wrappers over @sentientui/policy.\n */\nimport {\n canonicalArm,\n slotBaselineArm,\n slotResultFor,\n type SlotDecl,\n type SlotResult,\n} from '@sentientui/policy';\n\n/** SDK-facing slot declaration. `dims` accepts readonly arrays (`as const`). */\nexport type SlotDeclInput = {\n id: string;\n arms?: string[];\n dims?: Record<string, readonly string[]>;\n baseline?: string | Record<string, string>;\n};\n\nexport type { SlotResult };\n\n/**\n * Whitelists the wire fields of a slot declaration. Anything an SDK layer\n * attached (goal configs, refs, …) is stripped so it never reaches the zod\n * schema on the API. Also normalizes readonly arrays to mutable ones.\n */\nexport function toWireSlot(d: SlotDeclInput): SlotDecl {\n return {\n id: d.id,\n ...(d.arms ? { arms: [...d.arms] } : {}),\n ...(d.dims\n ? {\n dims: Object.fromEntries(\n Object.entries(d.dims).map(([dim, values]) => [dim, [...values]]),\n ),\n }\n : {}),\n ...(d.baseline !== undefined ? { baseline: d.baseline } : {}),\n };\n}\n\n/** The declared (or default first-declared) baseline result for a slot. */\nexport function baselineResultFor(d: SlotDeclInput): SlotResult {\n const decl = toWireSlot(d);\n return slotResultFor(decl, slotBaselineArm(decl));\n}\n\n/** Baseline results for a whole declaration list, keyed by slot id. */\nexport function baselineSlots(decls: SlotDeclInput[]): Record<string, SlotResult> {\n const out: Record<string, SlotResult> = {};\n for (const d of decls) out[d.id] = baselineResultFor(d);\n return out;\n}\n\n/**\n * Canonical arm string of a slot result: dims results encode as sorted\n * `dim=value` pairs joined with '|'; arms results are the arm id verbatim.\n */\nexport function armOfResult(result: SlotResult): string {\n return typeof result === 'string' ? result : canonicalArm(result);\n}\n","/**\n * Server-side helpers for SSR variant pre-loading.\n * Pure fetch — no DOM APIs. Safe in Node.js, Edge, and Deno runtimes.\n */\nimport { buildSessionUpsertPayload } from './session-meta.js';\nimport {\n toWireSlot,\n baselineResultFor,\n baselineSlots,\n type SlotDeclInput,\n type SlotResult,\n} from './slots.js';\n\nexport type { SlotDeclInput, SlotResult };\n\nexport type ServerAssignConfig = {\n /** Public API key (pk_...). */\n apiKey: string;\n /**\n * Base URL of the Sentient API without trailing slash.\n * e.g. 'https://api.yourapp.com/v1'\n */\n baseUrl: string;\n /**\n * Browser origin of your app (e.g. `http://localhost:3001`). Required for `pk_`\n * keys — server-side fetch must send the same `Origin` the API allows.\n */\n origin?: string;\n /** From `User-Agent` request header (Next.js `headers()`). */\n userAgent?: string;\n /** From `Referer` request header. */\n referer?: string;\n utmParams?: Record<string, string>;\n /**\n * Set true when the request carries a tracking opt-out — `DNT: 1` or\n * `Sec-GPC: 1`. When set, the SSR helpers skip the session upsert and the\n * assign/decide call entirely: the page renders defaults/baseline and no\n * session row is minted for the visitor (audit P4). The client SDK already\n * no-ops for these visitors; this keeps the server from minting a session +\n * assignment on every page view before the client can.\n */\n doNotTrack?: boolean;\n /**\n * Milliseconds to wait for the API before returning default variants.\n * Prevents slow/cold API from blocking SSR. Defaults to 1000 — the hot path\n * is served from in-process caches and typically returns in well under\n * 150 ms. The full 1 s budget is only reached on a cold start or an API\n * geographically distant from your SSR host, after which defaults render\n * with no layout shift. Lower it if your API is co-located and warm.\n */\n timeoutMs?: number;\n};\n\n/** componentId → assigned variantId */\nexport type ServerAssignments = Record<string, string>;\n\ntype AssignResult = { variantId: string; assignmentTtlMs: number };\n\nconst DEFAULT_TIMEOUT_MS = 1000;\n\nfunction fetchWithTimeout(\n url: string,\n init: RequestInit,\n timeoutMs: number,\n): Promise<Response> {\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), timeoutMs);\n return fetch(url, { ...init, signal: controller.signal }).finally(() =>\n clearTimeout(timer),\n );\n}\n\n/**\n * Fetches variant assignments server-side for all listed components.\n * Returns a map suitable for passing as `initialAssignments` to `<AdaptiveProvider>`.\n *\n * Call from Next.js layout, Server Component, or getServerSideProps.\n *\n * @example\n * ```tsx\n * const assignments = await preloadAssignments(\n * [\n * { id: 'hero', variantIds: ['hero-a', 'hero-b'] },\n * { id: 'cta', variantIds: ['cta-short', 'cta-long'] },\n * ],\n * sessionId, // read from cookies() or req.cookies\n * { apiKey: process.env.NEXT_PUBLIC_SENTIENT_API_KEY!, baseUrl: 'https://api.sentient-ui.com/v1' },\n * );\n * return <AdaptiveProvider ... initialAssignments={assignments}>{children}</AdaptiveProvider>;\n * ```\n */\nexport async function preloadAssignments(\n components: Array<{ id: string; variantIds: string[] }>,\n sessionId: string,\n config: ServerAssignConfig,\n): Promise<ServerAssignments> {\n // Opted-out visitor (DNT/GPC): render defaults, mint no session (audit P4).\n if (config.doNotTrack) return {};\n\n const timeoutMs = config.timeoutMs ?? DEFAULT_TIMEOUT_MS;\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n Authorization: `Bearer ${config.apiKey}`,\n };\n if (config.origin) {\n headers.Origin = config.origin;\n }\n\n // Session metadata must match the browser SDK so assign seeds variant_weights\n // under the same segment (not `unknown:unknown`).\n const sessionBody = buildSessionUpsertPayload(sessionId, {\n userAgent: config.userAgent,\n referer: config.referer,\n utmParams: config.utmParams,\n appOrigin: config.origin,\n });\n\n try {\n const res = await fetchWithTimeout(\n `${config.baseUrl}/sessions`,\n { method: 'POST', headers, body: JSON.stringify(sessionBody) },\n timeoutMs,\n );\n if (res.status === 402) {\n console.warn(\n '[SentientUI] Session limit exceeded for this project. The bandit will stop learning until the limit resets. Upgrade at sentient-ui.com/pricing',\n );\n } else if (!res.ok) {\n const body = await res.json().catch(() => ({}));\n console.error(`[SentientUI] preloadAssignments: session upsert failed (${res.status})`, body);\n }\n } catch (err) {\n console.error('[SentientUI] preloadAssignments: session upsert threw', err);\n }\n\n const results = await Promise.allSettled(\n components.map(async ({ id, variantIds }) => {\n const res = await fetchWithTimeout(\n `${config.baseUrl}/assign`,\n { method: 'POST', headers, body: JSON.stringify({ sessionId, componentId: id, variantIds }) },\n timeoutMs,\n );\n if (!res.ok) {\n const body = await res.json().catch(() => ({}));\n console.error(`[SentientUI] preloadAssignments: assign failed for \"${id}\" (${res.status})`, body);\n return null;\n }\n const body = (await res.json()) as AssignResult;\n return { id, variantId: body.variantId };\n }),\n );\n\n const assignments: ServerAssignments = {};\n for (const result of results) {\n if (result.status === 'fulfilled' && result.value) {\n assignments[result.value.id] = result.value.variantId;\n }\n }\n return assignments;\n}\n\n/**\n * Reads the Sentient session cookie from a Next.js `ReadonlyRequestCookies` object\n * (the return value of `cookies()` from `next/headers`), or any object with a\n * `get(name: string)` method. Returns null if the cookie is absent.\n */\nexport function readSessionCookie(\n cookies: { get(name: string): { value: string } | undefined },\n): string | null {\n return cookies.get('_snt_uid')?.value ?? null;\n}\n\nexport type DecideResult = {\n layoutOrder: string[];\n assignments: Record<string, string>;\n /** Slot results keyed by slot id. Baseline-resolved when the API omits/fails them. */\n slots: Record<string, SlotResult>;\n persona: string;\n confidence: number;\n};\n\n/**\n * Single-roundtrip SSR call returning layout order, component assignments,\n * and adaptive-slot results. Falls back to default section order + empty\n * assignments + baseline slots if the API is unavailable. A response without\n * a `slots` field means the server predates slots — every declared slot\n * resolves to its baseline (no retry).\n */\nexport async function preloadDecisions(\n params: {\n sections?: string[];\n components: Array<{ id: string; variantIds?: string[] }>;\n slots?: SlotDeclInput[];\n },\n sessionId: string,\n config: ServerAssignConfig,\n): Promise<DecideResult> {\n const timeoutMs = config.timeoutMs ?? DEFAULT_TIMEOUT_MS;\n const declaredSlots = params.slots ?? [];\n const fallback: DecideResult = {\n layoutOrder: params.sections ?? [],\n assignments: {},\n slots: baselineSlots(declaredSlots),\n persona: 'unknown',\n confidence: 0,\n };\n\n // Opted-out visitor (DNT/GPC): baseline layout/slots, mint no session (audit P4).\n if (config.doNotTrack) return fallback;\n\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n Authorization: `Bearer ${config.apiKey}`,\n };\n if (config.origin) headers.Origin = config.origin;\n\n const sessionBody = buildSessionUpsertPayload(sessionId, {\n userAgent: config.userAgent,\n referer: config.referer,\n utmParams: config.utmParams,\n appOrigin: config.origin,\n });\n\n try {\n const sessionRes = await fetchWithTimeout(\n `${config.baseUrl}/sessions`,\n { method: 'POST', headers, body: JSON.stringify(sessionBody) },\n timeoutMs,\n );\n if (!sessionRes.ok) {\n const body = await sessionRes.json().catch(() => ({}));\n console.error(`[SentientUI] preloadDecisions: session upsert failed (${sessionRes.status})`, body);\n }\n } catch (err) {\n console.error('[SentientUI] preloadDecisions: session upsert threw', err);\n }\n\n try {\n const res = await fetchWithTimeout(\n `${config.baseUrl}/decide`,\n {\n method: 'POST',\n headers,\n body: JSON.stringify({\n sessionId,\n sections: (params.sections ?? []).map((id) => ({ id })),\n components: params.components,\n ...(declaredSlots.length > 0 ? { slots: declaredSlots.map(toWireSlot) } : {}),\n }),\n },\n timeoutMs,\n );\n if (!res.ok) {\n const body = await res.json().catch(() => ({}));\n console.error(`[SentientUI] preloadDecisions: decide failed (${res.status})`, body);\n return fallback;\n }\n const data = (await res.json()) as {\n layoutOrder?: string[];\n assignments?: Record<string, string>;\n slots?: Record<string, SlotResult>;\n persona?: string;\n confidence?: number;\n };\n\n const slots: Record<string, SlotResult> = {};\n for (const d of declaredSlots) {\n // `data.slots === undefined` ⇒ server predates slots: baseline, no retry.\n slots[d.id] = data.slots?.[d.id] ?? baselineResultFor(d);\n }\n\n return {\n layoutOrder: data.layoutOrder ?? params.sections ?? [],\n assignments: data.assignments ?? {},\n slots,\n persona: data.persona ?? 'unknown',\n confidence: data.confidence ?? 0,\n };\n } catch (err) {\n console.error('[SentientUI] preloadDecisions: decide threw', err);\n return fallback;\n }\n}\n"],"mappings":"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","names":["index_server_exports","__export","buildSessionUpsertPayload","deriveSessionSegment","detectDeviceClass","detectTimeOfDay","detectTrafficSource","preloadAssignments","preloadDecisions","readSessionCookie","referrerDomainFromReferer","__toCommonJS","agentUaList","uaTokenMatch","userAgent","matchedAgentToken","_a","s","token","detectDeviceClass","detectTrafficSource","referrer","appOrigin","refUrl","e","host","referrerDomainFromReferer","detectTimeOfDay","d","h","deriveSessionSegment","opts","body","buildSessionUpsertPayload","sessionId","_b","_c","_d","_e","_f","_g","ua","referer","now","import_policy","toWireSlot","d","__spreadValues","dim","values","baselineResultFor","decl","baselineSlots","decls","out","DEFAULT_TIMEOUT_MS","fetchWithTimeout","url","init","timeoutMs","controller","timer","__spreadProps","__spreadValues","preloadAssignments","components","sessionId","config","_a","headers","sessionBody","buildSessionUpsertPayload","res","body","err","results","id","variantIds","assignments","result","readSessionCookie","cookies","_b","preloadDecisions","params","_c","_d","_e","_f","_g","_h","_i","_j","_k","declaredSlots","fallback","baselineSlots","sessionRes","toWireSlot","data","slots","d","baselineResultFor"]}
1
+ {"version":3,"sources":["../src/index-server.ts","../src/session-meta.ts","../src/slots.ts","../src/server.ts"],"sourcesContent":["/**\n * Server-only entry (`@sentientui/core/server`). SSR preload helpers that are\n * never needed in the browser — kept out of the lean client bundle.\n */\n\nexport { preloadAssignments, readSessionCookie, preloadDecisions } from './server.js';\nexport type { ServerAssignConfig, ServerAssignments, DecideResult, SlotDeclInput, SlotResult } from './server.js';\n\nexport {\n deriveSessionSegment,\n buildSessionUpsertPayload,\n detectDeviceClass,\n detectTrafficSource,\n detectTimeOfDay,\n referrerDomainFromReferer,\n} from './session-meta.js';\nexport type { SessionUpsertPayload } from './session-meta.js';\n","/** Session metadata helpers (browser + Node). No DOM APIs. */\n\n/**\n * Known AI-agent / crawler user-agent tokens. Matched case-insensitively as\n * substrings. This is maintained data — bot lists move monthly. Used both to\n * flag automation on sessions (agentic browsers that leak a token) and by the\n * server middleware / agent-feed route to identify crawler HTTP reads.\n */\nexport const agentUaList: readonly string[] = [\n 'GPTBot',\n 'ChatGPT-User',\n 'OAI-SearchBot',\n 'ClaudeBot',\n 'Claude-User',\n 'Claude-SearchBot',\n 'PerplexityBot',\n 'Perplexity-User',\n 'Google-Extended',\n 'Applebot-Extended',\n 'Meta-ExternalAgent',\n 'Bytespider',\n 'CCBot',\n 'Amazonbot',\n 'cohere-ai',\n 'Diffbot',\n];\n\n/** True when the user-agent contains a known AI-agent / crawler token. */\nexport function uaTokenMatch(userAgent: string): boolean {\n return matchedAgentToken(userAgent) !== null;\n}\n\n/** The first known agent token found in the user-agent, or null. */\nexport function matchedAgentToken(userAgent: string): string | null {\n if (!userAgent) return null;\n const s = userAgent.toLowerCase();\n return agentUaList.find((token) => s.includes(token.toLowerCase())) ?? null;\n}\n\n/**\n * Purpose category for an agent fetch, inferred from its published user-agent:\n * - `user` — a person asked an assistant to read the page, live (…-User UAs)\n * - `search` — indexing for an AI answer engine (…-SearchBot / SearchBot)\n * - `training` — model-training crawl (GPTBot, ClaudeBot, CCBot, …)\n * - `other` — not clearly AI, or an unknown/new token\n */\nexport type AgentIntent = 'user' | 'search' | 'training' | 'other';\n\n/** Intent per agent token. Maintained beside `agentUaList` — when you add or\n * rename a token above, set its intent here (a unit test enforces coverage). */\nexport const AGENT_INTENTS: Record<string, AgentIntent> = {\n 'GPTBot': 'training',\n 'ChatGPT-User': 'user',\n 'OAI-SearchBot': 'search',\n 'ClaudeBot': 'training',\n 'Claude-User': 'user',\n 'Claude-SearchBot': 'search',\n 'PerplexityBot': 'search',\n 'Perplexity-User': 'user',\n 'Google-Extended': 'training',\n 'Applebot-Extended': 'training',\n 'Meta-ExternalAgent': 'training',\n 'Bytespider': 'training',\n 'CCBot': 'training',\n 'Amazonbot': 'other',\n 'cohere-ai': 'training',\n 'Diffbot': 'other',\n};\n\n/** Intent for a matched bot token (case-insensitive); `other` for null/unknown. */\nexport function agentIntent(botName: string | null): AgentIntent {\n if (!botName) return 'other';\n const hit = agentUaList.find((t) => t.toLowerCase() === botName.toLowerCase());\n return (hit && AGENT_INTENTS[hit]) || 'other';\n}\n\n/** `agentUaList` grouped by intent — the \"which crawlers do you classify?\" reference. */\nexport function classifiedAgents(): Record<AgentIntent, string[]> {\n const out: Record<AgentIntent, string[]> = { user: [], search: [], training: [], other: [] };\n for (const t of agentUaList) out[AGENT_INTENTS[t] ?? 'other'].push(t);\n return out;\n}\n\nexport function detectDeviceClass(userAgent: string): string {\n const s = userAgent.toLowerCase();\n if (/ipad|tablet|playbook|kindle|silk/.test(s)) return 'tablet';\n if (/mobi|iphone|ipod|android.*mobile|phone/.test(s)) return 'mobile';\n return 'desktop';\n}\n\nexport function detectTrafficSource(referrer: string, appOrigin?: string): string {\n if (!referrer) return 'direct';\n try {\n const refUrl = new URL(referrer);\n if (appOrigin) {\n try {\n if (new URL(appOrigin).host === refUrl.host) return 'direct';\n } catch {\n /* ignore invalid appOrigin */\n }\n }\n const host = refUrl.hostname.toLowerCase();\n if (/(^|\\.)(google|bing|duckduckgo|yahoo)\\./.test(host)) return 'search';\n // Anchor to the registrable domain (exact host or a subdomain of it) so\n // hosts like `x.company.com`, `t.company.io` or `linkedinsights.com` are not\n // misclassified as social by an unbounded substring match.\n if (/(^|\\.)(twitter\\.com|x\\.com|facebook\\.com|linkedin\\.com|reddit\\.com|t\\.co)$/.test(host)) return 'social';\n return 'referral';\n } catch {\n return 'direct';\n }\n}\n\nexport function referrerDomainFromReferer(referrer: string): string | null {\n if (!referrer) return null;\n try {\n return new URL(referrer).hostname;\n } catch {\n return null;\n }\n}\n\nexport function detectTimeOfDay(d: Date): string {\n const h = d.getHours();\n if (h < 6) return 'night';\n if (h < 12) return 'morning';\n if (h < 18) return 'afternoon';\n return 'evening';\n}\n\nexport type SessionUpsertPayload = {\n sessionId: string;\n ephemeral: boolean;\n utmParams: Record<string, string>;\n deviceClass: string;\n trafficSource: string;\n referrerDomain: string | null;\n timeOfDay: string;\n dayOfWeek: string;\n /**\n * True when this session is likely driven by automation — either\n * `navigator.webdriver` was set, or the user-agent carried a known agent\n * token. Probabilistic: a flag for metrics + bandit exclusion, never a gate.\n */\n automation: boolean;\n};\n\n/** Bandit segment key: `<device_class>:<traffic_source>`. */\nexport function deriveSessionSegment(opts?: {\n userAgent?: string;\n referer?: string;\n appOrigin?: string;\n}): string {\n const body = buildSessionUpsertPayload('__segment__', opts);\n return `${body.deviceClass}:${body.trafficSource}`;\n}\n\n/**\n * Builds a session upsert body aligned with the browser SDK so SSR assign uses\n * the same segment key (`device:source`) as the client after hydration.\n */\nexport function buildSessionUpsertPayload(\n sessionId: string,\n opts?: {\n userAgent?: string;\n referer?: string;\n appOrigin?: string;\n utmParams?: Record<string, string>;\n now?: Date;\n /** `navigator.webdriver` value from the browser, when available. */\n webdriver?: boolean;\n },\n): SessionUpsertPayload {\n const ua = opts?.userAgent?.trim() ?? '';\n const referer = opts?.referer?.trim() ?? '';\n const now = opts?.now ?? new Date();\n return {\n sessionId,\n ephemeral: false,\n utmParams: opts?.utmParams ?? {},\n deviceClass: ua ? detectDeviceClass(ua) : 'desktop',\n trafficSource: referer\n ? detectTrafficSource(referer, opts?.appOrigin)\n : 'direct',\n referrerDomain: referrerDomainFromReferer(referer),\n timeOfDay: detectTimeOfDay(now),\n dayOfWeek: ['sun', 'mon', 'tue', 'wed', 'thu', 'fri', 'sat'][now.getDay()] ?? 'sun',\n automation: opts?.webdriver === true || uaTokenMatch(ua),\n };\n}\n","/**\n * Slot declaration helpers shared by the browser client (decide) and the\n * server preload path. Pure wrappers over @sentientui/policy.\n */\nimport {\n canonicalArm,\n slotBaselineArm,\n slotResultFor,\n type SlotDecl,\n type SlotResult,\n} from '@sentientui/policy';\n\n/** SDK-facing slot declaration. `dims` accepts readonly arrays (`as const`). */\nexport type SlotDeclInput = {\n id: string;\n arms?: string[];\n dims?: Record<string, readonly string[]>;\n baseline?: string | Record<string, string>;\n};\n\nexport type { SlotResult };\n\n/**\n * Whitelists the wire fields of a slot declaration. Anything an SDK layer\n * attached (goal configs, refs, …) is stripped so it never reaches the zod\n * schema on the API. Also normalizes readonly arrays to mutable ones.\n */\nexport function toWireSlot(d: SlotDeclInput): SlotDecl {\n return {\n id: d.id,\n ...(d.arms ? { arms: [...d.arms] } : {}),\n ...(d.dims\n ? {\n dims: Object.fromEntries(\n Object.entries(d.dims).map(([dim, values]) => [dim, [...values]]),\n ),\n }\n : {}),\n ...(d.baseline !== undefined ? { baseline: d.baseline } : {}),\n };\n}\n\n/** The declared (or default first-declared) baseline result for a slot. */\nexport function baselineResultFor(d: SlotDeclInput): SlotResult {\n const decl = toWireSlot(d);\n return slotResultFor(decl, slotBaselineArm(decl));\n}\n\n/** Baseline results for a whole declaration list, keyed by slot id. */\nexport function baselineSlots(decls: SlotDeclInput[]): Record<string, SlotResult> {\n const out: Record<string, SlotResult> = {};\n for (const d of decls) out[d.id] = baselineResultFor(d);\n return out;\n}\n\n/**\n * Canonical arm string of a slot result: dims results encode as sorted\n * `dim=value` pairs joined with '|'; arms results are the arm id verbatim.\n */\nexport function armOfResult(result: SlotResult): string {\n return typeof result === 'string' ? result : canonicalArm(result);\n}\n","/**\n * Server-side helpers for SSR variant pre-loading.\n * Pure fetch — no DOM APIs. Safe in Node.js, Edge, and Deno runtimes.\n */\nimport { buildSessionUpsertPayload } from './session-meta.js';\nimport {\n toWireSlot,\n baselineResultFor,\n baselineSlots,\n type SlotDeclInput,\n type SlotResult,\n} from './slots.js';\n\nexport type { SlotDeclInput, SlotResult };\n\nexport type ServerAssignConfig = {\n /** Public API key (pk_...). */\n apiKey: string;\n /**\n * Base URL of the Sentient API without trailing slash.\n * e.g. 'https://api.yourapp.com/v1'\n */\n baseUrl: string;\n /**\n * Browser origin of your app (e.g. `http://localhost:3001`). Required for `pk_`\n * keys — server-side fetch must send the same `Origin` the API allows.\n */\n origin?: string;\n /** From `User-Agent` request header (Next.js `headers()`). */\n userAgent?: string;\n /** From `Referer` request header. */\n referer?: string;\n utmParams?: Record<string, string>;\n /**\n * Set true when the request carries a tracking opt-out — `DNT: 1` or\n * `Sec-GPC: 1`. When set, the SSR helpers skip the session upsert and the\n * assign/decide call entirely: the page renders defaults/baseline and no\n * session row is minted for the visitor (audit P4). The client SDK already\n * no-ops for these visitors; this keeps the server from minting a session +\n * assignment on every page view before the client can.\n */\n doNotTrack?: boolean;\n /**\n * Milliseconds to wait for the API before returning default variants.\n * Prevents slow/cold API from blocking SSR. Defaults to 1000 — the hot path\n * is served from in-process caches and typically returns in well under\n * 150 ms. The full 1 s budget is only reached on a cold start or an API\n * geographically distant from your SSR host, after which defaults render\n * with no layout shift. Lower it if your API is co-located and warm.\n */\n timeoutMs?: number;\n};\n\n/** componentId → assigned variantId */\nexport type ServerAssignments = Record<string, string>;\n\ntype AssignResult = { variantId: string; assignmentTtlMs: number };\n\nconst DEFAULT_TIMEOUT_MS = 1000;\n\nfunction fetchWithTimeout(\n url: string,\n init: RequestInit,\n timeoutMs: number,\n): Promise<Response> {\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), timeoutMs);\n return fetch(url, { ...init, signal: controller.signal }).finally(() =>\n clearTimeout(timer),\n );\n}\n\n/**\n * Fetches variant assignments server-side for all listed components.\n * Returns a map suitable for passing as `initialAssignments` to `<AdaptiveProvider>`.\n *\n * Call from Next.js layout, Server Component, or getServerSideProps.\n *\n * @example\n * ```tsx\n * const assignments = await preloadAssignments(\n * [\n * { id: 'hero', variantIds: ['hero-a', 'hero-b'] },\n * { id: 'cta', variantIds: ['cta-short', 'cta-long'] },\n * ],\n * sessionId, // read from cookies() or req.cookies\n * { apiKey: process.env.NEXT_PUBLIC_SENTIENT_API_KEY!, baseUrl: 'https://api.sentient-ui.com/v1' },\n * );\n * return <AdaptiveProvider ... initialAssignments={assignments}>{children}</AdaptiveProvider>;\n * ```\n */\nexport async function preloadAssignments(\n components: Array<{ id: string; variantIds: string[] }>,\n sessionId: string,\n config: ServerAssignConfig,\n): Promise<ServerAssignments> {\n // Opted-out visitor (DNT/GPC): render defaults, mint no session (audit P4).\n if (config.doNotTrack) return {};\n\n const timeoutMs = config.timeoutMs ?? DEFAULT_TIMEOUT_MS;\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n Authorization: `Bearer ${config.apiKey}`,\n };\n if (config.origin) {\n headers.Origin = config.origin;\n }\n\n // Session metadata must match the browser SDK so assign seeds variant_weights\n // under the same segment (not `unknown:unknown`).\n const sessionBody = buildSessionUpsertPayload(sessionId, {\n userAgent: config.userAgent,\n referer: config.referer,\n utmParams: config.utmParams,\n appOrigin: config.origin,\n });\n\n try {\n const res = await fetchWithTimeout(\n `${config.baseUrl}/sessions`,\n { method: 'POST', headers, body: JSON.stringify(sessionBody) },\n timeoutMs,\n );\n if (res.status === 402) {\n console.warn(\n '[SentientUI] Session limit exceeded for this project. The bandit will stop learning until the limit resets. Upgrade at sentient-ui.com/pricing',\n );\n } else if (!res.ok) {\n const body = await res.json().catch(() => ({}));\n console.error(`[SentientUI] preloadAssignments: session upsert failed (${res.status})`, body);\n }\n } catch (err) {\n console.error('[SentientUI] preloadAssignments: session upsert threw', err);\n }\n\n const results = await Promise.allSettled(\n components.map(async ({ id, variantIds }) => {\n const res = await fetchWithTimeout(\n `${config.baseUrl}/assign`,\n { method: 'POST', headers, body: JSON.stringify({ sessionId, componentId: id, variantIds }) },\n timeoutMs,\n );\n if (!res.ok) {\n const body = await res.json().catch(() => ({}));\n console.error(`[SentientUI] preloadAssignments: assign failed for \"${id}\" (${res.status})`, body);\n return null;\n }\n const body = (await res.json()) as AssignResult;\n return { id, variantId: body.variantId };\n }),\n );\n\n const assignments: ServerAssignments = {};\n for (const result of results) {\n if (result.status === 'fulfilled' && result.value) {\n assignments[result.value.id] = result.value.variantId;\n }\n }\n return assignments;\n}\n\n/**\n * Reads the Sentient session cookie from a Next.js `ReadonlyRequestCookies` object\n * (the return value of `cookies()` from `next/headers`), or any object with a\n * `get(name: string)` method. Returns null if the cookie is absent.\n */\nexport function readSessionCookie(\n cookies: { get(name: string): { value: string } | undefined },\n): string | null {\n return cookies.get('_snt_uid')?.value ?? null;\n}\n\nexport type DecideResult = {\n layoutOrder: string[];\n assignments: Record<string, string>;\n /** Slot results keyed by slot id. Baseline-resolved when the API omits/fails them. */\n slots: Record<string, SlotResult>;\n persona: string;\n confidence: number;\n};\n\n/**\n * Single-roundtrip SSR call returning layout order, component assignments,\n * and adaptive-slot results. Falls back to default section order + empty\n * assignments + baseline slots if the API is unavailable. A response without\n * a `slots` field means the server predates slots — every declared slot\n * resolves to its baseline (no retry).\n */\nexport async function preloadDecisions(\n params: {\n sections?: string[];\n components: Array<{ id: string; variantIds?: string[] }>;\n slots?: SlotDeclInput[];\n },\n sessionId: string,\n config: ServerAssignConfig,\n): Promise<DecideResult> {\n const timeoutMs = config.timeoutMs ?? DEFAULT_TIMEOUT_MS;\n const declaredSlots = params.slots ?? [];\n const fallback: DecideResult = {\n layoutOrder: params.sections ?? [],\n assignments: {},\n slots: baselineSlots(declaredSlots),\n persona: 'unknown',\n confidence: 0,\n };\n\n // Opted-out visitor (DNT/GPC): baseline layout/slots, mint no session (audit P4).\n if (config.doNotTrack) return fallback;\n\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n Authorization: `Bearer ${config.apiKey}`,\n };\n if (config.origin) headers.Origin = config.origin;\n\n const sessionBody = buildSessionUpsertPayload(sessionId, {\n userAgent: config.userAgent,\n referer: config.referer,\n utmParams: config.utmParams,\n appOrigin: config.origin,\n });\n\n try {\n const sessionRes = await fetchWithTimeout(\n `${config.baseUrl}/sessions`,\n { method: 'POST', headers, body: JSON.stringify(sessionBody) },\n timeoutMs,\n );\n if (!sessionRes.ok) {\n const body = await sessionRes.json().catch(() => ({}));\n console.error(`[SentientUI] preloadDecisions: session upsert failed (${sessionRes.status})`, body);\n }\n } catch (err) {\n console.error('[SentientUI] preloadDecisions: session upsert threw', err);\n }\n\n try {\n const res = await fetchWithTimeout(\n `${config.baseUrl}/decide`,\n {\n method: 'POST',\n headers,\n body: JSON.stringify({\n sessionId,\n sections: (params.sections ?? []).map((id) => ({ id })),\n components: params.components,\n ...(declaredSlots.length > 0 ? { slots: declaredSlots.map(toWireSlot) } : {}),\n }),\n },\n timeoutMs,\n );\n if (!res.ok) {\n const body = await res.json().catch(() => ({}));\n console.error(`[SentientUI] preloadDecisions: decide failed (${res.status})`, body);\n return fallback;\n }\n const data = (await res.json()) as {\n layoutOrder?: string[];\n assignments?: Record<string, string>;\n slots?: Record<string, SlotResult>;\n persona?: string;\n confidence?: number;\n };\n\n const slots: Record<string, SlotResult> = {};\n for (const d of declaredSlots) {\n // `data.slots === undefined` ⇒ server predates slots: baseline, no retry.\n slots[d.id] = data.slots?.[d.id] ?? baselineResultFor(d);\n }\n\n return {\n layoutOrder: data.layoutOrder ?? params.sections ?? [],\n assignments: data.assignments ?? {},\n slots,\n persona: data.persona ?? 'unknown',\n confidence: data.confidence ?? 0,\n };\n } catch (err) {\n console.error('[SentientUI] preloadDecisions: decide threw', err);\n return fallback;\n }\n}\n"],"mappings":"owBAAA,IAAAA,GAAA,GAAAC,EAAAD,GAAA,+BAAAE,EAAA,yBAAAC,EAAA,sBAAAC,EAAA,oBAAAC,EAAA,wBAAAC,EAAA,uBAAAC,EAAA,qBAAAC,EAAA,sBAAAC,EAAA,8BAAAC,IAAA,eAAAC,EAAAX,ICQO,IAAMY,EAAiC,CAC5C,SACA,eACA,gBACA,YACA,cACA,mBACA,gBACA,kBACA,kBACA,oBACA,qBACA,aACA,QACA,YACA,YACA,SACF,EAGO,SAASC,EAAaC,EAA4B,CACvD,OAAOC,GAAkBD,CAAS,IAAM,IAC1C,CAGO,SAASC,GAAkBD,EAAkC,CAjCpE,IAAAE,EAkCE,GAAI,CAACF,EAAW,OAAO,KACvB,IAAMG,EAAIH,EAAU,YAAY,EAChC,OAAOE,EAAAJ,EAAY,KAAMM,GAAUD,EAAE,SAASC,EAAM,YAAY,CAAC,CAAC,IAA3D,KAAAF,EAAgE,IACzE,CA8CO,SAASG,EAAkBC,EAA2B,CAC3D,IAAMC,EAAID,EAAU,YAAY,EAChC,MAAI,mCAAmC,KAAKC,CAAC,EAAU,SACnD,yCAAyC,KAAKA,CAAC,EAAU,SACtD,SACT,CAEO,SAASC,EAAoBC,EAAkBC,EAA4B,CAChF,GAAI,CAACD,EAAU,MAAO,SACtB,GAAI,CACF,IAAME,EAAS,IAAI,IAAIF,CAAQ,EAC/B,GAAIC,EACF,GAAI,CACF,GAAI,IAAI,IAAIA,CAAS,EAAE,OAASC,EAAO,KAAM,MAAO,QACtD,OAAQC,EAAA,CAER,CAEF,IAAMC,EAAOF,EAAO,SAAS,YAAY,EACzC,MAAI,yCAAyC,KAAKE,CAAI,EAAU,SAI5D,6EAA6E,KAAKA,CAAI,EAAU,SAC7F,UACT,OAAQD,EAAA,CACN,MAAO,QACT,CACF,CAEO,SAASE,EAA0BL,EAAiC,CACzE,GAAI,CAACA,EAAU,OAAO,KACtB,GAAI,CACF,OAAO,IAAI,IAAIA,CAAQ,EAAE,QAC3B,OAAQ,GACN,OAAO,IACT,CACF,CAEO,SAASM,EAAgBC,EAAiB,CAC/C,IAAMC,EAAID,EAAE,SAAS,EACrB,OAAIC,EAAI,EAAU,QACdA,EAAI,GAAW,UACfA,EAAI,GAAW,YACZ,SACT,CAoBO,SAASC,EAAqBC,EAI1B,CACT,IAAMC,EAAOC,EAA0B,cAAeF,CAAI,EAC1D,MAAO,GAAGC,EAAK,WAAW,IAAIA,EAAK,aAAa,EAClD,CAMO,SAASC,EACdC,EACAH,EASsB,CA5KxB,IAAAI,EAAAC,EAAAC,EAAAC,EAAAC,EAAAC,EAAAC,EA6KE,IAAMC,GAAKN,GAAAD,EAAAJ,GAAA,YAAAA,EAAM,YAAN,YAAAI,EAAiB,SAAjB,KAAAC,EAA2B,GAChCO,GAAUL,GAAAD,EAAAN,GAAA,YAAAA,EAAM,UAAN,YAAAM,EAAe,SAAf,KAAAC,EAAyB,GACnCM,GAAML,EAAAR,GAAA,YAAAA,EAAM,MAAN,KAAAQ,EAAa,IAAI,KAC7B,MAAO,CACL,UAAAL,EACA,UAAW,GACX,WAAWM,EAAAT,GAAA,YAAAA,EAAM,YAAN,KAAAS,EAAmB,CAAC,EAC/B,YAAaE,EAAKzB,EAAkByB,CAAE,EAAI,UAC1C,cAAeC,EACXvB,EAAoBuB,EAASZ,GAAA,YAAAA,EAAM,SAAS,EAC5C,SACJ,eAAgBL,EAA0BiB,CAAO,EACjD,UAAWhB,EAAgBiB,CAAG,EAC9B,WAAWH,EAAA,CAAC,MAAO,MAAO,MAAO,MAAO,MAAO,MAAO,KAAK,EAAEG,EAAI,OAAO,CAAC,IAA9D,KAAAH,EAAmE,MAC9E,YAAYV,GAAA,YAAAA,EAAM,aAAc,IAAQc,EAAaH,CAAE,CACzD,CACF,CCzLA,IAAAI,EAMO,8BAiBA,SAASC,EAAWC,EAA4B,CACrD,OAAOC,MAAA,CACL,GAAID,EAAE,IACFA,EAAE,KAAO,CAAE,KAAM,CAAC,GAAGA,EAAE,IAAI,CAAE,EAAI,CAAC,GAClCA,EAAE,KACF,CACE,KAAM,OAAO,YACX,OAAO,QAAQA,EAAE,IAAI,EAAE,IAAI,CAAC,CAACE,EAAKC,CAAM,IAAM,CAACD,EAAK,CAAC,GAAGC,CAAM,CAAC,CAAC,CAClE,CACF,EACA,CAAC,GACDH,EAAE,WAAa,OAAY,CAAE,SAAUA,EAAE,QAAS,EAAI,CAAC,EAE/D,CAGO,SAASI,EAAkBJ,EAA8B,CAC9D,IAAMK,EAAON,EAAWC,CAAC,EACzB,SAAO,iBAAcK,KAAM,mBAAgBA,CAAI,CAAC,CAClD,CAGO,SAASC,EAAcC,EAAoD,CAChF,IAAMC,EAAkC,CAAC,EACzC,QAAWR,KAAKO,EAAOC,EAAIR,EAAE,EAAE,EAAII,EAAkBJ,CAAC,EACtD,OAAOQ,CACT,CCKA,IAAMC,EAAqB,IAE3B,SAASC,EACPC,EACAC,EACAC,EACmB,CACnB,IAAMC,EAAa,IAAI,gBACjBC,EAAQ,WAAW,IAAMD,EAAW,MAAM,EAAGD,CAAS,EAC5D,OAAO,MAAMF,EAAKK,EAAAC,EAAA,GAAKL,GAAL,CAAW,OAAQE,EAAW,MAAO,EAAC,EAAE,QAAQ,IAChE,aAAaC,CAAK,CACpB,CACF,CAqBA,eAAsBG,EACpBC,EACAC,EACAC,EAC4B,CA/F9B,IAAAC,EAiGE,GAAID,EAAO,WAAY,MAAO,CAAC,EAE/B,IAAMR,GAAYS,EAAAD,EAAO,YAAP,KAAAC,EAAoBb,EAChCc,EAAkC,CACtC,eAAgB,mBAChB,cAAe,UAAUF,EAAO,MAAM,EACxC,EACIA,EAAO,SACTE,EAAQ,OAASF,EAAO,QAK1B,IAAMG,EAAcC,EAA0BL,EAAW,CACvD,UAAWC,EAAO,UAClB,QAASA,EAAO,QAChB,UAAWA,EAAO,UAClB,UAAWA,EAAO,MACpB,CAAC,EAED,GAAI,CACF,IAAMK,EAAM,MAAMhB,EAChB,GAAGW,EAAO,OAAO,YACjB,CAAE,OAAQ,OAAQ,QAAAE,EAAS,KAAM,KAAK,UAAUC,CAAW,CAAE,EAC7DX,CACF,EACA,GAAIa,EAAI,SAAW,IACjB,QAAQ,KACN,gJACF,UACS,CAACA,EAAI,GAAI,CAClB,IAAMC,EAAO,MAAMD,EAAI,KAAK,EAAE,MAAM,KAAO,CAAC,EAAE,EAC9C,QAAQ,MAAM,2DAA2DA,EAAI,MAAM,IAAKC,CAAI,CAC9F,CACF,OAASC,EAAK,CACZ,QAAQ,MAAM,wDAAyDA,CAAG,CAC5E,CAEA,IAAMC,EAAU,MAAM,QAAQ,WAC5BV,EAAW,IAAI,MAAO,CAAE,GAAAW,EAAI,WAAAC,CAAW,IAAM,CAC3C,IAAML,EAAM,MAAMhB,EAChB,GAAGW,EAAO,OAAO,UACjB,CAAE,OAAQ,OAAQ,QAAAE,EAAS,KAAM,KAAK,UAAU,CAAE,UAAAH,EAAW,YAAaU,EAAI,WAAAC,CAAW,CAAC,CAAE,EAC5FlB,CACF,EACA,GAAI,CAACa,EAAI,GAAI,CACX,IAAMC,EAAO,MAAMD,EAAI,KAAK,EAAE,MAAM,KAAO,CAAC,EAAE,EAC9C,eAAQ,MAAM,uDAAuDI,CAAE,MAAMJ,EAAI,MAAM,IAAKC,CAAI,EACzF,IACT,CACA,IAAMA,EAAQ,MAAMD,EAAI,KAAK,EAC7B,MAAO,CAAE,GAAAI,EAAI,UAAWH,EAAK,SAAU,CACzC,CAAC,CACH,EAEMK,EAAiC,CAAC,EACxC,QAAWC,KAAUJ,EACfI,EAAO,SAAW,aAAeA,EAAO,QAC1CD,EAAYC,EAAO,MAAM,EAAE,EAAIA,EAAO,MAAM,WAGhD,OAAOD,CACT,CAOO,SAASE,EACdC,EACe,CAxKjB,IAAAb,EAAAc,EAyKE,OAAOA,GAAAd,EAAAa,EAAQ,IAAI,UAAU,IAAtB,YAAAb,EAAyB,QAAzB,KAAAc,EAAkC,IAC3C,CAkBA,eAAsBC,EACpBC,EAKAlB,EACAC,EACuB,CApMzB,IAAAC,EAAAc,EAAAG,EAAAC,EAAAC,EAAAC,EAAAC,EAAAC,EAAAC,EAAAC,EAAAC,EAqME,IAAMlC,GAAYS,EAAAD,EAAO,YAAP,KAAAC,EAAoBb,EAChCuC,GAAgBZ,EAAAE,EAAO,QAAP,KAAAF,EAAgB,CAAC,EACjCa,EAAyB,CAC7B,aAAaV,EAAAD,EAAO,WAAP,KAAAC,EAAmB,CAAC,EACjC,YAAa,CAAC,EACd,MAAOW,EAAcF,CAAa,EAClC,QAAS,UACT,WAAY,CACd,EAGA,GAAI3B,EAAO,WAAY,OAAO4B,EAE9B,IAAM1B,EAAkC,CACtC,eAAgB,mBAChB,cAAe,UAAUF,EAAO,MAAM,EACxC,EACIA,EAAO,SAAQE,EAAQ,OAASF,EAAO,QAE3C,IAAMG,EAAcC,EAA0BL,EAAW,CACvD,UAAWC,EAAO,UAClB,QAASA,EAAO,QAChB,UAAWA,EAAO,UAClB,UAAWA,EAAO,MACpB,CAAC,EAED,GAAI,CACF,IAAM8B,EAAa,MAAMzC,EACvB,GAAGW,EAAO,OAAO,YACjB,CAAE,OAAQ,OAAQ,QAAAE,EAAS,KAAM,KAAK,UAAUC,CAAW,CAAE,EAC7DX,CACF,EACA,GAAI,CAACsC,EAAW,GAAI,CAClB,IAAMxB,EAAO,MAAMwB,EAAW,KAAK,EAAE,MAAM,KAAO,CAAC,EAAE,EACrD,QAAQ,MAAM,yDAAyDA,EAAW,MAAM,IAAKxB,CAAI,CACnG,CACF,OAASC,EAAK,CACZ,QAAQ,MAAM,sDAAuDA,CAAG,CAC1E,CAEA,GAAI,CACF,IAAMF,EAAM,MAAMhB,EAChB,GAAGW,EAAO,OAAO,UACjB,CACE,OAAQ,OACR,QAAAE,EACA,KAAM,KAAK,UAAUN,EAAA,CACnB,UAAAG,EACA,WAAWoB,EAAAF,EAAO,WAAP,KAAAE,EAAmB,CAAC,GAAG,IAAKV,IAAQ,CAAE,GAAAA,CAAG,EAAE,EACtD,WAAYQ,EAAO,YACfU,EAAc,OAAS,EAAI,CAAE,MAAOA,EAAc,IAAII,CAAU,CAAE,EAAI,CAAC,EAC5E,CACH,EACAvC,CACF,EACA,GAAI,CAACa,EAAI,GAAI,CACX,IAAMC,EAAO,MAAMD,EAAI,KAAK,EAAE,MAAM,KAAO,CAAC,EAAE,EAC9C,eAAQ,MAAM,iDAAiDA,EAAI,MAAM,IAAKC,CAAI,EAC3EsB,CACT,CACA,IAAMI,EAAQ,MAAM3B,EAAI,KAAK,EAQvB4B,EAAoC,CAAC,EAC3C,QAAWC,KAAKP,EAEdM,EAAMC,EAAE,EAAE,GAAIb,GAAAD,EAAAY,EAAK,QAAL,YAAAZ,EAAac,EAAE,MAAf,KAAAb,EAAsBc,EAAkBD,CAAC,EAGzD,MAAO,CACL,aAAaX,GAAAD,EAAAU,EAAK,cAAL,KAAAV,EAAoBL,EAAO,WAA3B,KAAAM,EAAuC,CAAC,EACrD,aAAaC,EAAAQ,EAAK,cAAL,KAAAR,EAAoB,CAAC,EAClC,MAAAS,EACA,SAASR,EAAAO,EAAK,UAAL,KAAAP,EAAgB,UACzB,YAAYC,EAAAM,EAAK,aAAL,KAAAN,EAAmB,CACjC,CACF,OAASnB,EAAK,CACZ,eAAQ,MAAM,8CAA+CA,CAAG,EACzDqB,CACT,CACF","names":["index_server_exports","__export","buildSessionUpsertPayload","deriveSessionSegment","detectDeviceClass","detectTimeOfDay","detectTrafficSource","preloadAssignments","preloadDecisions","readSessionCookie","referrerDomainFromReferer","__toCommonJS","agentUaList","uaTokenMatch","userAgent","matchedAgentToken","_a","s","token","detectDeviceClass","userAgent","s","detectTrafficSource","referrer","appOrigin","refUrl","e","host","referrerDomainFromReferer","detectTimeOfDay","d","h","deriveSessionSegment","opts","body","buildSessionUpsertPayload","sessionId","_a","_b","_c","_d","_e","_f","_g","ua","referer","now","uaTokenMatch","import_policy","toWireSlot","d","__spreadValues","dim","values","baselineResultFor","decl","baselineSlots","decls","out","DEFAULT_TIMEOUT_MS","fetchWithTimeout","url","init","timeoutMs","controller","timer","__spreadProps","__spreadValues","preloadAssignments","components","sessionId","config","_a","headers","sessionBody","buildSessionUpsertPayload","res","body","err","results","id","variantIds","assignments","result","readSessionCookie","cookies","_b","preloadDecisions","params","_c","_d","_e","_f","_g","_h","_i","_j","_k","declaredSlots","fallback","baselineSlots","sessionRes","toWireSlot","data","slots","d","baselineResultFor"]}
@@ -1,2 +1,2 @@
1
- import{d as x,e as j,f as $,g as C,h as M,i as f,j as U,k as D,l as P}from"./chunk-L5TA3FAB.mjs";import{a as A,b as T}from"./chunk-TMCGHANO.mjs";var k=1e3;function b(r,n,e){let i=new AbortController,o=setTimeout(()=>i.abort(),e);return fetch(r,T(A({},n),{signal:i.signal})).finally(()=>clearTimeout(o))}async function N(r,n,e){var p;if(e.doNotTrack)return{};let i=(p=e.timeoutMs)!=null?p:k,o={"Content-Type":"application/json",Authorization:`Bearer ${e.apiKey}`};e.origin&&(o.Origin=e.origin);let u=f(n,{userAgent:e.userAgent,referer:e.referer,utmParams:e.utmParams,appOrigin:e.origin});try{let s=await b(`${e.baseUrl}/sessions`,{method:"POST",headers:o,body:JSON.stringify(u)},i);if(s.status===402)console.warn("[SentientUI] Session limit exceeded for this project. The bandit will stop learning until the limit resets. Upgrade at sentient-ui.com/pricing");else if(!s.ok){let d=await s.json().catch(()=>({}));console.error(`[SentientUI] preloadAssignments: session upsert failed (${s.status})`,d)}}catch(s){console.error("[SentientUI] preloadAssignments: session upsert threw",s)}let g=await Promise.allSettled(r.map(async({id:s,variantIds:d})=>{let a=await b(`${e.baseUrl}/assign`,{method:"POST",headers:o,body:JSON.stringify({sessionId:n,componentId:s,variantIds:d})},i);if(!a.ok){let y=await a.json().catch(()=>({}));return console.error(`[SentientUI] preloadAssignments: assign failed for "${s}" (${a.status})`,y),null}let S=await a.json();return{id:s,variantId:S.variantId}})),m={};for(let s of g)s.status==="fulfilled"&&s.value&&(m[s.value.id]=s.value.variantId);return m}function B(r){var n,e;return(e=(n=r.get("_snt_uid"))==null?void 0:n.value)!=null?e:null}async function J(r,n,e){var p,s,d,a,S,y,R,h,v,w,I;let i=(p=e.timeoutMs)!=null?p:k,o=(s=r.slots)!=null?s:[],u={layoutOrder:(d=r.sections)!=null?d:[],assignments:{},slots:P(o),persona:"unknown",confidence:0};if(e.doNotTrack)return u;let g={"Content-Type":"application/json",Authorization:`Bearer ${e.apiKey}`};e.origin&&(g.Origin=e.origin);let m=f(n,{userAgent:e.userAgent,referer:e.referer,utmParams:e.utmParams,appOrigin:e.origin});try{let t=await b(`${e.baseUrl}/sessions`,{method:"POST",headers:g,body:JSON.stringify(m)},i);if(!t.ok){let l=await t.json().catch(()=>({}));console.error(`[SentientUI] preloadDecisions: session upsert failed (${t.status})`,l)}}catch(t){console.error("[SentientUI] preloadDecisions: session upsert threw",t)}try{let t=await b(`${e.baseUrl}/decide`,{method:"POST",headers:g,body:JSON.stringify(A({sessionId:n,sections:((a=r.sections)!=null?a:[]).map(c=>({id:c})),components:r.components},o.length>0?{slots:o.map(U)}:{}))},i);if(!t.ok){let c=await t.json().catch(()=>({}));return console.error(`[SentientUI] preloadDecisions: decide failed (${t.status})`,c),u}let l=await t.json(),O={};for(let c of o)O[c.id]=(y=(S=l.slots)==null?void 0:S[c.id])!=null?y:D(c);return{layoutOrder:(h=(R=l.layoutOrder)!=null?R:r.sections)!=null?h:[],assignments:(v=l.assignments)!=null?v:{},slots:O,persona:(w=l.persona)!=null?w:"unknown",confidence:(I=l.confidence)!=null?I:0}}catch(t){return console.error("[SentientUI] preloadDecisions: decide threw",t),u}}export{f as buildSessionUpsertPayload,M as deriveSessionSegment,x as detectDeviceClass,C as detectTimeOfDay,j as detectTrafficSource,N as preloadAssignments,J as preloadDecisions,B as readSessionCookie,$ as referrerDomainFromReferer};
1
+ import{g as x,h as j,i as $,j as C,k as M,l as f,m as U,n as D,o as P}from"./chunk-MYT7OJBV.mjs";import{a as A,b as T}from"./chunk-TMCGHANO.mjs";var k=1e3;function b(r,n,e){let i=new AbortController,o=setTimeout(()=>i.abort(),e);return fetch(r,T(A({},n),{signal:i.signal})).finally(()=>clearTimeout(o))}async function N(r,n,e){var p;if(e.doNotTrack)return{};let i=(p=e.timeoutMs)!=null?p:k,o={"Content-Type":"application/json",Authorization:`Bearer ${e.apiKey}`};e.origin&&(o.Origin=e.origin);let u=f(n,{userAgent:e.userAgent,referer:e.referer,utmParams:e.utmParams,appOrigin:e.origin});try{let s=await b(`${e.baseUrl}/sessions`,{method:"POST",headers:o,body:JSON.stringify(u)},i);if(s.status===402)console.warn("[SentientUI] Session limit exceeded for this project. The bandit will stop learning until the limit resets. Upgrade at sentient-ui.com/pricing");else if(!s.ok){let d=await s.json().catch(()=>({}));console.error(`[SentientUI] preloadAssignments: session upsert failed (${s.status})`,d)}}catch(s){console.error("[SentientUI] preloadAssignments: session upsert threw",s)}let g=await Promise.allSettled(r.map(async({id:s,variantIds:d})=>{let a=await b(`${e.baseUrl}/assign`,{method:"POST",headers:o,body:JSON.stringify({sessionId:n,componentId:s,variantIds:d})},i);if(!a.ok){let y=await a.json().catch(()=>({}));return console.error(`[SentientUI] preloadAssignments: assign failed for "${s}" (${a.status})`,y),null}let S=await a.json();return{id:s,variantId:S.variantId}})),m={};for(let s of g)s.status==="fulfilled"&&s.value&&(m[s.value.id]=s.value.variantId);return m}function B(r){var n,e;return(e=(n=r.get("_snt_uid"))==null?void 0:n.value)!=null?e:null}async function J(r,n,e){var p,s,d,a,S,y,R,h,v,w,I;let i=(p=e.timeoutMs)!=null?p:k,o=(s=r.slots)!=null?s:[],u={layoutOrder:(d=r.sections)!=null?d:[],assignments:{},slots:P(o),persona:"unknown",confidence:0};if(e.doNotTrack)return u;let g={"Content-Type":"application/json",Authorization:`Bearer ${e.apiKey}`};e.origin&&(g.Origin=e.origin);let m=f(n,{userAgent:e.userAgent,referer:e.referer,utmParams:e.utmParams,appOrigin:e.origin});try{let t=await b(`${e.baseUrl}/sessions`,{method:"POST",headers:g,body:JSON.stringify(m)},i);if(!t.ok){let l=await t.json().catch(()=>({}));console.error(`[SentientUI] preloadDecisions: session upsert failed (${t.status})`,l)}}catch(t){console.error("[SentientUI] preloadDecisions: session upsert threw",t)}try{let t=await b(`${e.baseUrl}/decide`,{method:"POST",headers:g,body:JSON.stringify(A({sessionId:n,sections:((a=r.sections)!=null?a:[]).map(c=>({id:c})),components:r.components},o.length>0?{slots:o.map(U)}:{}))},i);if(!t.ok){let c=await t.json().catch(()=>({}));return console.error(`[SentientUI] preloadDecisions: decide failed (${t.status})`,c),u}let l=await t.json(),O={};for(let c of o)O[c.id]=(y=(S=l.slots)==null?void 0:S[c.id])!=null?y:D(c);return{layoutOrder:(h=(R=l.layoutOrder)!=null?R:r.sections)!=null?h:[],assignments:(v=l.assignments)!=null?v:{},slots:O,persona:(w=l.persona)!=null?w:"unknown",confidence:(I=l.confidence)!=null?I:0}}catch(t){return console.error("[SentientUI] preloadDecisions: decide threw",t),u}}export{f as buildSessionUpsertPayload,M as deriveSessionSegment,x as detectDeviceClass,C as detectTimeOfDay,j as detectTrafficSource,N as preloadAssignments,J as preloadDecisions,B as readSessionCookie,$ as referrerDomainFromReferer};
2
2
  //# sourceMappingURL=index-server.mjs.map
package/dist/index.d.cts CHANGED
@@ -1,3 +1,3 @@
1
- export { A as AssignResult, a as Assignment, C as ComponentGoalOptions, c as ComponentWeightEntry, d as CompoundLocator, D as DecideInput, e as DecideOutcome, f as DecisionSnapshot, g as EventType, G as GoalDefinition, i as GraphConfig, j as GraphSnapshot, L as LOCAL_MODE_BANNER, M as MicroSignalEmitter, k as MicroSignalType, P as PROD_KEYLESS_ERROR, Q as QueueConfig, S as SNAPSHOT_STORAGE_KEY_PREFIX, m as SectionMapEntry, n as SentientClient, o as SentientConfig, p as SentientEvent, q as SessionConfig, r as SessionManager, s as SlotConfigEntry, t as SlotOps, W as WeightEntry, u as attachMicroSignalDetectors, v as grantConsent, w as init, x as isDoNotTrackEnabled, y as readSnapshot, z as renderPrePaintScript, F as writeSnapshot } from './index-DCP2qgno.cjs';
2
- export { a as SlotDeclInput, b as agentUaList, c as armOfResult, d as baselineResultFor, e as baselineSlots, g as deriveSessionSegment, h as detectDeviceClass, i as detectTimeOfDay, j as detectTrafficSource, m as matchedAgentToken, r as referrerDomainFromReferer, t as toWireSlot, u as uaTokenMatch } from './session-meta-DU_3mY7U.cjs';
1
+ export { A as AssignResult, a as Assignment, C as ComponentGoalOptions, c as ComponentWeightEntry, d as CompoundLocator, D as DecideInput, e as DecideOutcome, f as DecisionSnapshot, g as EventType, G as GoalDefinition, i as GraphConfig, j as GraphSnapshot, L as LOCAL_MODE_BANNER, M as MicroSignalEmitter, k as MicroSignalType, P as PROD_KEYLESS_ERROR, Q as QueueConfig, S as SNAPSHOT_STORAGE_KEY_PREFIX, m as SectionMapEntry, n as SentientClient, o as SentientConfig, p as SentientEvent, q as SessionConfig, r as SessionManager, s as SlotConfigEntry, t as SlotOps, W as WeightEntry, u as attachMicroSignalDetectors, v as grantConsent, w as init, x as isDoNotTrackEnabled, y as readSnapshot, z as renderPrePaintScript, F as writeSnapshot } from './index-a8WMLbpe.cjs';
2
+ export { A as AGENT_INTENTS, a as AgentIntent, b as SlotDeclInput, c as agentIntent, d as agentUaList, e as armOfResult, f as baselineResultFor, g as baselineSlots, i as classifiedAgents, j as deriveSessionSegment, k as detectDeviceClass, l as detectTimeOfDay, m as detectTrafficSource, n as matchedAgentToken, r as referrerDomainFromReferer, t as toWireSlot, u as uaTokenMatch } from './session-meta-BVvq5RBB.cjs';
3
3
  export { SlotResult } from '@sentientui/policy';
package/dist/index.d.ts CHANGED
@@ -1,3 +1,3 @@
1
- export { A as AssignResult, a as Assignment, C as ComponentGoalOptions, c as ComponentWeightEntry, d as CompoundLocator, D as DecideInput, e as DecideOutcome, f as DecisionSnapshot, g as EventType, G as GoalDefinition, i as GraphConfig, j as GraphSnapshot, L as LOCAL_MODE_BANNER, M as MicroSignalEmitter, k as MicroSignalType, P as PROD_KEYLESS_ERROR, Q as QueueConfig, S as SNAPSHOT_STORAGE_KEY_PREFIX, m as SectionMapEntry, n as SentientClient, o as SentientConfig, p as SentientEvent, q as SessionConfig, r as SessionManager, s as SlotConfigEntry, t as SlotOps, W as WeightEntry, u as attachMicroSignalDetectors, v as grantConsent, w as init, x as isDoNotTrackEnabled, y as readSnapshot, z as renderPrePaintScript, F as writeSnapshot } from './index-Br4jju2S.js';
2
- export { a as SlotDeclInput, b as agentUaList, c as armOfResult, d as baselineResultFor, e as baselineSlots, g as deriveSessionSegment, h as detectDeviceClass, i as detectTimeOfDay, j as detectTrafficSource, m as matchedAgentToken, r as referrerDomainFromReferer, t as toWireSlot, u as uaTokenMatch } from './session-meta-DU_3mY7U.js';
1
+ export { A as AssignResult, a as Assignment, C as ComponentGoalOptions, c as ComponentWeightEntry, d as CompoundLocator, D as DecideInput, e as DecideOutcome, f as DecisionSnapshot, g as EventType, G as GoalDefinition, i as GraphConfig, j as GraphSnapshot, L as LOCAL_MODE_BANNER, M as MicroSignalEmitter, k as MicroSignalType, P as PROD_KEYLESS_ERROR, Q as QueueConfig, S as SNAPSHOT_STORAGE_KEY_PREFIX, m as SectionMapEntry, n as SentientClient, o as SentientConfig, p as SentientEvent, q as SessionConfig, r as SessionManager, s as SlotConfigEntry, t as SlotOps, W as WeightEntry, u as attachMicroSignalDetectors, v as grantConsent, w as init, x as isDoNotTrackEnabled, y as readSnapshot, z as renderPrePaintScript, F as writeSnapshot } from './index-sGcvT3pc.js';
2
+ export { A as AGENT_INTENTS, a as AgentIntent, b as SlotDeclInput, c as agentIntent, d as agentUaList, e as armOfResult, f as baselineResultFor, g as baselineSlots, i as classifiedAgents, j as deriveSessionSegment, k as detectDeviceClass, l as detectTimeOfDay, m as detectTrafficSource, n as matchedAgentToken, r as referrerDomainFromReferer, t as toWireSlot, u as uaTokenMatch } from './session-meta-BVvq5RBB.js';
3
3
  export { SlotResult } from '@sentientui/policy';
package/dist/index.js CHANGED
@@ -1,2 +1,2 @@
1
- "use strict";var Ve=Object.create;var oe=Object.defineProperty,He=Object.defineProperties,ze=Object.getOwnPropertyDescriptor,Ye=Object.getOwnPropertyDescriptors,qe=Object.getOwnPropertyNames,De=Object.getOwnPropertySymbols,Xe=Object.getPrototypeOf,Te=Object.prototype.hasOwnProperty,Ze=Object.prototype.propertyIsEnumerable;var Oe=(e,t,n)=>t in e?oe(e,t,{enumerable:!0,configurable:!0,writable:!0,value:n}):e[t]=n,v=(e,t)=>{for(var n in t||(t={}))Te.call(t,n)&&Oe(e,n,t[n]);if(De)for(var n of De(t))Ze.call(t,n)&&Oe(e,n,t[n]);return e},Q=(e,t)=>He(e,Ye(t));var et=(e,t)=>{for(var n in t)oe(e,n,{get:t[n],enumerable:!0})},Pe=(e,t,n,i)=>{if(t&&typeof t=="object"||typeof t=="function")for(let f of qe(t))!Te.call(e,f)&&f!==n&&oe(e,f,{get:()=>t[f],enumerable:!(i=ze(t,f))||i.enumerable});return e};var tt=(e,t,n)=>(n=e!=null?Ve(Xe(e)):{},Pe(t||!e||!e.__esModule?oe(n,"default",{value:e,enumerable:!0}):n,e)),nt=e=>Pe(oe({},"__esModule",{value:!0}),e);var At={};et(At,{LOCAL_MODE_BANNER:()=>Ie,PROD_KEYLESS_ERROR:()=>ve,SNAPSHOT_STORAGE_KEY_PREFIX:()=>J,agentUaList:()=>Ee,armOfResult:()=>me,attachMicroSignalDetectors:()=>Be,baselineResultFor:()=>H,baselineSlots:()=>Ue,deriveSessionSegment:()=>Ne,detectDeviceClass:()=>se,detectTimeOfDay:()=>le,detectTrafficSource:()=>ie,grantConsent:()=>Rt,init:()=>Je,isDoNotTrackEnabled:()=>ke,matchedAgentToken:()=>xe,readSnapshot:()=>ye,referrerDomainFromReferer:()=>ae,renderPrePaintScript:()=>Ke,toWireSlot:()=>ce,uaTokenMatch:()=>re,writeSnapshot:()=>z});module.exports=nt(At);function ue(){try{if(typeof crypto!="undefined"&&typeof crypto.randomUUID=="function")return crypto.randomUUID()}catch(e){}try{if(typeof crypto!="undefined"&&typeof crypto.getRandomValues=="function"){let e=new Uint8Array(16);crypto.getRandomValues(e),e[6]=e[6]&15|64,e[8]=e[8]&63|128;let t="";for(let n=0;n<16;n++)t+=e[n].toString(16).padStart(2,"0"),(n===3||n===5||n===7||n===9)&&(t+="-");return t}}catch(e){}return"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,e=>{let t=Math.random()*16|0;return(e==="x"?t:t&3|8).toString(16)})}function ge(e){return e?`_${e.slice(0,12)}`:""}var ot="_snt_uid",rt=365,st="_snt_uid";function it(){return ue()}function at(e){try{let t=document.cookie.match(new RegExp(`(?:^|; )${e}=([^;]*)`));return t?decodeURIComponent(t[1]):null}catch(t){return null}}function lt(e,t,n){try{document.cookie=`${e}=${encodeURIComponent(t)}; max-age=${n}; SameSite=strict; path=/`}catch(i){}}function ct(e){try{return localStorage.getItem(e)}catch(t){return null}}function dt(e,t){try{return localStorage.setItem(e,t),!0}catch(n){return!1}}function ut(e){try{return sessionStorage.getItem(e)}catch(t){return null}}function gt(e,t){try{return sessionStorage.setItem(e,t),!0}catch(n){return!1}}function pt(e){try{sessionStorage.removeItem(e)}catch(t){}}function ft(e){try{return document.cookie=`${e}_probe=1; max-age=1; SameSite=strict; path=/`,document.cookie.indexOf(`${e}_probe=1`)!==-1}catch(t){return!1}}function mt(e){try{localStorage.removeItem(e)}catch(t){}}function yt(e){try{document.cookie=`${e}=; max-age=0; SameSite=strict; path=/`}catch(t){}}var St={getSessionId:()=>null,isEphemeral:()=>!1,destroy:()=>{}};function pe(e){var m,E,L,b,I,C;if(typeof window=="undefined")return St;let t=ge(e==null?void 0:e.apiKey),n=(m=e==null?void 0:e.cookieName)!=null?m:`${ot}${t}`,i=`${st}${t}`,c=((E=e==null?void 0:e.cookieTTLDays)!=null?E:rt)*24*60*60,u=h=>h&&h.length>0?h:null,r=(C=(I=(b=(L=u(at(n)))!=null?L:u(ct(i)))!=null?b:u(ut(i)))!=null?I:u(e==null?void 0:e.ssrSessionId))!=null?C:it();lt(n,r,c);let s=dt(i,r),o=ft(n),l=s?!1:gt(i,r),d=!s&&!o&&!l;return{getSessionId:()=>r,isEphemeral:()=>d,destroy:()=>{r=null,yt(n),mt(i),pt(i)}}}function be(e){return`_snt_retry_${e.slice(0,12)}`}var ht={push:()=>{},flush:()=>{},destroy:()=>{}};function vt(e,t){try{let n=localStorage.getItem(t);if(!n)return[];let i=JSON.parse(n);return Array.isArray(i)?(localStorage.removeItem(t),i.slice(-e)):[]}catch(n){return[]}}function we(e,t,n){try{let i=(()=>{try{let u=localStorage.getItem(n);if(!u)return[];let r=JSON.parse(u);return Array.isArray(r)?r:[]}catch(u){return[]}})(),f=new Map;for(let u of i)f.set(u.id,u);for(let u of e)f.set(u.id,u);let c=[...f.values()].slice(-t);localStorage.setItem(n,JSON.stringify(c))}catch(i){}}function wt(e,t){try{let n=localStorage.getItem(t);if(!n)return;let i=JSON.parse(n);if(!Array.isArray(i))return;let f=new Set(e),c=i.filter(u=>!f.has(u.id));if(c.length===i.length)return;c.length===0?localStorage.removeItem(t):localStorage.setItem(t,JSON.stringify(c))}catch(n){}}function Le(e){var X,Z,ee;if(typeof window=="undefined")return ht;let t=(X=e.flushIntervalMs)!=null?X:5e3,n=(Z=e.maxBatchSize)!=null?Z:20,i=(ee=e.maxRetrySize)!=null?ee:100,f=e.ingestUrl,c=e.apiKey,u=be(c),r=[],s=new Set,o=[],l=p=>{for(let y of p)d.delete(y),!s.has(y)&&(s.add(y),o.push(y));for(;o.length>500;){let y=o.shift();y&&s.delete(y)}wt(p,u)},d=new Set,m=p=>{s.has(p.id)||d.has(p.id)||(d.add(p.id),r.push(p))},E=p=>{for(let y of p)s.has(y.id)||(d.add(y.id),r.push(y))},L=vt(i,u);for(let p of L)m(p);let b=0,I=0,C=p=>{if(p.length===0)return;let y=JSON.stringify(p),N=p.map(a=>a.id),T;try{T=fetch(f,{method:"POST",keepalive:!0,body:y,headers:{"Content-Type":"application/json",Authorization:`Bearer ${c}`}})}catch(a){we(p,i,u),E(p),I++,b=Date.now()+Math.min(6e4,1e3*2**Math.min(I,6));return}let K=a=>{if(a.ok||a.status>=400&&a.status<500&&a.status!==429){l(N),I=0,b=0;return}we(p,i,u),E(p),I++,b=Date.now()+Math.min(6e4,1e3*2**Math.min(I,6))};T instanceof Promise?T.then(K).catch(()=>{we(p,i,u),E(p),I++,b=Date.now()+Math.min(6e4,1e3*2**Math.min(I,6))}):K(T)},h=typeof TextEncoder!="undefined"?new TextEncoder:null,de=p=>h?h.encode(p).length:p.length,B=p=>{let y=[],N=2;for(let T of p){let K=de(JSON.stringify(T))+1;if(y.length>0&&N+K>57344||y.length>=n)break;y.push(T),N+=K}return y},M=()=>{try{if(Date.now()<b)return;for(;r.length>0&&!(Date.now()<b);){let p=r.filter(N=>!s.has(N.id));if(r.length=0,p.length===0)break;let y=B(p);if(y.length===0)break;y.length<p.length&&r.push(...p.slice(y.length)),C(y)}}catch(p){}},O=!0,W=null;W=setInterval(()=>{O&&M()},t);let U=()=>{document.visibilityState==="hidden"&&M()},q=()=>{M()};return document.addEventListener("visibilitychange",U),window.addEventListener("pagehide",q),{push(p){m(p),r.length>=n&&M()},flush:M,destroy(){O=!1,W!==null&&(clearInterval(W),W=null),document.removeEventListener("visibilitychange",U),window.removeEventListener("pagehide",q),M()}}}var bt=1800*1e3;function fe(e,t){return`${encodeURIComponent(e)}:${encodeURIComponent(t)}`}function Me(e=bt,t){let n=new Map,i=`_snt_asgn${ge(t)}_`,f=(o,l)=>`${i}${encodeURIComponent(o)}:${encodeURIComponent(l)}`,c=o=>{let l=o.slice(i.length),d=l.indexOf(":");if(d<0)return null;try{return{componentId:decodeURIComponent(l.slice(0,d)),segment:decodeURIComponent(l.slice(d+1))}}catch(m){return null}},u=()=>{try{let o=[];for(let l=0;l<localStorage.length;l++){let d=localStorage.key(l);d!=null&&d.startsWith(i)&&o.push(d)}return o}catch(o){return[]}},r=o=>o.assignedAt+(o.ttlMs&&o.ttlMs>0?o.ttlMs:e)<Date.now();return typeof window!="undefined"&&(()=>{for(let o of u())try{let l=localStorage.getItem(o);if(!l)continue;let d=JSON.parse(l);if(r(d)){localStorage.removeItem(o);continue}let m=c(o);if(!m)continue;n.set(fe(m.componentId,m.segment),d)}catch(l){}})(),{get(o,l){let d=n.get(fe(o,l));return d?r(d)?(n.delete(fe(o,l)),null):d:null},set(o,l,d){let m=fe(o,l);n.set(m,d);try{localStorage.setItem(f(o,l),JSON.stringify(d))}catch(E){}},invalidate(o){let l=`${encodeURIComponent(o)}:`;for(let d of[...n.keys()])d.startsWith(l)&&n.delete(d);for(let d of u()){let m=c(d);if((m==null?void 0:m.componentId)===o)try{localStorage.removeItem(d)}catch(E){}}},clear(){n.clear();for(let o of u())try{localStorage.removeItem(o)}catch(l){}}}}var Ee=["GPTBot","ChatGPT-User","OAI-SearchBot","ClaudeBot","Claude-User","Claude-SearchBot","PerplexityBot","Perplexity-User","Google-Extended","Applebot-Extended","Meta-ExternalAgent","Bytespider","CCBot","Amazonbot","cohere-ai","Diffbot"];function re(e){return xe(e)!==null}function xe(e){var n;if(!e)return null;let t=e.toLowerCase();return(n=Ee.find(i=>t.includes(i.toLowerCase())))!=null?n:null}function se(e){let t=e.toLowerCase();return/ipad|tablet|playbook|kindle|silk/.test(t)?"tablet":/mobi|iphone|ipod|android.*mobile|phone/.test(t)?"mobile":"desktop"}function ie(e,t){if(!e)return"direct";try{let n=new URL(e);if(t)try{if(new URL(t).host===n.host)return"direct"}catch(f){}let i=n.hostname.toLowerCase();return/(^|\.)(google|bing|duckduckgo|yahoo)\./.test(i)?"search":/(^|\.)(twitter\.com|x\.com|facebook\.com|linkedin\.com|reddit\.com|t\.co)$/.test(i)?"social":"referral"}catch(n){return"direct"}}function ae(e){if(!e)return null;try{return new URL(e).hostname}catch(t){return null}}function le(e){let t=e.getHours();return t<6?"night":t<12?"morning":t<18?"afternoon":"evening"}function Ne(e){let t=Et("__segment__",e);return`${t.deviceClass}:${t.trafficSource}`}function Et(e,t){var c,u,r,s,o,l,d;let n=(u=(c=t==null?void 0:t.userAgent)==null?void 0:c.trim())!=null?u:"",i=(s=(r=t==null?void 0:t.referer)==null?void 0:r.trim())!=null?s:"",f=(o=t==null?void 0:t.now)!=null?o:new Date;return{sessionId:e,ephemeral:!1,utmParams:(l=t==null?void 0:t.utmParams)!=null?l:{},deviceClass:n?se(n):"desktop",trafficSource:i?ie(i,t==null?void 0:t.appOrigin):"direct",referrerDomain:ae(i),timeOfDay:le(f),dayOfWeek:(d=["sun","mon","tue","wed","thu","fri","sat"][f.getDay()])!=null?d:"sun",automation:(t==null?void 0:t.webdriver)===!0||re(n)}}var V=require("@sentientui/policy");function ce(e){return v(v(v({id:e.id},e.arms?{arms:[...e.arms]}:{}),e.dims?{dims:Object.fromEntries(Object.entries(e.dims).map(([t,n])=>[t,[...n]]))}:{}),e.baseline!==void 0?{baseline:e.baseline}:{})}function H(e){let t=ce(e);return(0,V.slotResultFor)(t,(0,V.slotBaselineArm)(t))}function Ue(e){let t={};for(let n of e)t[n.id]=H(n);return t}function me(e){return typeof e=="string"?e:(0,V.canonicalArm)(e)}var J="_snt_snap:",xt=["low","medium","high"];function ye(e){try{let t=localStorage.getItem(J+e);if(!t)return null;let n=JSON.parse(t);return!n||typeof n!="object"||n.v!==1||typeof n.persona!="string"||typeof n.band!="string"||!xt.includes(n.band)||typeof n.slots!="object"||n.slots===null||Array.isArray(n.slots)||!(n.layoutOrder===null||Array.isArray(n.layoutOrder))||typeof n.savedAt!="number"||!(n.slotConfig===void 0||typeof n.slotConfig=="object"&&n.slotConfig!==null&&!Array.isArray(n.slotConfig))?null:n}catch(t){return null}}function z(e,t){try{localStorage.setItem(J+e,JSON.stringify(t))}catch(n){}}function Ke(e){return"(function(){try{var r=localStorage.getItem("+JSON.stringify(J+e).replace(/</g,"\\u003c")+');if(!r)return;var s=JSON.parse(r);if(!s||s.v!==1||typeof s.persona!=="string"||typeof s.band!=="string")return;var d=document.documentElement;if(d.hasAttribute("data-sentient-persona"))return;d.setAttribute("data-sentient-persona",s.persona);d.setAttribute("data-sentient-confidence",s.band);}catch(e){}})();'}var Re=require("@sentientui/policy");var he=require("@sentientui/policy");var ve="[sentient] No API key configured \u2014 nothing is being learned. Set NEXT_PUBLIC_SENTIENT_API_KEY or pass localMode: true for local development.",Ie="[sentient] Local mode \u2014 decisions are simulated on-device and nothing is sent over the network. Add an API key to learn from real traffic.",Ge=!1,Se=!1;function It(){var e;try{return(e=new URLSearchParams(window.location.search).get("sentient_persona"))!=null?e:void 0}catch(t){return}}function $e(e){var r;let t=pe({ssrSessionId:e.ssrSessionId,apiKey:e.apiKey}),n=(r=t.getSessionId())!=null?r:"local",i=It(),f=import("@sentientui/core/local").then(s=>{let o=s;return o.LOCAL_ENGINE_AVAILABLE?(Ge||(Ge=!0,console.info(Ie)),o):(Se||(Se=!0,console.error(ve)),null)}).catch(()=>(Se||(Se=!0,console.error(ve)),null)),c=null;function u(s){let o=document.documentElement;o.dataset.sentientPersona===void 0&&(o.dataset.sentientPersona=s.persona,o.dataset.sentientConfidence=(0,he.confidenceBand)(s.confidence))}return{isLocal:!0,async decide(s){var d,m,E;let o=await f;if(!o)return null;let l=o.createLocalEngine({sessionId:n,forcedPersona:i}).decide(s);return c=Q(v({},l),{layoutOrder:(m=(d=l.layoutOrder)!=null?d:c==null?void 0:c.layoutOrder)!=null?m:null,slots:v(v({},(E=c==null?void 0:c.slots)!=null?E:{}),l.slots)}),z(e.apiKey||"local",{v:1,persona:c.persona,band:(0,he.confidenceBand)(c.confidence),slots:c.slots,layoutOrder:c.layoutOrder,savedAt:Date.now()}),u(l),l},getSlotResult(s){var o,l,d;return(d=(l=c==null?void 0:c.slots[s])!=null?l:(o=e.initialSlots)==null?void 0:o[s])!=null?d:null},getPersona(){return c?{persona:c.persona,confidence:c.confidence,band:(0,he.confidenceBand)(c.confidence)}:null},async assign(s,o){var m;let l=await f;return!l||!o||o.length===0?o!=null&&o[0]?{variantId:o[0],assignmentTtlMs:0}:null:{variantId:(m=l.createLocalEngine({sessionId:n,forcedPersona:i}).decide({components:[{id:s,variantIds:o}]}).assignments[s])!=null?m:o[0],assignmentTtlMs:0}},track:()=>{},goal:()=>{},componentGoal:()=>{},identify:()=>{},getAssignment:()=>null,fetchWeights:()=>Promise.resolve([]),getGraph:()=>({pageNodes:[],capturedAt:0}),dispose:()=>{},destroy:()=>t.destroy()}}function Be(e,t,n,i){let f=[];{let r=!1,s=[],o=()=>{if(r)return;let l=Date.now();for(s.push(l);s.length>0&&l-s[0]>500;)s.shift();s.length>=3&&(r=!0,e("rage_click"))};t.addEventListener("click",o),f.push(()=>t.removeEventListener("click",o))}{let c=!1,u=r=>{if(c||!(r.target instanceof Node)||!t.contains(r.target)&&t!==r.target)return;c=!0;let s=typeof window!="undefined"?window.getSelection():null,o=s?s.toString().length:0;e("text_copy",{selectionLength:o})};document.addEventListener("copy",u),f.push(()=>document.removeEventListener("copy",u))}{let c=!1,u=!1,r=null,s=()=>{r!==null&&(clearTimeout(r),r=null)},o=()=>{c||!u||(s(),r=setTimeout(()=>{!c&&u&&(c=!0,e("scroll_hesitation"))},3e3))},l=()=>{s(),o()},d=E=>{for(let L of E)u=L.intersectionRatio>.3,u?o():s()},m=new IntersectionObserver(d,{threshold:[.3]});m.observe(t),window.addEventListener("scroll",l,{passive:!0}),f.push(()=>{m.disconnect(),window.removeEventListener("scroll",l),s()})}if((i==null?void 0:i.tabLoss)!==!1){let c=!1,u=n!=null?n:Date.now(),r=()=>{if(c||document.visibilityState!=="hidden")return;let s=Date.now()-u;s<15e3&&(c=!0,e("tab_loss",{timeOnPage:s}))};document.addEventListener("visibilitychange",r),f.push(()=>document.removeEventListener("visibilitychange",r))}return()=>{for(let c of f)c()}}var We="https://api.sentient-ui.com/v1/events",k=new Map,je=null;function Ce(){return ue()}var Y={track:()=>{},goal:()=>{},componentGoal:()=>{},identify:()=>{},getAssignment:()=>null,assign:()=>Promise.resolve(null),decide:()=>Promise.resolve(null),getSlotResult:()=>null,getPersona:()=>null,fetchWeights:()=>Promise.resolve([]),getGraph:()=>({pageNodes:[],capturedAt:0}),dispose:()=>{},destroy:()=>{}};function Ct(){try{let e={},t=new URLSearchParams(window.location.search);for(let[n,i]of t)n.startsWith("utm_")&&(e[n]=i);return e}catch(e){return{}}}function Fe(e){return e.replace(/\/events\/?$/,"")}function ke(){return typeof navigator!="undefined"&&navigator.globalPrivacyControl===!0?!0:[typeof navigator!="undefined"?navigator.doNotTrack:void 0,typeof window!="undefined"?window.doNotTrack:void 0,typeof navigator!="undefined"?navigator.msDoNotTrack:void 0].some(t=>t==="1"||t==="yes")}function Rt(e){var r;if(typeof window=="undefined")return;let t=e!=null?e:je;if(!t){console.warn("[sentient] grantConsent() called before init()");return}let n=k.get(t);if(!n){console.warn("[sentient] grantConsent() called before init()");return}let{config:i,upgrade:f}=n;if(!f||i.respectDoNotTrack!==!1&&ke())return;let c=Je(Q(v({},i),{consent:!0}));f(c);let u=(r=k.get(t))==null?void 0:r.dispose;k.set(t,{config:Q(v({},i),{consent:!0}),upgrade:null,dispose:u})}function kt(e){var u;let t=Fe((u=e.ingestUrl)!=null?u:We),n={"Content-Type":"application/json",Authorization:`Bearer ${e.apiKey}`},i={track:()=>{},goal:()=>{},componentGoal:()=>{},identify:()=>{},getAssignment:()=>null,fetchWeights:()=>Promise.resolve([]),async assign(r,s,o){try{let l=new URLSearchParams({componentId:r});for(let E of s!=null?s:[])l.append("variantIds[]",E);let d=await fetch(`${t}/winner?${l.toString()}`,{headers:n});return d.ok?{variantId:(await d.json()).variantId,assignmentTtlMs:0}:s!=null&&s[0]?{variantId:s[0],assignmentTtlMs:0}:null}catch(l){return s!=null&&s[0]?{variantId:s[0],assignmentTtlMs:0}:null}},decide:()=>Promise.resolve(null),getSlotResult:()=>null,getPersona:()=>null,getGraph:()=>({pageNodes:[],capturedAt:0}),dispose:()=>{},destroy:()=>{}},f={track:r=>i.track(r),goal:(r,s,o,l)=>i.goal(r,s,o,l),componentGoal:(r,s,o)=>i.componentGoal(r,s,o),identify:r=>i.identify(r),getAssignment:(r,s)=>i.getAssignment(r,s),assign:(r,s,o,l)=>i.assign(r,s,o,l),decide:r=>i.decide(r),getSlotResult:r=>i.getSlotResult(r),getPersona:()=>i.getPersona(),fetchWeights:()=>i.fetchWeights(),getGraph:()=>i.getGraph(),dispose:()=>i.dispose(),destroy:()=>i.destroy()};function c(r){i=r}return{proxy:f,setInner:c}}function Je(e){var q,X,Z,ee,p,y,N,T,K;if(typeof window=="undefined")return Y;je=e.apiKey;let t=k.get(e.apiKey||"local");if(t!=null&&t.dispose)try{t.dispose()}catch(a){}let n=e.respectDoNotTrack!==!1&&ke(),i=e.consent===!1||n,f=typeof e.apiKey=="string"&&e.apiKey.startsWith("pk_");if(e.localMode===!0||!f&&e.localMode!==!1)return i?(k.set(e.apiKey||"local",{config:e,upgrade:null}),Y):(k.set(e.apiKey||"local",{config:e,upgrade:null}),$e(e));if(i){if(e.preConsentBehavior==="statistical_winner"){if(!e.apiKey||!e.apiKey.startsWith("pk_"))return console.warn("[sentient] init() called with an invalid apiKey \u2014 expected a pk_ public key. SDK disabled."),Y;let{proxy:a,setInner:g}=kt(e);return k.set(e.apiKey,{config:e,upgrade:n?null:g}),a}return k.set(e.apiKey,{config:e,upgrade:null}),Y}if(!e.apiKey||!e.apiKey.startsWith("pk_"))return console.warn("[sentient] init() called with an invalid apiKey \u2014 expected a pk_ public key. SDK disabled."),Y;if(e.ingestUrl==="")return console.warn("[sentient] init() called with an empty ingestUrl. SDK disabled."),Y;let c=(q=e.ingestUrl)!=null?q:We,u=Date.now(),r=pe({ssrSessionId:e.ssrSessionId,apiKey:e.apiKey}),s=Me(void 0,e.apiKey),o=Le({ingestUrl:c,apiKey:e.apiKey}),l=Fe(c),d={"Content-Type":"application/json",Authorization:`Bearer ${e.apiKey}`},m=se((X=navigator.userAgent)!=null?X:""),E=typeof window!="undefined"?window.location.origin:void 0,L=ie((Z=document.referrer)!=null?Z:"",E),b=(ee=e.sessionSegment)!=null?ee:`${m}:${L}`,I=new Map,C=new Map,h=null,de=a=>{for(let g of a)C.has(g.id)||C.set(g.id,H(g))};if(e.initialSlots)for(let[a,g]of Object.entries(e.initialSlots))C.set(a,g);let B=ye(e.apiKey);if(B)for(let[a,g]of Object.entries(B.slots))C.has(a)||C.set(a,g);let M={low:.15,medium:.5,high:.85};if(e.initialPersona)h=v({},e.initialPersona);else{let a=document.documentElement.dataset;a.sentientPersona?h={persona:a.sentientPersona,confidence:(y=M[(p=a.sentientConfidence)!=null?p:"low"])!=null?y:.15}:B&&(h={persona:B.persona,confidence:(N=M[B.band])!=null?N:.15})}if(e.initialAssignments)for(let[a,g]of Object.entries(e.initialAssignments))s.set(a,b,{variantId:g,assignedAt:Date.now(),segment:b,confidence:1});let O=Promise.resolve(),W=r.getSessionId();if(W){let a=ae((T=document.referrer)!=null?T:""),g=v(v({sessionId:W,deviceClass:m,trafficSource:L,referrerDomain:a,utmParams:Ct(),timeOfDay:le(new Date),dayOfWeek:["sun","mon","tue","wed","thu","fri","sat"][new Date().getDay()],ephemeral:r.isEphemeral(),automation:typeof navigator!="undefined"&&navigator.webdriver===!0||re((K=navigator.userAgent)!=null?K:"")},e.userId?{userId:e.userId}:{}),e.country?{country:e.country}:{});try{O=fetch(`${l}/sessions`,{method:"POST",keepalive:!0,body:JSON.stringify(g),headers:d}).then(S=>{S.status===402&&console.warn("[SentientUI] Session limit exceeded for this project. The bandit will stop learning until the limit resets. Upgrade at sentient-ui.com/pricing")}).catch(()=>{})}catch(S){}}e.debug&&(console.log("[sentient] initialized",{context:e.context}),window.__sentient={client:null,queue:o});let U={goal(a,g={},S=1,P=0){let R=r.getSessionId();if(!R)return;let x=Ce();O.then(()=>{fetch(`${l}/goals`,{method:"POST",keepalive:!0,body:JSON.stringify({sessionId:R,name:a,metadata:g,weight:S,stepIndex:P,goalId:x}),headers:d}).catch(()=>{})})},componentGoal(a,g,S){var A,$,_;let P=r.getSessionId();if(!P)return;let R=s.get(a,b),x=R?null:(A=C.get(a))!=null?A:null;if(!R&&x===null){e.debug&&console.warn(`[sentient] componentGoal("${a}"): no assignment or slot decision yet \u2014 render its <Adaptive>/adaptive hook or call assign()/decide() before recording a goal.`);return}let j=R?R.variantId:me(x),G={id:Ce(),sessionId:P,projectId:e.apiKey,componentId:a,variantId:j,eventType:"goal_achieved",goalType:g,payload:v({reward:($=S==null?void 0:S.reward)!=null?$:1},(_=S==null?void 0:S.metadata)!=null?_:{}),timestamp:Date.now(),timeInSession:Date.now()-u};e.debug&&console.log("[sentient] componentGoal",G),O.then(()=>o.push(G))},identify(a){let g=r.getSessionId();g&&O.then(()=>{fetch(`${l}/sessions`,{method:"POST",keepalive:!0,body:JSON.stringify({sessionId:g,userId:a,ephemeral:r.isEphemeral()}),headers:d}).catch(()=>{})})},track(a){let g=r.getSessionId();if(!g)return;let S=Q(v({},a),{id:Ce(),sessionId:g,timestamp:Date.now(),timeInSession:Date.now()-u});e.debug&&console.log("[sentient] track",S),O.then(()=>o.push(S))},getAssignment(a,g){return s.get(a,g)},async assign(a,g,S,P){let R=r.getSessionId();if(!R)return null;let x=s.get(a,b);if(x&&(g!=null&&g.length||x.content!==void 0)){let A=x.ttlMs&&x.ttlMs>0?Math.max(0,x.assignedAt+x.ttlMs-Date.now()):0;return{variantId:x.variantId,assignmentTtlMs:A,content:x.content}}let j=I.get(a);if(j)return j;let G=(async()=>{await O;try{let A={sessionId:R,componentId:a,variantIds:g};P!==void 0?A.agentDataByVariant=P:S!==void 0&&(A.agentData=S);let $=await fetch(`${l}/assign`,{method:"POST",body:JSON.stringify(A),headers:d});if(!$.ok)return null;let _=await $.json();return s.set(a,b,v({variantId:_.variantId,assignedAt:Date.now(),segment:b,confidence:1,content:_.content},_.assignmentTtlMs&&_.assignmentTtlMs>0?{ttlMs:_.assignmentTtlMs}:{})),_}catch(A){return null}finally{I.delete(a)}})();return I.set(a,G),G},async decide(a){var P,R,x,j,G,A,$,_,Ae;let g=r.getSessionId();if(!g)return null;let S=(P=a.slots)!=null?P:[];await O;try{let F={sessionId:g};a.sections&&a.sections.length>0&&(F.sections=a.sections.map(D=>({id:D}))),F.components=(R=a.components)!=null?R:[],S.length>0&&(F.slots=S.map(ce)),a.slotsFrom==="registry"&&(F.slotsFrom="registry"),a.v&&(F.v=a.v);let _e=await fetch(`${l}/decide`,{method:"POST",body:JSON.stringify(F),headers:d});if(!_e.ok)return de(S),null;let w=await _e.json(),te={};for(let D of S)te[D.id]=(j=(x=w.slots)==null?void 0:x[D.id])!=null?j:H(D);if(w.slots)for(let[D,ne]of Object.entries(w.slots))D in te||(te[D]=ne);for(let[D,ne]of Object.entries(te))C.set(D,ne);let Qe=h!=null&&h.persona!=="unknown";w.persona&&!(w.persona==="unknown"&&Qe)?h={persona:w.persona,confidence:(G=w.confidence)!=null?G:0}:h||(h={persona:"unknown",confidence:0});for(let[D,ne]of Object.entries((A=w.assignments)!=null?A:{}))s.set(D,b,{variantId:ne,assignedAt:Date.now(),segment:b,confidence:1});return z(e.apiKey,v({v:1,persona:h.persona,band:(0,Re.confidenceBand)(h.confidence),slots:Object.fromEntries(C),layoutOrder:($=w.layoutOrder)!=null?$:null,savedAt:Date.now()},w.slotConfig?{slotConfig:w.slotConfig}:{})),v(v(v({layoutOrder:(_=w.layoutOrder)!=null?_:null,assignments:(Ae=w.assignments)!=null?Ae:{},slots:te,persona:h.persona,confidence:h.confidence},w.slotConfig?{slotConfig:w.slotConfig}:{}),w.goals?{goals:w.goals}:{}),w.sectionMap?{sectionMap:w.sectionMap}:{})}catch(F){return de(S),null}},getSlotResult(a){var g;return(g=C.get(a))!=null?g:null},getPersona(){return h?{persona:h.persona,confidence:h.confidence,band:(0,Re.confidenceBand)(h.confidence)}:null},async fetchWeights(){var a;try{let g=await fetch(`${l}/weights`,{headers:d});return g.ok?(a=(await g.json()).components)!=null?a:[]:[]}catch(g){return[]}},getGraph(){return{pageNodes:[],capturedAt:0}},dispose(){var a;o.destroy(),((a=k.get(e.apiKey))==null?void 0:a.dispose)===U.dispose&&k.delete(e.apiKey),e.debug&&console.log("[sentient] disposed")},destroy(){var a;o.destroy(),r.destroy(),((a=k.get(e.apiKey))==null?void 0:a.dispose)===U.dispose&&k.delete(e.apiKey);try{localStorage.removeItem(J+e.apiKey),localStorage.removeItem(be(e.apiKey))}catch(g){}e.debug&&console.log("[sentient] destroyed")}};if(k.set(e.apiKey,{config:e,upgrade:null,dispose:U.dispose}),e.debug){let a=window;a.__sentient&&(a.__sentient.client=U)}return U}0&&(module.exports={LOCAL_MODE_BANNER,PROD_KEYLESS_ERROR,SNAPSHOT_STORAGE_KEY_PREFIX,agentUaList,armOfResult,attachMicroSignalDetectors,baselineResultFor,baselineSlots,deriveSessionSegment,detectDeviceClass,detectTimeOfDay,detectTrafficSource,grantConsent,init,isDoNotTrackEnabled,matchedAgentToken,readSnapshot,referrerDomainFromReferer,renderPrePaintScript,toWireSlot,uaTokenMatch,writeSnapshot});
1
+ "use strict";var Ye=Object.create;var ne=Object.defineProperty,qe=Object.defineProperties,Xe=Object.getOwnPropertyDescriptor,Ze=Object.getOwnPropertyDescriptors,et=Object.getOwnPropertyNames,Oe=Object.getOwnPropertySymbols,tt=Object.getPrototypeOf,Pe=Object.prototype.hasOwnProperty,nt=Object.prototype.propertyIsEnumerable;var Te=(e,t,n)=>t in e?ne(e,t,{enumerable:!0,configurable:!0,writable:!0,value:n}):e[t]=n,v=(e,t)=>{for(var n in t||(t={}))Pe.call(t,n)&&Te(e,n,t[n]);if(Oe)for(var n of Oe(t))nt.call(t,n)&&Te(e,n,t[n]);return e},Q=(e,t)=>qe(e,Ze(t));var ot=(e,t)=>{for(var n in t)ne(e,n,{get:t[n],enumerable:!0})},Le=(e,t,n,c)=>{if(t&&typeof t=="object"||typeof t=="function")for(let u of et(t))!Pe.call(e,u)&&u!==n&&ne(e,u,{get:()=>t[u],enumerable:!(c=Xe(t,u))||c.enumerable});return e};var rt=(e,t,n)=>(n=e!=null?Ye(tt(e)):{},Le(t||!e||!e.__esModule?ne(n,"default",{value:e,enumerable:!0}):n,e)),st=e=>Le(ne({},"__esModule",{value:!0}),e);var Ot={};ot(Ot,{AGENT_INTENTS:()=>ye,LOCAL_MODE_BANNER:()=>Ce,PROD_KEYLESS_ERROR:()=>be,SNAPSHOT_STORAGE_KEY_PREFIX:()=>J,agentIntent:()=>Ue,agentUaList:()=>oe,armOfResult:()=>Se,attachMicroSignalDetectors:()=>Fe,baselineResultFor:()=>z,baselineSlots:()=>Ge,classifiedAgents:()=>Ke,deriveSessionSegment:()=>Be,detectDeviceClass:()=>se,detectTimeOfDay:()=>le,detectTrafficSource:()=>ie,grantConsent:()=>_t,init:()=>ze,isDoNotTrackEnabled:()=>ke,matchedAgentToken:()=>Ie,readSnapshot:()=>he,referrerDomainFromReferer:()=>ae,renderPrePaintScript:()=>$e,toWireSlot:()=>ce,uaTokenMatch:()=>re,writeSnapshot:()=>H});module.exports=st(Ot);function ge(){try{if(typeof crypto!="undefined"&&typeof crypto.randomUUID=="function")return crypto.randomUUID()}catch(e){}try{if(typeof crypto!="undefined"&&typeof crypto.getRandomValues=="function"){let e=new Uint8Array(16);crypto.getRandomValues(e),e[6]=e[6]&15|64,e[8]=e[8]&63|128;let t="";for(let n=0;n<16;n++)t+=e[n].toString(16).padStart(2,"0"),(n===3||n===5||n===7||n===9)&&(t+="-");return t}}catch(e){}return"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,e=>{let t=Math.random()*16|0;return(e==="x"?t:t&3|8).toString(16)})}function pe(e){return e?`_${e.slice(0,12)}`:""}var it="_snt_uid",at=365,lt="_snt_uid";function ct(){return ge()}function dt(e){try{let t=document.cookie.match(new RegExp(`(?:^|; )${e}=([^;]*)`));return t?decodeURIComponent(t[1]):null}catch(t){return null}}function ut(e,t,n){try{document.cookie=`${e}=${encodeURIComponent(t)}; max-age=${n}; SameSite=strict; path=/`}catch(c){}}function gt(e){try{return localStorage.getItem(e)}catch(t){return null}}function pt(e,t){try{return localStorage.setItem(e,t),!0}catch(n){return!1}}function ft(e){try{return sessionStorage.getItem(e)}catch(t){return null}}function mt(e,t){try{return sessionStorage.setItem(e,t),!0}catch(n){return!1}}function yt(e){try{sessionStorage.removeItem(e)}catch(t){}}function St(e){try{return document.cookie=`${e}_probe=1; max-age=1; SameSite=strict; path=/`,document.cookie.indexOf(`${e}_probe=1`)!==-1}catch(t){return!1}}function ht(e){try{localStorage.removeItem(e)}catch(t){}}function vt(e){try{document.cookie=`${e}=; max-age=0; SameSite=strict; path=/`}catch(t){}}var wt={getSessionId:()=>null,isEphemeral:()=>!1,destroy:()=>{}};function fe(e){var m,x,O,b,I,C;if(typeof window=="undefined")return wt;let t=pe(e==null?void 0:e.apiKey),n=(m=e==null?void 0:e.cookieName)!=null?m:`${it}${t}`,c=`${lt}${t}`,d=((x=e==null?void 0:e.cookieTTLDays)!=null?x:at)*24*60*60,g=h=>h&&h.length>0?h:null,l=(C=(I=(b=(O=g(dt(n)))!=null?O:g(gt(c)))!=null?b:g(ft(c)))!=null?I:g(e==null?void 0:e.ssrSessionId))!=null?C:ct();ut(n,l,d);let r=pt(c,l),o=St(n),i=r?!1:mt(c,l),a=!r&&!o&&!i;return{getSessionId:()=>l,isEphemeral:()=>a,destroy:()=>{l=null,vt(n),ht(c),yt(c)}}}function Ee(e){return`_snt_retry_${e.slice(0,12)}`}var bt={push:()=>{},flush:()=>{},destroy:()=>{}};function xt(e,t){try{let n=localStorage.getItem(t);if(!n)return[];let c=JSON.parse(n);return Array.isArray(c)?(localStorage.removeItem(t),c.slice(-e)):[]}catch(n){return[]}}function xe(e,t,n){try{let c=(()=>{try{let g=localStorage.getItem(n);if(!g)return[];let l=JSON.parse(g);return Array.isArray(l)?l:[]}catch(g){return[]}})(),u=new Map;for(let g of c)u.set(g.id,g);for(let g of e)u.set(g.id,g);let d=[...u.values()].slice(-t);localStorage.setItem(n,JSON.stringify(d))}catch(c){}}function Et(e,t){try{let n=localStorage.getItem(t);if(!n)return;let c=JSON.parse(n);if(!Array.isArray(c))return;let u=new Set(e),d=c.filter(g=>!u.has(g.id));if(d.length===c.length)return;d.length===0?localStorage.removeItem(t):localStorage.setItem(t,JSON.stringify(d))}catch(n){}}function Me(e){var q,X,Z;if(typeof window=="undefined")return bt;let t=(q=e.flushIntervalMs)!=null?q:5e3,n=(X=e.maxBatchSize)!=null?X:20,c=(Z=e.maxRetrySize)!=null?Z:100,u=e.ingestUrl,d=e.apiKey,g=Ee(d),l=[],r=new Set,o=[],i=f=>{for(let y of f)a.delete(y),!r.has(y)&&(r.add(y),o.push(y));for(;o.length>500;){let y=o.shift();y&&r.delete(y)}Et(f,g)},a=new Set,m=f=>{r.has(f.id)||a.has(f.id)||(a.add(f.id),l.push(f))},x=f=>{for(let y of f)r.has(y.id)||(a.add(y.id),l.push(y))},O=xt(c,g);for(let f of O)m(f);let b=0,I=0,C=f=>{if(f.length===0)return;let y=JSON.stringify(f),N=f.map(s=>s.id),P;try{P=fetch(u,{method:"POST",keepalive:!0,body:y,headers:{"Content-Type":"application/json",Authorization:`Bearer ${d}`}})}catch(s){xe(f,c,g),x(f),I++,b=Date.now()+Math.min(6e4,1e3*2**Math.min(I,6));return}let K=s=>{if(s.ok||s.status>=400&&s.status<500&&s.status!==429){i(N),I=0,b=0;return}xe(f,c,g),x(f),I++,b=Date.now()+Math.min(6e4,1e3*2**Math.min(I,6))};P instanceof Promise?P.then(K).catch(()=>{xe(f,c,g),x(f),I++,b=Date.now()+Math.min(6e4,1e3*2**Math.min(I,6))}):K(P)},h=typeof TextEncoder!="undefined"?new TextEncoder:null,ue=f=>h?h.encode(f).length:f.length,$=f=>{let y=[],N=2;for(let P of f){let K=ue(JSON.stringify(P))+1;if(y.length>0&&N+K>57344||y.length>=n)break;y.push(P),N+=K}return y},M=()=>{try{if(Date.now()<b)return;for(;l.length>0&&!(Date.now()<b);){let f=l.filter(N=>!r.has(N.id));if(l.length=0,f.length===0)break;let y=$(f);if(y.length===0)break;y.length<f.length&&l.push(...f.slice(y.length)),C(y)}}catch(f){}},T=!0,W=null;W=setInterval(()=>{T&&M()},t);let U=()=>{document.visibilityState==="hidden"&&M()},Y=()=>{M()};return document.addEventListener("visibilitychange",U),window.addEventListener("pagehide",Y),{push(f){m(f),l.length>=n&&M()},flush:M,destroy(){T=!1,W!==null&&(clearInterval(W),W=null),document.removeEventListener("visibilitychange",U),window.removeEventListener("pagehide",Y),M()}}}var It=1800*1e3;function me(e,t){return`${encodeURIComponent(e)}:${encodeURIComponent(t)}`}function Ne(e=It,t){let n=new Map,c=`_snt_asgn${pe(t)}_`,u=(o,i)=>`${c}${encodeURIComponent(o)}:${encodeURIComponent(i)}`,d=o=>{let i=o.slice(c.length),a=i.indexOf(":");if(a<0)return null;try{return{componentId:decodeURIComponent(i.slice(0,a)),segment:decodeURIComponent(i.slice(a+1))}}catch(m){return null}},g=()=>{try{let o=[];for(let i=0;i<localStorage.length;i++){let a=localStorage.key(i);a!=null&&a.startsWith(c)&&o.push(a)}return o}catch(o){return[]}},l=o=>o.assignedAt+(o.ttlMs&&o.ttlMs>0?o.ttlMs:e)<Date.now();return typeof window!="undefined"&&(()=>{for(let o of g())try{let i=localStorage.getItem(o);if(!i)continue;let a=JSON.parse(i);if(l(a)){localStorage.removeItem(o);continue}let m=d(o);if(!m)continue;n.set(me(m.componentId,m.segment),a)}catch(i){}})(),{get(o,i){let a=n.get(me(o,i));return a?l(a)?(n.delete(me(o,i)),null):a:null},set(o,i,a){let m=me(o,i);n.set(m,a);try{localStorage.setItem(u(o,i),JSON.stringify(a))}catch(x){}},invalidate(o){let i=`${encodeURIComponent(o)}:`;for(let a of[...n.keys()])a.startsWith(i)&&n.delete(a);for(let a of g()){let m=d(a);if((m==null?void 0:m.componentId)===o)try{localStorage.removeItem(a)}catch(x){}}},clear(){n.clear();for(let o of g())try{localStorage.removeItem(o)}catch(i){}}}}var oe=["GPTBot","ChatGPT-User","OAI-SearchBot","ClaudeBot","Claude-User","Claude-SearchBot","PerplexityBot","Perplexity-User","Google-Extended","Applebot-Extended","Meta-ExternalAgent","Bytespider","CCBot","Amazonbot","cohere-ai","Diffbot"];function re(e){return Ie(e)!==null}function Ie(e){var n;if(!e)return null;let t=e.toLowerCase();return(n=oe.find(c=>t.includes(c.toLowerCase())))!=null?n:null}var ye={GPTBot:"training","ChatGPT-User":"user","OAI-SearchBot":"search",ClaudeBot:"training","Claude-User":"user","Claude-SearchBot":"search",PerplexityBot:"search","Perplexity-User":"user","Google-Extended":"training","Applebot-Extended":"training","Meta-ExternalAgent":"training",Bytespider:"training",CCBot:"training",Amazonbot:"other","cohere-ai":"training",Diffbot:"other"};function Ue(e){if(!e)return"other";let t=oe.find(n=>n.toLowerCase()===e.toLowerCase());return t&&ye[t]||"other"}function Ke(){var t;let e={user:[],search:[],training:[],other:[]};for(let n of oe)e[(t=ye[n])!=null?t:"other"].push(n);return e}function se(e){let t=e.toLowerCase();return/ipad|tablet|playbook|kindle|silk/.test(t)?"tablet":/mobi|iphone|ipod|android.*mobile|phone/.test(t)?"mobile":"desktop"}function ie(e,t){if(!e)return"direct";try{let n=new URL(e);if(t)try{if(new URL(t).host===n.host)return"direct"}catch(u){}let c=n.hostname.toLowerCase();return/(^|\.)(google|bing|duckduckgo|yahoo)\./.test(c)?"search":/(^|\.)(twitter\.com|x\.com|facebook\.com|linkedin\.com|reddit\.com|t\.co)$/.test(c)?"social":"referral"}catch(n){return"direct"}}function ae(e){if(!e)return null;try{return new URL(e).hostname}catch(t){return null}}function le(e){let t=e.getHours();return t<6?"night":t<12?"morning":t<18?"afternoon":"evening"}function Be(e){let t=Ct("__segment__",e);return`${t.deviceClass}:${t.trafficSource}`}function Ct(e,t){var d,g,l,r,o,i,a;let n=(g=(d=t==null?void 0:t.userAgent)==null?void 0:d.trim())!=null?g:"",c=(r=(l=t==null?void 0:t.referer)==null?void 0:l.trim())!=null?r:"",u=(o=t==null?void 0:t.now)!=null?o:new Date;return{sessionId:e,ephemeral:!1,utmParams:(i=t==null?void 0:t.utmParams)!=null?i:{},deviceClass:n?se(n):"desktop",trafficSource:c?ie(c,t==null?void 0:t.appOrigin):"direct",referrerDomain:ae(c),timeOfDay:le(u),dayOfWeek:(a=["sun","mon","tue","wed","thu","fri","sat"][u.getDay()])!=null?a:"sun",automation:(t==null?void 0:t.webdriver)===!0||re(n)}}var V=require("@sentientui/policy");function ce(e){return v(v(v({id:e.id},e.arms?{arms:[...e.arms]}:{}),e.dims?{dims:Object.fromEntries(Object.entries(e.dims).map(([t,n])=>[t,[...n]]))}:{}),e.baseline!==void 0?{baseline:e.baseline}:{})}function z(e){let t=ce(e);return(0,V.slotResultFor)(t,(0,V.slotBaselineArm)(t))}function Ge(e){let t={};for(let n of e)t[n.id]=z(n);return t}function Se(e){return typeof e=="string"?e:(0,V.canonicalArm)(e)}var J="_snt_snap:",At=["low","medium","high"];function he(e){try{let t=localStorage.getItem(J+e);if(!t)return null;let n=JSON.parse(t);return!n||typeof n!="object"||n.v!==1||typeof n.persona!="string"||typeof n.band!="string"||!At.includes(n.band)||typeof n.slots!="object"||n.slots===null||Array.isArray(n.slots)||!(n.layoutOrder===null||Array.isArray(n.layoutOrder))||typeof n.savedAt!="number"||!(n.slotConfig===void 0||typeof n.slotConfig=="object"&&n.slotConfig!==null&&!Array.isArray(n.slotConfig))?null:n}catch(t){return null}}function H(e,t){try{localStorage.setItem(J+e,JSON.stringify(t))}catch(n){}}function $e(e){return"(function(){try{var r=localStorage.getItem("+JSON.stringify(J+e).replace(/</g,"\\u003c")+');if(!r)return;var s=JSON.parse(r);if(!s||s.v!==1||typeof s.persona!=="string"||typeof s.band!=="string")return;var d=document.documentElement;if(d.hasAttribute("data-sentient-persona"))return;d.setAttribute("data-sentient-persona",s.persona);d.setAttribute("data-sentient-confidence",s.band);}catch(e){}})();'}var Re=require("@sentientui/policy");var we=require("@sentientui/policy");var be="[sentient] No API key configured \u2014 nothing is being learned. Set NEXT_PUBLIC_SENTIENT_API_KEY or pass localMode: true for local development.",Ce="[sentient] Local mode \u2014 decisions are simulated on-device and nothing is sent over the network. Add an API key to learn from real traffic.",We=!1,ve=!1;function Rt(){var e;try{return(e=new URLSearchParams(window.location.search).get("sentient_persona"))!=null?e:void 0}catch(t){return}}function je(e){var l;let t=fe({ssrSessionId:e.ssrSessionId,apiKey:e.apiKey}),n=(l=t.getSessionId())!=null?l:"local",c=Rt(),u=import("@sentientui/core/local").then(r=>{let o=r;return o.LOCAL_ENGINE_AVAILABLE?(We||(We=!0,console.info(Ce)),o):(ve||(ve=!0,console.error(be)),null)}).catch(()=>(ve||(ve=!0,console.error(be)),null)),d=null;function g(r){let o=document.documentElement;o.dataset.sentientPersona===void 0&&(o.dataset.sentientPersona=r.persona,o.dataset.sentientConfidence=(0,we.confidenceBand)(r.confidence))}return{isLocal:!0,async decide(r){var a,m,x;let o=await u;if(!o)return null;let i=o.createLocalEngine({sessionId:n,forcedPersona:c}).decide(r);return d=Q(v({},i),{layoutOrder:(m=(a=i.layoutOrder)!=null?a:d==null?void 0:d.layoutOrder)!=null?m:null,slots:v(v({},(x=d==null?void 0:d.slots)!=null?x:{}),i.slots)}),H(e.apiKey||"local",{v:1,persona:d.persona,band:(0,we.confidenceBand)(d.confidence),slots:d.slots,layoutOrder:d.layoutOrder,savedAt:Date.now()}),g(i),i},getSlotResult(r){var o,i,a;return(a=(i=d==null?void 0:d.slots[r])!=null?i:(o=e.initialSlots)==null?void 0:o[r])!=null?a:null},getPersona(){return d?{persona:d.persona,confidence:d.confidence,band:(0,we.confidenceBand)(d.confidence)}:null},async assign(r,o){var m;let i=await u;return!i||!o||o.length===0?o!=null&&o[0]?{variantId:o[0],assignmentTtlMs:0}:null:{variantId:(m=i.createLocalEngine({sessionId:n,forcedPersona:c}).decide({components:[{id:r,variantIds:o}]}).assignments[r])!=null?m:o[0],assignmentTtlMs:0}},track:()=>{},goal:()=>{},componentGoal:()=>{},identify:()=>{},getAssignment:()=>null,fetchWeights:()=>Promise.resolve([]),getGraph:()=>({pageNodes:[],capturedAt:0}),dispose:()=>{},destroy:()=>t.destroy()}}function Fe(e,t,n,c){let u=[];{let l=!1,r=[],o=()=>{if(l)return;let i=Date.now();for(r.push(i);r.length>0&&i-r[0]>500;)r.shift();r.length>=3&&(l=!0,e("rage_click"))};t.addEventListener("click",o),u.push(()=>t.removeEventListener("click",o))}{let d=!1,g=l=>{if(d||!(l.target instanceof Node)||!t.contains(l.target)&&t!==l.target)return;d=!0;let r=typeof window!="undefined"?window.getSelection():null,o=r?r.toString().length:0;e("text_copy",{selectionLength:o})};document.addEventListener("copy",g),u.push(()=>document.removeEventListener("copy",g))}{let d=!1,g=!1,l=null,r=()=>{l!==null&&(clearTimeout(l),l=null)},o=()=>{d||!g||(r(),l=setTimeout(()=>{!d&&g&&(d=!0,e("scroll_hesitation"))},3e3))},i=()=>{r(),o()},a=x=>{for(let O of x)g=O.intersectionRatio>.3,g?o():r()},m=new IntersectionObserver(a,{threshold:[.3]});m.observe(t),window.addEventListener("scroll",i,{passive:!0}),u.push(()=>{m.disconnect(),window.removeEventListener("scroll",i),r()})}if((c==null?void 0:c.tabLoss)!==!1){let d=!1,g=n!=null?n:Date.now(),l=()=>{if(d||document.visibilityState!=="hidden")return;let r=Date.now()-g;r<15e3&&(d=!0,e("tab_loss",{timeOnPage:r}))};document.addEventListener("visibilitychange",l),u.push(()=>document.removeEventListener("visibilitychange",l))}return()=>{for(let d of u)d()}}var Je="https://api.sentient-ui.com/v1/events",R=new Map,Qe=null;function Ae(){return ge()}var de={track:()=>{},goal:()=>{},componentGoal:()=>{},identify:()=>{},getAssignment:()=>null,assign:()=>Promise.resolve(null),decide:()=>Promise.resolve(null),getSlotResult:()=>null,getPersona:()=>null,fetchWeights:()=>Promise.resolve([]),getGraph:()=>({pageNodes:[],capturedAt:0}),dispose:()=>{},destroy:()=>{}};function kt(){try{let e={},t=new URLSearchParams(window.location.search);for(let[n,c]of t)n.startsWith("utm_")&&(e[n]=c);return e}catch(e){return{}}}function Ve(e){return e.replace(/\/events\/?$/,"")}function ke(){return typeof navigator!="undefined"&&navigator.globalPrivacyControl===!0?!0:[typeof navigator!="undefined"?navigator.doNotTrack:void 0,typeof window!="undefined"?window.doNotTrack:void 0,typeof navigator!="undefined"?navigator.msDoNotTrack:void 0].some(t=>t==="1"||t==="yes")}function _t(e){var l;if(typeof window=="undefined")return;let t=e!=null?e:Qe;if(!t){console.warn("[sentient] grantConsent() called before init()");return}let n=R.get(t);if(!n){console.warn("[sentient] grantConsent() called before init()");return}let{config:c,upgrade:u}=n;if(!u||c.respectDoNotTrack!==!1&&ke())return;let d=ze(Q(v({},c),{consent:!0}));u(d);let g=(l=R.get(t))==null?void 0:l.dispose;R.set(t,{config:Q(v({},c),{consent:!0}),upgrade:null,dispose:g})}function Dt(e){var l;let t=e.preConsentBehavior==="statistical_winner",n=Ve((l=e.ingestUrl)!=null?l:Je),c={"Content-Type":"application/json",Authorization:`Bearer ${e.apiKey}`},u={track:()=>{},goal:()=>{},componentGoal:()=>{},identify:()=>{},getAssignment:()=>null,fetchWeights:()=>Promise.resolve([]),async assign(r,o,i){if(!t)return null;try{let a=new URLSearchParams({componentId:r});for(let O of o!=null?o:[])a.append("variantIds[]",O);let m=await fetch(`${n}/winner?${a.toString()}`,{headers:c});return m.ok?{variantId:(await m.json()).variantId,assignmentTtlMs:0}:o!=null&&o[0]?{variantId:o[0],assignmentTtlMs:0}:null}catch(a){return o!=null&&o[0]?{variantId:o[0],assignmentTtlMs:0}:null}},decide:()=>Promise.resolve(null),getSlotResult:()=>null,getPersona:()=>null,getGraph:()=>({pageNodes:[],capturedAt:0}),dispose:()=>{},destroy:()=>{}},d={track:r=>u.track(r),goal:(r,o,i,a)=>u.goal(r,o,i,a),componentGoal:(r,o,i)=>u.componentGoal(r,o,i),identify:r=>u.identify(r),getAssignment:(r,o)=>u.getAssignment(r,o),assign:(r,o,i,a)=>u.assign(r,o,i,a),decide:r=>u.decide(r),getSlotResult:r=>u.getSlotResult(r),getPersona:()=>u.getPersona(),fetchWeights:()=>u.fetchWeights(),getGraph:()=>u.getGraph(),dispose:()=>u.dispose(),destroy:()=>u.destroy()};function g(r){u=r}return{proxy:d,setInner:g}}function ze(e){var Y,q,X,Z,f,y,N,P,K;if(typeof window=="undefined")return de;Qe=e.apiKey;let t=R.get(e.apiKey||"local");if(t!=null&&t.dispose)try{t.dispose()}catch(s){}let n=e.respectDoNotTrack!==!1&&ke(),c=e.consent===!1||n,u=typeof e.apiKey=="string"&&e.apiKey.startsWith("pk_");if(e.localMode===!0||!u&&e.localMode!==!1)return c?(R.set(e.apiKey||"local",{config:e,upgrade:null}),de):(R.set(e.apiKey||"local",{config:e,upgrade:null}),je(e));if(c){if(!e.apiKey||!e.apiKey.startsWith("pk_"))return e.preConsentBehavior==="statistical_winner"&&console.warn("[sentient] init() called with an invalid apiKey \u2014 expected a pk_ public key. SDK disabled."),R.set(e.apiKey,{config:e,upgrade:null}),de;let{proxy:s,setInner:p}=Dt(e);return R.set(e.apiKey,{config:e,upgrade:n?null:p}),s}if(!e.apiKey||!e.apiKey.startsWith("pk_"))return console.warn("[sentient] init() called with an invalid apiKey \u2014 expected a pk_ public key. SDK disabled."),de;if(e.ingestUrl==="")return console.warn("[sentient] init() called with an empty ingestUrl. SDK disabled."),de;let d=(Y=e.ingestUrl)!=null?Y:Je,g=Date.now(),l=fe({ssrSessionId:e.ssrSessionId,apiKey:e.apiKey}),r=Ne(void 0,e.apiKey),o=Me({ingestUrl:d,apiKey:e.apiKey}),i=Ve(d),a={"Content-Type":"application/json",Authorization:`Bearer ${e.apiKey}`},m=se((q=navigator.userAgent)!=null?q:""),x=typeof window!="undefined"?window.location.origin:void 0,O=ie((X=document.referrer)!=null?X:"",x),b=(Z=e.sessionSegment)!=null?Z:`${m}:${O}`,I=new Map,C=new Map,h=null,ue=s=>{for(let p of s)C.has(p.id)||C.set(p.id,z(p))};if(e.initialSlots)for(let[s,p]of Object.entries(e.initialSlots))C.set(s,p);let $=he(e.apiKey);if($)for(let[s,p]of Object.entries($.slots))C.has(s)||C.set(s,p);let M={low:.15,medium:.5,high:.85};if(e.initialPersona)h=v({},e.initialPersona);else{let s=document.documentElement.dataset;s.sentientPersona?h={persona:s.sentientPersona,confidence:(y=M[(f=s.sentientConfidence)!=null?f:"low"])!=null?y:.15}:$&&(h={persona:$.persona,confidence:(N=M[$.band])!=null?N:.15})}if(e.initialAssignments)for(let[s,p]of Object.entries(e.initialAssignments))r.set(s,b,{variantId:p,assignedAt:Date.now(),segment:b,confidence:1});let T=Promise.resolve(),W=l.getSessionId();if(W){let s=ae((P=document.referrer)!=null?P:""),p=v(v({sessionId:W,deviceClass:m,trafficSource:O,referrerDomain:s,utmParams:kt(),timeOfDay:le(new Date),dayOfWeek:["sun","mon","tue","wed","thu","fri","sat"][new Date().getDay()],ephemeral:l.isEphemeral(),automation:typeof navigator!="undefined"&&navigator.webdriver===!0||re((K=navigator.userAgent)!=null?K:"")},e.userId?{userId:e.userId}:{}),e.country?{country:e.country}:{});try{T=fetch(`${i}/sessions`,{method:"POST",keepalive:!0,body:JSON.stringify(p),headers:a}).then(S=>{S.status===402&&console.warn("[SentientUI] Session limit exceeded for this project. The bandit will stop learning until the limit resets. Upgrade at sentient-ui.com/pricing")}).catch(()=>{})}catch(S){}}e.debug&&(console.log("[sentient] initialized",{context:e.context}),window.__sentient={client:null,queue:o});let U={goal(s,p={},S=1,L=0){let A=l.getSessionId();if(!A)return;let E=Ae();T.then(()=>{fetch(`${i}/goals`,{method:"POST",keepalive:!0,body:JSON.stringify({sessionId:A,name:s,metadata:p,weight:S,stepIndex:L,goalId:E}),headers:a}).catch(()=>{})})},componentGoal(s,p,S){var k,G,_;let L=l.getSessionId();if(!L)return;let A=r.get(s,b),E=A?null:(k=C.get(s))!=null?k:null;if(!A&&E===null){e.debug&&console.warn(`[sentient] componentGoal("${s}"): no assignment or slot decision yet \u2014 render its <Adaptive>/adaptive hook or call assign()/decide() before recording a goal.`);return}let j=A?A.variantId:Se(E),B={id:Ae(),sessionId:L,projectId:e.apiKey,componentId:s,variantId:j,eventType:"goal_achieved",goalType:p,payload:v({reward:(G=S==null?void 0:S.reward)!=null?G:1},(_=S==null?void 0:S.metadata)!=null?_:{}),timestamp:Date.now(),timeInSession:Date.now()-g};e.debug&&console.log("[sentient] componentGoal",B),T.then(()=>o.push(B))},identify(s){let p=l.getSessionId();p&&T.then(()=>{fetch(`${i}/sessions`,{method:"POST",keepalive:!0,body:JSON.stringify({sessionId:p,userId:s,ephemeral:l.isEphemeral()}),headers:a}).catch(()=>{})})},track(s){let p=l.getSessionId();if(!p)return;let S=Q(v({},s),{id:Ae(),sessionId:p,timestamp:Date.now(),timeInSession:Date.now()-g});e.debug&&console.log("[sentient] track",S),T.then(()=>o.push(S))},getAssignment(s,p){return r.get(s,p)},async assign(s,p,S,L){let A=l.getSessionId();if(!A)return null;let E=r.get(s,b);if(E&&(p!=null&&p.length||E.content!==void 0)){let k=E.ttlMs&&E.ttlMs>0?Math.max(0,E.assignedAt+E.ttlMs-Date.now()):0;return{variantId:E.variantId,assignmentTtlMs:k,content:E.content}}let j=I.get(s);if(j)return j;let B=(async()=>{await T;try{let k={sessionId:A,componentId:s,variantIds:p};L!==void 0?k.agentDataByVariant=L:S!==void 0&&(k.agentData=S);let G=await fetch(`${i}/assign`,{method:"POST",body:JSON.stringify(k),headers:a});if(!G.ok)return null;let _=await G.json();return r.set(s,b,v({variantId:_.variantId,assignedAt:Date.now(),segment:b,confidence:1,content:_.content},_.assignmentTtlMs&&_.assignmentTtlMs>0?{ttlMs:_.assignmentTtlMs}:{})),_}catch(k){return null}finally{I.delete(s)}})();return I.set(s,B),B},async decide(s){var L,A,E,j,B,k,G,_,_e;let p=l.getSessionId();if(!p)return null;let S=(L=s.slots)!=null?L:[];await T;try{let F={sessionId:p};s.sections&&s.sections.length>0&&(F.sections=s.sections.map(D=>({id:D}))),F.components=(A=s.components)!=null?A:[],S.length>0&&(F.slots=S.map(ce)),s.slotsFrom==="registry"&&(F.slotsFrom="registry"),s.v&&(F.v=s.v);let De=await fetch(`${i}/decide`,{method:"POST",body:JSON.stringify(F),headers:a});if(!De.ok)return ue(S),null;let w=await De.json(),ee={};for(let D of S)ee[D.id]=(j=(E=w.slots)==null?void 0:E[D.id])!=null?j:z(D);if(w.slots)for(let[D,te]of Object.entries(w.slots))D in ee||(ee[D]=te);for(let[D,te]of Object.entries(ee))C.set(D,te);let He=h!=null&&h.persona!=="unknown";w.persona&&!(w.persona==="unknown"&&He)?h={persona:w.persona,confidence:(B=w.confidence)!=null?B:0}:h||(h={persona:"unknown",confidence:0});for(let[D,te]of Object.entries((k=w.assignments)!=null?k:{}))r.set(D,b,{variantId:te,assignedAt:Date.now(),segment:b,confidence:1});return H(e.apiKey,v({v:1,persona:h.persona,band:(0,Re.confidenceBand)(h.confidence),slots:Object.fromEntries(C),layoutOrder:(G=w.layoutOrder)!=null?G:null,savedAt:Date.now()},w.slotConfig?{slotConfig:w.slotConfig}:{})),v(v(v({layoutOrder:(_=w.layoutOrder)!=null?_:null,assignments:(_e=w.assignments)!=null?_e:{},slots:ee,persona:h.persona,confidence:h.confidence},w.slotConfig?{slotConfig:w.slotConfig}:{}),w.goals?{goals:w.goals}:{}),w.sectionMap?{sectionMap:w.sectionMap}:{})}catch(F){return ue(S),null}},getSlotResult(s){var p;return(p=C.get(s))!=null?p:null},getPersona(){return h?{persona:h.persona,confidence:h.confidence,band:(0,Re.confidenceBand)(h.confidence)}:null},async fetchWeights(){var s;try{let p=await fetch(`${i}/weights`,{headers:a});return p.ok?(s=(await p.json()).components)!=null?s:[]:[]}catch(p){return[]}},getGraph(){return{pageNodes:[],capturedAt:0}},dispose(){var s;o.destroy(),((s=R.get(e.apiKey))==null?void 0:s.dispose)===U.dispose&&R.delete(e.apiKey),e.debug&&console.log("[sentient] disposed")},destroy(){var s;o.destroy(),l.destroy(),((s=R.get(e.apiKey))==null?void 0:s.dispose)===U.dispose&&R.delete(e.apiKey);try{localStorage.removeItem(J+e.apiKey),localStorage.removeItem(Ee(e.apiKey))}catch(p){}e.debug&&console.log("[sentient] destroyed")}};if(R.set(e.apiKey,{config:e,upgrade:null,dispose:U.dispose}),e.debug){let s=window;s.__sentient&&(s.__sentient.client=U)}return U}0&&(module.exports={AGENT_INTENTS,LOCAL_MODE_BANNER,PROD_KEYLESS_ERROR,SNAPSHOT_STORAGE_KEY_PREFIX,agentIntent,agentUaList,armOfResult,attachMicroSignalDetectors,baselineResultFor,baselineSlots,classifiedAgents,deriveSessionSegment,detectDeviceClass,detectTimeOfDay,detectTrafficSource,grantConsent,init,isDoNotTrackEnabled,matchedAgentToken,readSnapshot,referrerDomainFromReferer,renderPrePaintScript,toWireSlot,uaTokenMatch,writeSnapshot});
2
2
  //# sourceMappingURL=index.js.map