@thg-agentic/hyper-personalisation-web 3.28.1 → 3.30.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +13 -5
- package/dist/hp.min.js +2 -2
- package/dist/onsite-answers.min.js +15 -1
- package/dist/onsite-products.min.js +9 -3
- package/dist/onsite-render.min.js +5 -6
- package/dist/onsite-wheel.min.js +1 -1
- package/dist/onsite.min.js +1 -1
- package/package.json +2 -2
- package/src/index.js +2 -0
- package/src/onsite/answers.js +84 -2
- package/src/onsite/api.js +16 -1
- package/src/onsite/countdown.js +35 -0
- package/src/onsite/index.js +238 -102
- package/src/onsite/preview.js +3 -2
- package/src/onsite/products.js +78 -21
- package/src/onsite/render.js +180 -84
- package/src/onsite/rules.js +35 -8
- package/src/onsite/styles.js +0 -1
- package/src/onsite-facade.js +8 -4
- package/src/spec-version.js +1 -1
- package/src/version.js +1 -1
- package/types/events.d.ts +3 -2
- package/types/onsite.d.ts +50 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
(()=>{async function
|
|
1
|
+
(()=>{async function Be(o,r,a){let l=b=>Array.from(new Uint8Array(b),w=>w.toString(16).padStart(2,"0")).join(""),p=new TextEncoder,x=o.maxnumber??1e6;for(let b=0;b<=x;b+=256){let w=[];for(let C=b;C<b+256&&C<=x;C++)w.push(crypto.subtle.digest("SHA-256",p.encode(o.salt+C)));let h=(await Promise.all(w)).findIndex(C=>l(C)===o.challenge);if(h>=0)return b+h;if(r&&await r(),a?.aborted)return null}return null}var Ct=()=>globalThis.scheduler?.postTask?.(()=>{},{priority:"user-visible"})??new Promise(o=>setTimeout(o,0)),He=(o,r)=>Be(o,Ct,r);function Tt(o,r){let a=`onmessage=async(e)=>postMessage(await(${Be})(e.data))`,l=URL.createObjectURL(new Blob([a],{type:"text/javascript"}));return new Promise((p,x)=>{let b;try{b=new Worker(l)}catch(h){URL.revokeObjectURL(l),x(h);return}let w=(h,C)=>{b.terminate(),URL.revokeObjectURL(l),h(C)};r.addEventListener("abort",()=>w(p,null),{once:!0}),b.onmessage=h=>w(p,h.data),b.onerror=h=>{h.preventDefault?.(),w(x,h)},b.postMessage({challenge:o.challenge,salt:o.salt,maxnumber:o.maxnumber})})}var Lt=o=>o&&o.algorithm==="SHA-256"&&typeof o.challenge=="string"&&typeof o.salt=="string"&&typeof o.signature=="string";async function Ge(o){if(!Lt(o)||typeof crypto?.subtle?.digest!="function")return null;let r=Date.now(),a=new AbortController,l,p=new Promise(w=>{l=setTimeout(()=>w(null),2e4)}),x=typeof Worker=="function"&&typeof Blob=="function"?Tt(o,a.signal).catch(()=>He(o,a.signal)):He(o,a.signal),b=await Promise.race([x,p]);return clearTimeout(l),a.abort(),typeof b!="number"?null:btoa(JSON.stringify({algorithm:o.algorithm,challenge:o.challenge,number:b,salt:o.salt,signature:o.signature,took:Date.now()-r}))}function X(o){if(typeof o!="string")return null;try{let r=new URL(o);return r.protocol==="https:"?r.href:null}catch{return null}}function K(o){if(typeof o!="string")return null;try{let r=new URL(o);return r.protocol==="https:"||r.protocol==="http:"&&r.hostname==="localhost"?r.href:null}catch{return null}}function be(o,r,a,l){if(typeof r=="string"){o.append(a.createTextNode(r));return}if(l>6||r===null)return;if(Array.isArray(r)){for(let w of r)be(o,w,a,l+1);return}if(typeof r!="object")return;let p="b"in r?"b":"i"in r?"i":"a"in r?"a":null;if(!p)return;let x=p==="a"?X(r.href):null,b=p==="a"&&!x?o:a.createElement(p);x&&(b.setAttribute("href",x),b.setAttribute("rel","noopener")),be(b,r[p],a,l+1),b!==o&&o.append(b)}function Ve(o,r=document){let a=r.createDocumentFragment();return be(a,o,r,0),a}var M=o=>o!==null&&typeof o=="object"&&!Array.isArray(o);function ee(o,r,a){if(typeof a=="string"&&a)return a;let l=M(o?.next?.answers)?o.next.answers:{};for(let p of o?.blocks??[])for(let x of r[p?.question]??[]){let b=l[`${p.question}=${x}`];if(typeof b=="string")return b}return typeof o?.next?.default=="string"?o.next.default:null}var ge={AT:"43",AU:"61",BE:"32",CA:"1",CH:"41",DE:"49",DK:"45",ES:"34",FI:"358",FR:"33",GB:"44",IE:"353",IT:"39",NL:"31",NO:"47",NZ:"64",PL:"48",PT:"351",SE:"46",US:"1"};function Xe(o,r){let a=String(o??"").replace(/[\s.()-]/g,"");a.startsWith("00")&&(a=`+${a.slice(2)}`);let l=ge[String(r??"").toUpperCase()];return!a.startsWith("+")&&l&&(a=`+${l}${a.replace(/^0/,"")}`),/^\+[1-9]\d{7,14}$/.test(a)?a:null}var Ke=o=>/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(o);function xe(o,r,a,l,p){let x=o("select","i");x.setAttribute("aria-label",r);for(let[b,w]of[["",a],...l]){let h=o("option","",w);h.value=b,h.selected=b===p,x.append(h)}return x}var Ze=o=>{let r=o.options.length;return r<=4?r:r%4?3:4};var ve={system:"system-ui,sans-serif","neo-grotesque":'Inter,Roboto,"Helvetica Neue",Arial,sans-serif',humanist:'Seravek,"Gill Sans Nova",Ubuntu,Calibri,sans-serif',"geometric-humanist":"Avenir,Montserrat,Corbel,sans-serif","rounded-sans":'ui-rounded,Quicksand,Comfortaa,"Arial Rounded MT Bold",sans-serif',industrial:'Bahnschrift,"DIN Alternate","Franklin Gothic Medium",sans-serif',transitional:'Charter,"Sitka Text",Cambria,serif',"old-style":'"Iowan Old Style","Palatino Linotype",P052,serif',didone:'Didot,"Bodoni MT","Noto Serif Display",serif',"slab-serif":'Rockwell,"Roboto Slab","DejaVu Serif",serif'},ye="cubic-bezier(.16,1,.3,1)",we=`
|
|
2
2
|
:host{all:initial}
|
|
3
3
|
:host([preview]){display:block;position:relative;width:100%;height:100%;overflow:hidden;contain:layout paint}
|
|
4
4
|
.s{--a:var(--hp-accent,#111);--b:var(--hp-bg,#fff);--t:var(--hp-text,#111);--r:var(--hp-radius,16px);--oa:var(--hp-on-accent,#fff);--ot:var(--hp-on-accent-text,var(--oa));--fl:var(--hp-field,color-mix(in srgb,var(--t) 5%,var(--b)));--ft:var(--hp-field-text,var(--t));--mu:color-mix(in srgb,var(--t) 74%,var(--b));--ln:color-mix(in srgb,var(--t) 18%,var(--b));--br:min(12px,var(--r));--ir:min(var(--r),8px);font:16px/1.5 var(--hp-font,system-ui,-apple-system,"Segoe UI",Roboto,sans-serif);color:var(--t);-webkit-font-smoothing:antialiased;box-sizing:border-box;margin:0;padding:0;border:0;background:none;max-width:none;max-height:none;overflow:visible}
|
|
@@ -13,7 +13,7 @@ dialog::backdrop{background:none}
|
|
|
13
13
|
.mob.popup{padding:12px}
|
|
14
14
|
.ov{display:none;position:absolute;inset:0;background:var(--hp-ov,rgb(10 10 14/.6));animation:hp-fade .3s ease both}
|
|
15
15
|
.popup>.ov,.fullscreen>.ov{display:block}
|
|
16
|
-
.w{position:relative;display:flex;flex-direction:column;width:min(100%,480px);max-height:100%;min-height:0;overflow:auto;overscroll-behavior:contain;background:var(--b);color:var(--t);border-radius:var(--r);box-shadow:0 24px 48px -24px rgb(0 0 0/.35),0 0 0 1px rgb(0 0 0/.05);animation:hp-pop .44s ${
|
|
16
|
+
.w{position:relative;display:flex;flex-direction:column;width:min(100%,480px);max-height:100%;min-height:0;overflow:auto;overscroll-behavior:contain;background:var(--b);color:var(--t);border-radius:var(--r);box-shadow:0 24px 48px -24px rgb(0 0 0/.35),0 0 0 1px rgb(0 0 0/.05);animation:hp-pop .44s ${ye} both}
|
|
17
17
|
.z-sm{width:min(100%,380px)}
|
|
18
18
|
.z-lg{width:min(100%,880px)}
|
|
19
19
|
.z-full,.fullscreen .w{width:100%;height:100%;max-height:none;border-radius:0;box-shadow:none}
|
|
@@ -105,8 +105,7 @@ legend{padding:0;margin-bottom:8px;font-size:13px;font-weight:600}
|
|
|
105
105
|
.pg{display:flex;flex-direction:column;gap:8px}
|
|
106
106
|
.pg p{font-weight:600}
|
|
107
107
|
.tr{height:6px;border-radius:99px;background:color-mix(in srgb,var(--t) 18%,var(--b));overflow:hidden}
|
|
108
|
-
.tr i{display:block;height:100%;border-radius:inherit;background:var(--a);transform:scaleX(0);transform-origin:left;transition:transform .6s ${
|
|
109
|
-
.tm{font-size:40px;line-height:1;font-weight:800;letter-spacing:.02em;font-variant-numeric:tabular-nums;text-align:center}
|
|
108
|
+
.tr i{display:block;height:100%;border-radius:inherit;background:var(--a);transform:scaleX(0);transform-origin:left;transition:transform .6s ${ye}}
|
|
110
109
|
.bi{display:block;width:100%;height:auto}
|
|
111
110
|
.bl{display:block;border-radius:var(--br)}
|
|
112
111
|
hr{width:100%;margin:4px 0;border:0;border-top:1px solid var(--ln)}
|
|
@@ -170,7 +169,7 @@ hr{width:100%;margin:4px 0;border:0;border-top:1px solid var(--ln)}
|
|
|
170
169
|
.inline .t-stack .m{max-height:none}
|
|
171
170
|
.out .w{animation:hp-out .2s ease-in both}
|
|
172
171
|
.out .ov{animation:hp-fade .2s ease-in reverse both}
|
|
173
|
-
.f>*{animation:hp-rise .5s ${
|
|
172
|
+
.f>*{animation:hp-rise .5s ${ye}}
|
|
174
173
|
.pv .w,.pv .ov,.pv .f>*,.inline .f>*{animation:none}
|
|
175
174
|
@keyframes hp-pop{from{opacity:0;transform:translateY(24px) scale(.96)}}
|
|
176
175
|
@keyframes hp-fade{from{opacity:0}}
|
|
@@ -179,4 +178,4 @@ hr{width:100%;margin:4px 0;border:0;border-top:1px solid var(--ln)}
|
|
|
179
178
|
@keyframes hp-down{from{transform:translateY(-100%)}}
|
|
180
179
|
@keyframes hp-out{to{opacity:0;transform:translateY(12px) scale(.98)}}
|
|
181
180
|
@media (prefers-reduced-motion:reduce){.s .w,.s .ov,.f>*{animation:hp-fade .15s ease both!important}.btn{transition:none}}
|
|
182
|
-
`;var zt=/^#(?:[0-9a-f]{3}){1,2}$/i,He=["popup","fullscreen"],Tt=["ok","verify","already"],Ct=["stack","split","overlay","image-only"],Be={bar:["bottom","top"],sheet:["bottom-right","bottom-left","bottom"],teaser:["bottom-left","bottom-right","left","right"]},Lt=["xs","sm","md","lg","xl","display"],Ge={xs:4,sm:8,md:16,lg:28,xl:44},Ve={sm:380,md:480,lg:880},Mt=["left","center","right"],Xe={secondary:" b2",link:" no"},Ot=220,It=["verify","already","held","fallback","success"],Pt=[500,1500],Nt=600,jt=1800,A={email:"Enter a valid email address.",phone:"Enter a valid mobile number.",intl:"Enter a valid mobile number, starting with + and its country code.",consent:"Tick the box to sign up.",failed:"Something went wrong. Please try again.",busy:"Too many tries. Please wait a moment and try again.",spin:"Sign up first to spin.",yours:"Your code",held:"You\u2019re already on the list",resent:"We\u2019ve sent your code to your inbox again.",inbox:"Your code is in the email we sent when you first signed up.",shop:"Continue shopping",closeOffer:"Close offer",code:"We\u2019ll email your code to you.",claimed:"This email address has already claimed its code.",copied:"Copied",thanks:"Thanks, you\u2019re signed up",retry:"You\u2019re signed up, but we couldn\u2019t load your prize. Please try again.",unclaimed:"We couldn\u2019t load your prize right now.",unavailable:"Not available right now.",won:"You won"},P=i=>i!==null&&typeof i=="object"&&!Array.isArray(i),F=(i,o,a)=>i.includes(o)?o:a,I=(i,o,a)=>Number.isFinite(i)?Math.min(Math.max(i,o),a):null,ge=i=>i.type==="date"||i.type==="number",xe=()=>globalThis.matchMedia?.("(prefers-reduced-motion: reduce)")?.matches===!0;function Je(i){let o=P(i.layout)?i.layout:{},a=P(o.media)?o.media:null,l=F(Ct,o.template,"stack"),u=a?.side==="right"?"right":"left";return!a&&P(o.image)&&o.image.side!=="none"&&(a=o.image,o.image.side!=="top"&&(l="split",u=o.image.side==="right"?"right":"left")),(!a||!G(a.asset))&&(a=null,l="stack"),{template:l,media:a,side:u,scrim:I(o.scrim,0,.9)??.45,padding:F(["none","sm","md","lg"],o.padding,"md")}}var Qe=(i,o)=>F(["sm","md","lg","full"],i.size,null)??(o.template==="split"||o.template==="overlay"?"lg":"md"),et=(i,o,a=1)=>{if(i==="fullscreen"||o==="full")return"100vw";let l=i==="teaser"?220:i==="sheet"?400:Ve[o]??Ve.md;return`(max-width: 639px) 100vw, ${Math.round(l*a)}px`},tt=(i,o,a)=>{if(!a||!Array.isArray(i.widths)||!o.endsWith(".webp"))return null;let l=i.widths.filter(u=>Number.isInteger(u)&&u>0&&u<a).sort((u,x)=>u-x);return l.length===0?null:[...l.map(u=>`${o.slice(0,-5)}-${u}w.webp ${u}w`),`${o} ${a}w`].join(",")},nt=(i,o)=>i.format==="inline"?"inline":o.format&&o.format!=="inline"?o.format:i.format,ve=i=>i.kind==="video"||i.t==="video",we={webm:"video/webm",mp4:"video/mp4",m4v:"video/mp4",mov:"video/quicktime",ogv:"video/ogg"},ke=i=>we[i.split(/[?#]/)[0].split(".").pop().toLowerCase()],qt=(i,o)=>[...new Set([o,...Array.isArray(i.sources)?i.sources.map(G):[]])].filter(Boolean).sort((a,l)=>(ke(l)===we.webm)-(ke(a)===we.webm));function Ae(i,o,a,l=new Set){let u=o.steps.find(k=>k.id===a);if(!u)return Promise.resolve();let x=nt(i,o),h=Je(u),v=x==="teaser"&&u===o.steps[0],m=x==="teaser"&&!v?"popup":x,T=Qe(o.theme,h),E=v?[]:u.blocks.filter(k=>P(k)&&(k.t==="image"||k.t==="video")).map(k=>[k,1]);return h.media&&!(v&&h.template!=="image-only")&&E.push([h.media,h.template==="split"?.46:1]),Promise.all(E.map(([k,Q])=>{let L=G(ve(k)?k.poster:k.asset);if(!L)return null;let C=document.createElement("img"),U=!ve(k)&&tt(k,L,I(k.width,1,8192));U&&(C.sizes=et(m,T,Q),C.srcset=U);let y=`${C.sizes} ${U||L}`;return l.has(y)?null:(l.add(y),C.src=L,C.decode?.().catch(()=>{}))}))}var Ke=i=>i?.call?i():clearInterval(i),Dt=0,ye=i=>`hp-${i}-${++Dt}`;function p(i,o,a){let l=document.createElement(i);return o&&(l.className=o),a!==void 0&&l.append(We(a)),l}var it=i=>{let o=i.length===4?[...i.slice(1)].map(a=>a+a).join(""):i.slice(1);return[0,2,4].map(a=>Number.parseInt(o.slice(a,a+2),16))},J=i=>{let[o,a,l]=it(i).map(u=>{let x=u/255;return x<=.04045?x/12.92:((x+.055)/1.055)**2.4});return .2126*o+.7152*a+.0722*l},Ze=(i,o=4.5)=>{let a=J(i)+.05,l=1.05/a;return l>=o?"#fff":a/(J("#111")+.05)>l?"#111":"#fff"};function Rt(i,o){let a=(E,k)=>k&&i.style.setProperty(E,k),l=E=>zt.test(E??"")?E:null;a("--hp-accent",l(o.accent)),a("--hp-bg",l(o.background)),a("--hp-text",l(o.text));let u=I(o.radius,0,48);u!==null&&a("--hp-radius",`${u}px`),a("--hp-font",o.font==="site"?i.ownerDocument.defaultView.getComputedStyle(i.parentElement??i.ownerDocument.body).fontFamily:Object.hasOwn(he,o.font)?he[o.font]:null),l(o.accent)&&(a("--hp-on-accent",Ze(o.accent,3)),a("--hp-on-accent-text",Ze(o.accent))),l(o.background)&&J(o.background)<.18&&(a("--hp-field","#fff"),a("--hp-field-text","#111"));let x=P(o.overlay)?o.overlay:{},h=[l(o.text),l(o.background)].filter(Boolean).sort((E,k)=>J(E)-J(k))[0],[v,m,T]=it(l(x.colour)??h??"#0b0b0f");a("--hp-ov",`rgb(${v} ${m} ${T} / ${I(x.opacity,0,1)??.6})`)}function Ut(i){try{let o=new CSSStyleSheet;o.replaceSync(be),i.adoptedStyleSheets=[o]}catch{let o=document.createElement("style");o.textContent=be,i.append(o)}}function ot(i){let{form:o,creative:a,decision:l,access:u,client:x,api:h,counters:v}=i,m=i.preview??null,T=e=>{let t=e.blocks.find(r=>r?.t==="email"||r?.t==="phone");return t?.t==="phone"||!t&&!o.consent_text?o.sms_consent_text:o.consent_text},E=nt(o,a),k=a.theme,Q=F(Be[E]??[],k.position,Be[E]?.[0]),L=document.createElement("hp-onsite");m&&L.setAttribute("preview",""),Rt(L,k);let C=L.attachShadow({mode:"open"});Ut(C);let U=E!=="inline"&&!m,y=p(U?"dialog":E==="inline"?"section":"div"),Se=p("div","ov"),_=p("div","w"),W=p("div","m");m&&(W.dataset.hpMedia="");let Ee=()=>{let e=p("form","f");return e.noValidate=!0,e.addEventListener("submit",yt),e.addEventListener("input",()=>{M.textContent&&S.getAttribute("aria-busy")!=="true"&&N(null)}),e},S=Ee(),M=p("p","e");M.id=ye("err"),M.setAttribute("aria-live","assertive");let re=p("div","hd");re.setAttribute("aria-hidden","true"),_.append(re,W,S),y.append(Se,_);let Y=E!=="inline"&&p("button","x");Y&&(Y.type="button",Y.addEventListener("click",()=>j("close")),_.append(Y),Se.addEventListener("click",()=>j("close"))),C.append(y);let n={step:null,mode:E,size:"md",modal:!1,mobile:m?.device==="mobile",answers:{},sent:new Set,seen:new Set,receipt:null,claim:i.coupon?{code:i.coupon}:m?{code:"WELCOME15"}:null,claiming:null,touched:!1,toWarm:new Set,warmed:i.warmed??new Set,warming:!1,owed:!1,unclaimed:!1,misses:0,submitted:!1,pow:null,wheel:null,timers:[],codes:[],videos:[],closed:!1},X=o.locale||document.documentElement.lang,rt=o.questions.some(ge)&&i.loadAnswers().catch(()=>null),_e=new WeakMap,$e=()=>{let e=P(k.button)?k.button:{};y.className=`s ${n.mode}${Q?` p-${Q}`:""} b-${F(["pill","rounded","square"],e.shape,"rounded")}${n.mobile?" mob":""}${m?" pv":""}${e.style==="outline"?" bo":""}${k.caps===!0?" uc":""}`},K=m?null:globalThis.matchMedia?.("(max-width: 639px)"),ze=()=>{n.mobile=K?.matches===!0,le(),$e()};K&&(n.mobile=K.matches===!0,K.addEventListener?.("change",ze));let Z=(e,t,r={})=>{m||!l.decision_id||!u.analytics()||x.slotEngaged({decision_id:l.decision_id,slot:l.slot,arm:l.arm??null,engagement:e,step:t??n.step?.id??null,...r})},N=(e,t)=>{M.className="e",M.textContent=e??"";for(let s of S.querySelectorAll("[aria-invalid]"))s.removeAttribute("aria-invalid");let r=t?.closest("label,fieldset");r&&S.contains(r)?r.after(M):S.append(M),t&&(t.setAttribute("aria-invalid","true"),t.setAttribute("aria-describedby",M.id),t.focus(),t.scrollIntoView?.({block:"nearest"}))},H=e=>{S.setAttribute("aria-busy",String(e));for(let t of S.querySelectorAll("button"))t.disabled=e},Te=()=>m?Promise.resolve(null):(n.pow??(n.pow=h.challenge().then(e=>e.status===200?Ue(e.body):null).catch(()=>null)),n.pow),se=()=>{for(let e of n.videos)try{document.hidden||xe()?e.pause():e.play()?.catch?.(()=>{})}catch{}};document.addEventListener("visibilitychange",se);function Ce(e,t,r,s){let c=G(e.asset);if(!c)return null;let f=typeof e.alt=="string"?e.alt:"",d;if(ve(e)){d=p("video",t),d.muted=d.defaultMuted=d.loop=d.playsInline=!0;let w=G(e.poster);w&&(d.poster=w),f?d.setAttribute("aria-label",f):d.setAttribute("aria-hidden","true"),d.autoplay=!xe()&&!m,d.preload=d.autoplay?"auto":w?"none":"metadata";let $=qt(e,c);if($.length>1)for(let z of $){let O=p("source");O.src=z;let q=ke(z);q&&(O.type=q),d.append(O)}else d.src=c;n.videos.push(d)}else{d=p("img",t),d.alt=f,d.decoding="async",d.loading=r?"eager":"lazy",r&&(d.fetchPriority="high");let w=tt(e,c,I(e.width,1,8192));w&&(d.sizes=et(n.mode,n.size,s),d.srcset=w),d.src=c}let b=I(e.width,1,8192),g=I(e.height,1,8192);return b&&g&&(d.width=b,d.height=g),P(e.focal)&&(d.style.objectPosition=`${I(e.focal.x,0,100)??50}% ${I(e.focal.y,0,100)??50}%`),d}function Le(e,t){let r=p("label","l");r.append(p("span","lt",e.label??(t==="email"?"Email":"Mobile number")));let s=p("input","i");if(s.type=t,s.name=t==="email"?"email":"phone",s.autocomplete=s.inputMode=t,s.required=!0,typeof e.placeholder=="string"&&(s.placeholder=e.placeholder),s.setAttribute("aria-describedby",M.id),s.addEventListener("focus",Te,{once:!0}),t!=="tel")return r.append(s),r;s.id=`${M.id}-p`,r.htmlFor=s.id;let c=fe(p,"Country code","+",Object.entries(ue).map(([d,b])=>[d,`${d} +${b}`]),(e.country||/-(\w\w)$/.exec(X)?.[1]||"").toUpperCase());c.classList.add("cc"),c.name="hp_cc";let f=p("span","ph");return f.append(c,s),r.append(f),r}function st(e){let t=o.questions.find(b=>b.key===e.question);if(!t||!ge(t)&&!Array.isArray(t.options))return null;let r=p("fieldset");r.dataset.question=t.key,r.append(p("legend","",t.label??""));let s=n.answers[t.key]??[];if(ge(t))return rt.then(b=>{if(!b)return r.append(p("p","sm",A.unavailable));b.answerFields(r,t,p,s[0],X),_e.set(r,()=>b.answerOf(r,t,void 0,X))}),r;let c=t.type==="many",f=F(["list","dropdown"],e.display,"buttons"),d=t.options.filter(b=>P(b)&&typeof b.value=="string");if(f==="dropdown"&&!c)return r.append(fe(p,t.label??t.key,"\u2014",d.map(b=>[b.value,b.label??b.value]),s[0])),r;f!=="buttons"&&(r.className="ls");for(let b of d){let g=p("input");g.value=b.value,g.checked=s.includes(b.value),g.type=c?"checkbox":"radio",g.name=`q_${t.key}`;let w=p("label",f==="buttons"?"ch":"c");w.append(g,p("span","",b.label??b.value)),r.append(w)}return r}function ee(){for(let e of n.codes){if(e.replaceChildren(),!n.claim){n.unclaimed&&e.append(p("p","",A.unclaimed));continue}if(!n.claim.code){let s=n.claim.held?A.claimed:n.claim.fallback===!0?A.code:n.claim.prize?.label;s&&e.append(p("p","",s));continue}n.claim.prize?.label&&e.append(p("p","",n.claim.prize.label));let t=p("output");t.textContent=n.claim.code;let r=p("button","btn cp");r.type="button",r.textContent="Copy code",r.addEventListener("click",()=>{navigator.clipboard?.writeText(n.claim.code).then(()=>{r.textContent=A.copied}).catch(()=>{})}),e.append(t,r)}}function at(e){if(n.claim&&!n.claim.code)return null;let t=p("p","tm");t.setAttribute("role","timer");let r=Date.now()+Math.max(0,Number(e.minutes)||0)*6e4,s=()=>{let f=Math.max(0,Math.round((r-Date.now())/1e3));t.textContent=`${String(Math.floor(f/60)).padStart(2,"0")}:${String(f%60).padStart(2,"0")}`,f===0&&clearInterval(c)},c=setInterval(s,1e3);return n.timers.push(c),s(),t}function ae(e,t){return e.href=t,e.rel="noopener",e.addEventListener("click",r=>{m?r.preventDefault():Z("click")}),e}function lt(e){let t=e.label??"Continue";if(e.action==="link"){let s=B(e.href);return s?ae(p("a",`btn${Xe[e.variant]??""}`,t),s):null}let r=p("button",`btn${Xe[e.variant]??""}`,t);return r.type=e.action==="submit"?"submit":"button",r.type==="button"?r.addEventListener("click",()=>ie(e)):r.dataset.submit="",r}let Me=(e,t,r)=>(e.classList.add(`x-${F(Lt,t.size,r)}`),Mt.includes(t.align)&&e.classList.add(`a-${t.align}`),e);function Oe(e){let t=Ce(e,"bi",n.step===a.steps[0]);if(!t)return null;t.style.objectFit=e.fit==="contain"?"contain":"cover";let r=I(e.radius,0,48);r!==null&&(t.style.borderRadius=`${r}px`);let s=I(e.max_height,40,800);if(s!==null&&(t.style.maxHeight=`${s}px`),!t.width&&e.fit!=="contain"&&(t.style.aspectRatio="16 / 9"),e.t==="video"||!B(e.href))return t;let c=ae(p("a","bl"),B(e.href));return c.append(t),c}function ct(e){let t=I(e.threshold,.01,1e7);if(!t)return null;let r=p("div","pg"),s=p("p"),c=p("div","tr"),f=p("i");c.append(f),c.setAttribute("role","progressbar"),c.setAttribute("aria-valuemin","0"),c.setAttribute("aria-valuemax",String(t)),r.append(s,c);let d=g=>g.toFixed(2);try{let g=new Intl.NumberFormat(X||void 0,{style:"currency",currency:e.currency});d=w=>g.format(w)}catch{}let b=()=>{let g=Math.max(0,Number(i.basket?.())||0),w=t-g;s.textContent=w>0?String(e.text??"").replace("{amount}",d(w)):e.done??"",f.style.transform=`scaleX(${Math.min(1,g/t)})`,c.setAttribute("aria-valuenow",String(Math.min(g,t))),s.id||(s.id=ye("pg")),c.setAttribute("aria-labelledby",s.id)};return b(),n.timers.push(setInterval(b,2e3)),r}function dt(e){let t=p("div","pr");return i.loadProducts?.().then(r=>{t.isConnected&&n.timers.push(r.mountProducts(t,e,{el:p,lang:X,root:C,placement:o.slot,preview:m,client:!m&&u.analytics()&&x,engaged:Z,seen:n.seen}))}).catch(()=>{}),t}let Ie={heading(e){let t=Me(p("h2","",e.text),e,"xl");return t.id=ye("h"),t.tabIndex=-1,y.hasAttribute("aria-labelledby")||(y.setAttribute("aria-labelledby",t.id),n.step===a.steps[0]&&He.includes(n.mode)&&!m&&(t.autofocus=!0)),t},text:e=>Me(p("p","",e.text),e,"md"),email:e=>Le(e,"email"),phone:e=>Le(e,"tel"),consent(e){let t=T(n.step)?.text;if(typeof t!="string")return null;if(e.required!==!0)return p("p","sm",t);let r=p("label","c"),s=p("input");return s.type="checkbox",s.name="hp_consent",s.required=!0,s.setAttribute("aria-describedby",M.id),r.append(s,p("span","",t)),r},question:st,wheel(){let e=p("div","wh");return i.loadWheel().then(t=>{n.closed||(n.wheel=t.mountWheel(e,o.prizes))}).catch(()=>{}),e},code(){let e=p("div","k");return e.setAttribute("aria-live","polite"),n.codes.push(e),e},button:lt,decline(e){let t=p("button","btn no",e.label??"No thanks");return t.type="button",t.addEventListener("click",()=>j("decline")),t},countdown:at,progress:ct,products:dt,image:Oe,video:Oe,spacer(e){let t=p("div","sp");return t.style.height=`${Ge[e.size]??Ge.md}px`,t.setAttribute("aria-hidden","true"),t},divider:()=>p("hr")};function pt(e,t){W.replaceChildren();let r=e.media,s=!r||t&&e.template!=="image-only";if(n.size=Qe(k,e),_.className=`w t-${e.template} z-${n.size}${e.side==="right"?" right":""}${k.text_align==="center"?" ta-center":""}${s?" nm":""}`,_.style.setProperty("--sc",String(e.scrim)),S.className=`f pd-${e.padding}`,W.hidden=s,W.hidden)return;let c=Ce(r,"",n.step===a.steps[0],e.template==="split"?.46:1);if(!c)return;if(c.width?_.style.setProperty("--ar",`${c.width} / ${c.height}`):_.style.removeProperty("--ar"),e.template!=="image-only"){c.tagName==="IMG"&&e.template==="overlay"&&(c.alt=""),W.append(c);return}let f=B(r.href),d=f?ae(p("a","io"),f):p("button","io");f||(d.type="button",d.addEventListener("click",()=>ie({action:"next"}))),d.append(c),W.append(d)}function ut(e){let t=e.blocks.find(c=>c?.t==="heading"),r=e.blocks.find(c=>c?.t==="button"&&c.action==="next"),s=p("button","tb");return s.textContent=t?p("b","",t.text).textContent:r?.label??"Open",s.type="button",s.addEventListener("click",()=>ie(r??{action:"next"})),s}function D(e,t=new Set){let r=a.steps.find(z=>z.id===e);if(!r)return j("done");if(r.kind==="question"&&!m&&!u.analytics()&&!t.has(r.id))return D(V(r,n.answers),t.add(r.id));let s=n.step!==null,c=s&&(C.activeElement||document.activeElement===document.body),f=s&&!m?{mode:n.mode,w:_.offsetWidth,h:_.offsetHeight,top:_.offsetTop}:null;n.step=r,n.touched=!1;for(let z of n.timers.splice(0))Ke(z);n.codes=[],n.videos=[],n.wheel=null;let d=E==="teaser"&&r===a.steps[0];if(n.mode=E==="teaser"&&!d?"popup":E,E==="teaser"&&v.tab?.(o.slot,d),Y&&Y.setAttribute("aria-label",d?A.closeOffer:"Close"),$e(),y.removeAttribute("aria-labelledby"),f){let z=Ee();S.replaceWith(z),S=z}let b=Je(r);pt(b,d);let g=f?.mode==="popup"&&n.mode==="popup";if(le(),f?.mode===n.mode&&f.h>0&&!g&&(_.style.setProperty("--lw",`${f.w}px`),_.style.setProperty("--lh",`${f.h}px`),_.classList.add("lk")),S.replaceChildren(),d&&b.template!=="image-only")S.append(ut(r));else for(let[z,O]of r.blocks.entries()){let q=P(O)&&Object.hasOwn(Ie,O.t)?Ie[O.t](O):null;q&&(m&&(q.dataset.hpBlock=String(z)),S.append(q))}let w=S.querySelector("[data-submit]"),$=S.querySelector("[name=hp_consent]")?.parentNode;w&&$&&w.before($),S.hidden=S.childElementCount===0,N(null),ee(),y.hasAttribute("aria-labelledby")?y.removeAttribute("aria-label"):y.setAttribute("aria-label",b.media?.alt?.trim?.()||"Sign up"),g&&f.h>0&&ft(f),s&&Pe(),se(),m||mt(r),c&&S.querySelector("h2")?.focus()}function le(){_.classList.remove("lk","an"),_.style.removeProperty("--tp")}function ft(e){let t=_.offsetHeight;_.classList.add("an");let r=_.offsetTop,s=Math.max(0,e.top-r);if(s+t>y.clientHeight-2*r)return le();_.style.setProperty("--tp",`${s}px`)}function mt(e){let t=e.next??{};for(let c of[t.default,...Object.values(P(t.answers)?t.answers:{}),...e.blocks.map(f=>f?.next),...It])typeof c=="string"&&n.toWarm.add(c);if(n.warming)return;n.warming=!0;let r=()=>{if(n.warming=!1,!n.closed&&L.isConnected)for(let c of n.toWarm)Ae(o,a,c,n.warmed);n.toWarm.clear()},s=()=>globalThis.requestIdleCallback?requestIdleCallback(r,{timeout:2e3}):setTimeout(r,200);document.readyState==="complete"?s():window.addEventListener("load",s,{once:!0})}function Pe(){if(!U)return;let e=He.includes(n.mode);if(!(y.open&&n.modal===e)){try{y.open&&y.close()}catch{}if(n.modal=e,y.setAttribute("aria-modal",String(e)),e&&typeof y.showModal=="function")y.showModal();else if(typeof y.show=="function"){let t=document.activeElement;y.show(),t&&t!==document.body?t.focus?.({preventScroll:!0}):L.blur()}else y.setAttribute("open","");!e||typeof y.showModal!="function"?y.setAttribute("role","dialog"):y.removeAttribute("role")}}function ht(){for(let e of S.querySelectorAll("fieldset[data-question]")){let t=e.dataset.question,r=_e.get(e)?.()??{};if(r.error)return r;let s=[r.value,...[...e.querySelectorAll("input:checked,select:not([name])")].map(c=>c.value)].filter(Boolean);s.length?n.answers[t]=s:delete n.answers[t]}}function bt(){let e=[];for(let[r,s]of Object.entries(n.answers)){let c=`${r}=${s.join(",")}`;n.sent.has(c)||(n.sent.add(c),e.push({question:r,values:s}))}let t=n.step.id;if(n.signedUp&&e.length)return void h.answers({anonymousId:u.anonymousId(),sessionId:u.sessionId()??void 0,slot:l.slot,arm:l.arm??void 0,decision_id:l.decision_id??void 0,step:t,...n.signedUp,answers:e,context:Ne()});if(u.analytics())for(let r of e)x.preferencesStated({...r,source:"onsite",slot:l.slot,arm:l.arm??null,decision_id:l.decision_id??null,step:t})}let Ne=()=>({page:{url:u.pageUrl()},locale:u.locale()??void 0,consent:u.consent()}),te=e=>{n.receipt&&!m&&bt(),D(V(n.step,n.answers,e))};async function gt(e){let t=n.step,r=S.querySelector("input[name=email],input[name=phone]");if(!r)return te(e.next);let s=r.name==="email"?"email":"sms",c=S.querySelector("select[name=hp_cc]")?.value,f=s==="email"?Ye(r.value.trim())?r.value.trim():null:Fe(r.value,c);if(!f)return N(s==="email"?A.email:c?A.phone:A.intl,r);let d=S.querySelector("input[name=hp_consent]");if(d&&!d.checked)return N(A.consent,d);N(null),H(!0);let b=await Te();n.pow=null;let g=Object.entries(n.answers).map(([R,de])=>({question:R,values:de})),w=s==="sms"?o.sms_consent_text:o.consent_text,$=await h.capture({anonymousId:u.anonymousId(),sessionId:u.sessionId()??void 0,slot:l.slot,arm:l.arm??void 0,decision_id:l.decision_id??void 0,step:t.id,channel:s,[s==="email"?"email":"phone"]:f,...s==="sms"&&n.signedUp,consent_text:w?{id:w.id,version:w.version}:void 0,...g.length?{answers:g}:{},...b?{altcha:b}:{},context:Ne()}),z=$.body?.status,O=($.status===202||$.status===200)&&Tt.includes(z);if(n.closed&&!O)return;O||H(!1);let q=$.status===400?$.body?.field:null;if(q==="email"||q==="phone")return N(A[q],r);if(!O)return N($.status===429?A.busy:A.failed,r);r.value="";for(let[R,de]of Object.entries(n.answers))n.sent.add(`${R}=${de.join(",")}`);n.receipt=typeof $.body.receipt=="string"?$.body.receipt:null,s==="email"&&(n.signedUp={email:f,email_receipt:n.receipt}),n.submitted=!0,v.submitted(o.slot),Z("submit",t.id),n.owed=s==="email"&&o.prizes.length>0;let oe=n.owed?ce([]):null;oe||i.emit?.("submitted",{coupon:null});let wt=oe&&await Promise.race([oe,new Promise(R=>setTimeout(R,Nt))]);if(n.closed)return;if(H(!1),wt?.held)return D(ne("held"));let kt=z!=="ok"&&a.steps.some(R=>R.id===z);D(kt?z:V(t,n.answers,e.next));let At=n.step;oe?.then(R=>{R?.held&&!n.closed&&n.step===At&&!n.touched&&D(ne("held"))})}function ne(e){if(a.steps.some(s=>s.id===e))return e;let t={t:"button",label:A.shop,action:"close"},r=e==="unclaimed"?[{t:"heading",text:A.thanks},{t:"text",text:A.unclaimed},t]:e==="fallback"||n.claim?.code?[{t:"heading",text:e==="fallback"?A.thanks:A.yours},{t:"code"}]:[{t:"heading",text:A.held},{t:"text",text:o.code_relayed===!0?A.resent:A.inbox},t];return a.steps.push({id:e,blocks:r}),e}function je(e){n.owed&&(n.owed=!1,i.emit?.("submitted",{coupon:e?{code:e.code??null,prize:e.prize?.key}:null}))}function ce(e=Pt){let t=n.receipt;return n.claiming??(n.claiming=(async()=>{n.unclaimed=!1;let r;for(let d of[0,...e])if(d&&await new Promise(b=>setTimeout(b,d)),r=await h.claim({slot:l.slot,decision_id:l.decision_id??void 0,receipt:t}),r.status!==503)break;let s=r.body,c=s?.fallback===!0&&!s.code;if(r.status!==200||!(P(s?.prize)||c))return n.claiming=null,!e.length&&r.status===503?ce():(je(null),n.unclaimed=!0,n.closed||ee(),null);let f=s.held&&!s.code?v.code?.():null;return f&&(s={...s,code:f}),n.claim=s,typeof s.code=="string"&&v.code?.(s.code),je(s),n.closed||ee(),s})()),n.claiming}async function xt(e){if(!n.receipt)return N(A.spin);H(!0);let t=await ce();if(n.closed)return;if(!t)return H(!1),n.misses+=1,n.misses<2?N(A.retry):D(ne("unclaimed"));let r=t.fallback===!0&&!t.code,s=t.held?-1:o.prizes.findIndex(d=>d.key===t.prize?.key&&d.label===t.prize?.label);if(n.wheel&&s>=0&&!r){if(await n.wheel.spinTo(s),n.closed)return;M.className="e won",M.textContent=`${A.won} ${t.prize.label}`,await new Promise(d=>setTimeout(d,jt))}if(n.closed)return;H(!1);let c=r?"fallback":s<0?"held":null,f=c?ne(c):V(n.step,n.answers,e.next);f?D(f):ee()}function ie(e){if(e.action==="close")return j("close");let t=ht();return m?te(e.next):t?N(t.error,t.input):e.action==="apply"?(i.emit?.("apply",{coupon:n.claim?.code?{code:n.claim.code}:null}),Z("click"),V(n.step,n.answers,e.next)?te(e.next):j("done")):e.action==="submit"?gt(e):e.action==="spin"?xt(e):te(e.next)}function yt(e){if(e.preventDefault(),S.getAttribute("aria-busy")==="true")return;let t=n.step.blocks.find(r=>r?.t==="button"&&r.action==="submit");ie(t??{action:"next"})}function qe(){n.closed=!0;for(let t of n.timers.splice(0))Ke(t);document.removeEventListener("visibilitychange",se),K?.removeEventListener?.("change",ze);let e=()=>{try{y.open&&y.close()}catch{}L.remove()};if(!U||xe())return e();y.classList.add("out"),setTimeout(e,Ot)}function j(e){n.closed||m||(!n.submitted&&e!=="done"&&Z("dismiss"),v.closed(o.slot),v.tab?.(o.slot,!1),qe(),i.onClose?.(e))}for(let e of["pointerdown","keydown","input"])y.addEventListener(e,()=>{n.touched=!0});y.addEventListener("cancel",e=>{e.preventDefault(),j("esc")}),y.addEventListener("keydown",e=>{e.key==="Escape"&&!n.modal&&E!=="inline"&&j("esc"),e.key==="Tab"&&n.modal&&vt(e)});function vt(e){let t=[...C.querySelectorAll("input[type=radio]:checked")],r=new Set,s=[...C.querySelectorAll("a[href],button,input,select,textarea")].filter(g=>{if(g.disabled||!g.getClientRects().length)return!1;if(g.type!=="radio")return!0;let w=t.find($=>$.name===g.name);return(w?g!==w:r.has(g.name))?!1:(r.add(g.name),!0)});if(!s.length)return;let c=e.shiftKey,f=C.activeElement;f?.type==="radio"&&(f=s.find(g=>g.type==="radio"&&g.name===f.name)??f);let d=s.indexOf(f),b=null;if(d<0){let g=w=>f&&f.compareDocumentPosition(w)&4;b=c?s.findLast(w=>!g(w))??s.at(-1):s.find(g)??s[0]}else(c?d===0:d===s.length-1)&&(b=s.at(c?-1:0));b&&(e.preventDefault(),b.focus())}return re.addEventListener("pointerdown",e=>{if(!n.mobile||n.mode!=="sheet")return;let t=e.clientY,r=0,s=f=>{r=Math.max(0,f.clientY-t),_.style.transform=`translateY(${r}px)`},c=()=>{document.removeEventListener("pointermove",s),document.removeEventListener("pointerup",c),_.style.transform="",r>80&&j("close")};document.addEventListener("pointermove",s),document.addEventListener("pointerup",c)}),D(m?.step&&a.steps.some(e=>e.id===m.step)?m.step:a.steps[0].id),(i.container??document.body).append(L),Pe(),{close:j,root:C,host:L,show:D,step:()=>n.step?.id??null,modal:()=>!n.closed&&n.modal,destroy:()=>!n.closed&&qe()}}window[Symbol.for("@thg-agentic/hyper-personalisation-web.onsite.render")]={mountForm:ot,warm:Ae};})();
|
|
181
|
+
`;var Ot=/^#(?:[0-9a-f]{3}){1,2}$/i,Je=["popup","fullscreen"],Mt=["ok","verify","already"],It=["stack","split","overlay","image-only"],Qe={bar:["bottom","top"],sheet:["bottom-right","bottom-left","bottom"],teaser:["bottom-left","bottom-right","left","right"]},Pt=["xs","sm","md","lg","xl","display"],et={xs:4,sm:8,md:16,lg:28,xl:44},tt={sm:380,md:480,lg:880},qt=["left","center","right"],nt={secondary:" b2",link:" no"},Nt=220,jt=["verify","already","held","fallback","success"],Rt=[500,1500],Dt=600,Ut=1800,S={email:"Enter a valid email address.",phone:"Enter a valid mobile number.",intl:"Enter a valid mobile number, starting with + and its country code.",consent:"Tick the box to sign up.",failed:"Something went wrong. Please try again.",busy:"Too many tries. Please wait a moment and try again.",spin:"Sign up first to spin.",yours:"Your code",held:"You\u2019re already on the list",resent:"We\u2019ve sent your code to your inbox again.",inbox:"Your code is in the email we sent when you first signed up.",shop:"Continue shopping",closeOffer:"Close offer",code:"We\u2019ll email your code to you.",claimed:"This email address has already claimed its code.",copied:"Copied",thanks:"Thanks, you\u2019re signed up",retry:"You\u2019re signed up, but we couldn\u2019t load your prize. Please try again.",unclaimed:"We couldn\u2019t load your prize right now.",unavailable:"Not available right now.",won:"You won"},H=(o,r,a)=>o.includes(r)?r:a,I=(o,r,a)=>Number.isFinite(o)?Math.min(Math.max(o,r),a):null,ke=o=>o.type==="date"||o.type==="number",Ae=()=>globalThis.matchMedia?.("(prefers-reduced-motion: reduce)")?.matches===!0;function rt(o){let r=M(o.layout)?o.layout:{},a=M(r.media)?r.media:null,l=H(It,r.template,"stack"),p=a?.side==="right"?"right":"left";return!a&&M(r.image)&&r.image.side!=="none"&&(a=r.image,r.image.side!=="top"&&(l="split",p=r.image.side==="right"?"right":"left")),(!a||!K(a.asset))&&(a=null,l="stack"),{template:l,media:a,side:p,scrim:I(r.scrim,0,.9)??.45,padding:H(["none","sm","md","lg"],r.padding,"md")}}var st=(o,r)=>H(["sm","md","lg","full"],o.size,null)??(r.template==="split"||r.template==="overlay"?"lg":"md"),at=(o,r,a=1,l="100vw")=>{if(o==="fullscreen"||r==="full")return l;let p=o==="teaser"?220:o==="sheet"?400:tt[r]??tt.md;return`(max-width: 639px) ${l}, ${Math.round(p*a)}px`},lt=(o,r)=>o==="lg"?1/Ze(r):.5,ct=(o,r,a)=>{if(!a||!Array.isArray(o.widths)||!r.endsWith(".webp"))return null;let l=o.widths.filter(p=>Number.isInteger(p)&&p>0&&p<a).sort((p,x)=>p-x);return l.length===0?null:[...l.map(p=>`${r.slice(0,-5)}-${p}w.webp ${p}w`),`${r} ${a}w`].join(",")},dt=(o,r)=>o.format==="inline"?"inline":r.format&&r.format!=="inline"?r.format:o.format,Ee=o=>o.kind==="video"||o.t==="video",$e={webm:"video/webm",mp4:"video/mp4",m4v:"video/mp4",mov:"video/quicktime",ogv:"video/ogg"},_e=o=>$e[o.split(/[?#]/)[0].split(".").pop().toLowerCase()],Wt=(o,r)=>[...new Set([r,...Array.isArray(o.sources)?o.sources.map(K):[]])].filter(Boolean).sort((a,l)=>(_e(l)===$e.webm)-(_e(a)===$e.webm));function ze(o,r,a,l=new Set){let p=r.steps.find(v=>v.id===a);if(!p)return Promise.resolve();let x=dt(o,r),b=rt(p),w=x==="teaser"&&p===r.steps[0],h=x==="teaser"&&!w?"popup":x,C=st(r.theme,b),$=w?[]:p.blocks.flatMap(v=>{if(v?.t==="image"||v?.t==="video")return[[v]];let W=v?.display==="cards"&&o.questions.find(T=>T.key===v.question&&T.type==="one");return W?Object.values(v.pictures??{}).filter(M).map(T=>[T,lt(C,W),"50vw"]):[]});return b.media&&!(w&&b.template!=="image-only")&&$.push([b.media,b.template==="split"?.46:1]),Promise.all($.map(([v,W,T])=>{let L=K(Ee(v)?v.poster:v.asset);if(!L)return null;let j=document.createElement("img"),y=!Ee(v)&&ct(v,L,I(v.width,1,8192));y&&(j.sizes=at(h,C,W,T),j.srcset=y);let Z=`${j.sizes} ${y||L}`;return l.has(Z)?null:(l.add(Z),j.src=L,j.decode?.().catch(()=>{}))}))}var it=o=>o?.call?o():clearInterval(o),Ft=0,Se=o=>`hp-${o}-${++Ft}`;function d(o,r,a){let l=document.createElement(o);return r&&(l.className=r),a!==void 0&&l.append(Ve(a)),l}var pt=o=>{let r=o.length===4?[...o.slice(1)].map(a=>a+a).join(""):o.slice(1);return[0,2,4].map(a=>Number.parseInt(r.slice(a,a+2),16))},te=o=>{let[r,a,l]=pt(o).map(p=>{let x=p/255;return x<=.04045?x/12.92:((x+.055)/1.055)**2.4});return .2126*r+.7152*a+.0722*l},ot=(o,r=4.5)=>{let a=te(o)+.05,l=1.05/a;return l>=r?"#fff":a/(te("#111")+.05)>l?"#111":"#fff"};function Yt(o,r){let a=($,v)=>v&&o.style.setProperty($,v),l=$=>Ot.test($??"")?$:null;a("--hp-accent",l(r.accent)),a("--hp-bg",l(r.background)),a("--hp-text",l(r.text));let p=I(r.radius,0,48);p!==null&&a("--hp-radius",`${p}px`),a("--hp-font",r.font==="site"?o.ownerDocument.defaultView.getComputedStyle(o.parentElement??o.ownerDocument.body).fontFamily:Object.hasOwn(ve,r.font)?ve[r.font]:null),l(r.accent)&&(a("--hp-on-accent",ot(r.accent,3)),a("--hp-on-accent-text",ot(r.accent))),l(r.background)&&te(r.background)<.18&&(a("--hp-field","#fff"),a("--hp-field-text","#111"));let x=M(r.overlay)?r.overlay:{},b=[l(r.text),l(r.background)].filter(Boolean).sort(($,v)=>te($)-te(v))[0],[w,h,C]=pt(l(x.colour)??b??"#0b0b0f");a("--hp-ov",`rgb(${w} ${h} ${C} / ${I(x.opacity,0,1)??.6})`)}function Ht(o){try{let r=new CSSStyleSheet;r.replaceSync(we),o.adoptedStyleSheets=[r]}catch{let r=document.createElement("style");r.textContent=we,o.append(r)}}function ut(o){let{form:r,creative:a,decision:l,access:p,client:x,api:b,counters:w}=o,h=o.preview??null,C=e=>{let t=e.blocks.find(i=>i?.t==="email"||i?.t==="phone");return t?.t==="phone"||!t&&!r.consent_text?r.sms_consent_text:r.consent_text},$=dt(r,a),v=a.theme,W=H(Qe[$]??[],v.position,Qe[$]?.[0]),T=document.createElement("hp-onsite");h&&T.setAttribute("preview",""),Yt(T,v);let L=T.attachShadow({mode:"open"});Ht(L);let j=$!=="inline"&&!h,y=d(j?"dialog":$==="inline"?"section":"div"),Z=d("div","ov"),_=d("div","w"),F=d("div","m");h&&(F.dataset.hpMedia="");let Ce=()=>{let e=d("form","f");return e.noValidate=!0,e.addEventListener("submit",St),e.addEventListener("input",()=>{O.textContent&&E.getAttribute("aria-busy")!=="true"&&N(null)}),e},E=Ce(),O=d("p","e");O.id=Se("err"),O.setAttribute("aria-live","assertive");let se=d("div","hd");se.setAttribute("aria-hidden","true"),_.append(se,F,E),y.append(Z,_);let B=$!=="inline"&&d("button","x");B&&(B.type="button",B.addEventListener("click",()=>D("close")),_.append(B),Z.addEventListener("click",()=>D("close"))),L.append(y);let n={step:null,mode:$,size:"md",modal:!1,mobile:h?.device==="mobile",answers:{},answeredOn:{},sent:new Set,clicked:!1,seen:new Set,receipt:null,claim:o.coupon?{code:o.coupon}:h?{code:"WELCOME15"}:null,claiming:null,touched:!1,toWarm:new Set,warmed:o.warmed??new Set,warming:!1,owed:!1,unclaimed:!1,misses:0,submitted:!1,pow:null,wheel:null,timers:[],codes:[],videos:[],closed:!1},J=r.locale||document.documentElement.lang,Te=(r.questions.some(ke)||a.steps.some(e=>e.blocks.some(t=>t?.t==="countdown"||t?.display==="cards")))&&o.loadAnswers().catch(()=>null),Le=new WeakMap,Oe=()=>{let e=M(v.button)?v.button:{};y.className=`s ${n.mode}${W?` p-${W}`:""} b-${H(["pill","rounded","square"],e.shape,"rounded")}${n.mobile?" mob":""}${h?" pv":""}${e.style==="outline"?" bo":""}${v.caps===!0?" uc":""}`},Q=h?null:globalThis.matchMedia?.("(max-width: 639px)"),Me=()=>{n.mobile=Q?.matches===!0,pe(),Oe()};Q&&(n.mobile=Q.matches===!0,Q.addEventListener?.("change",Me));let ae=!r.channels?.length,G=(e,t,i={})=>{if(!(h||!l.decision_id||!p.analytics())){if(e==="click"){let s=n.clicked;if(n.clicked=!0,s&&!i.products)return}x.slotEngaged({decision_id:l.decision_id,slot:l.slot,arm:l.arm??null,engagement:e,step:t??n.step?.id??null,...i})}},N=(e,t)=>{O.className="e",O.textContent=e??"";for(let s of E.querySelectorAll("[aria-invalid]"))s.removeAttribute("aria-invalid");let i=t?.closest("label,fieldset");i&&E.contains(i)?i.after(O):E.append(O),t&&(t.setAttribute("aria-invalid","true"),t.setAttribute("aria-describedby",O.id),t.focus(),t.scrollIntoView?.({block:"nearest"}))},V=e=>{E.setAttribute("aria-busy",String(e));for(let t of E.querySelectorAll("button"))t.disabled=e},Ie=()=>h?Promise.resolve(null):(n.pow??(n.pow=b.challenge().then(e=>e.status===200?Ge(e.body):null).catch(()=>null)),n.pow),le=()=>{for(let e of n.videos)try{document.hidden||Ae()?e.pause():e.play()?.catch?.(()=>{})}catch{}};document.addEventListener("visibilitychange",le);function ce(e,t,i,s,c){let u=K(e.asset);if(!u)return null;let g=typeof e.alt=="string"?e.alt:"",m;if(Ee(e)){m=d("video",t),m.muted=m.defaultMuted=m.loop=m.playsInline=!0;let A=K(e.poster);A&&(m.poster=A),g?m.setAttribute("aria-label",g):m.setAttribute("aria-hidden","true"),m.autoplay=!Ae()&&!h,m.preload=m.autoplay?"auto":A?"none":"metadata";let z=Wt(e,u);if(z.length>1)for(let P of z){let q=d("source");q.src=P;let Y=_e(P);Y&&(q.type=Y),m.append(q)}else m.src=u;n.videos.push(m)}else{m=d("img",t),m.alt=g,m.decoding="async",m.loading=i?"eager":"lazy",i&&(m.fetchPriority="high");let A=ct(e,u,I(e.width,1,8192));A&&(m.sizes=at(n.mode,n.size,s,c),m.srcset=A),m.src=u}let f=I(e.width,1,8192),k=I(e.height,1,8192);return f&&k&&(m.width=f,m.height=k),M(e.focal)&&(m.style.objectPosition=`${I(e.focal.x,0,100)??50}% ${I(e.focal.y,0,100)??50}%`),m}function Pe(e,t){let i=d("label","l");i.append(d("span","lt",e.label??(t==="email"?"Email":"Mobile number")));let s=d("input","i");if(s.type=t,s.name=t==="email"?"email":"phone",s.autocomplete=s.inputMode=t,s.required=!0,typeof e.placeholder=="string"&&(s.placeholder=e.placeholder),s.setAttribute("aria-describedby",O.id),s.addEventListener("focus",Ie,{once:!0}),t!=="tel")return i.append(s),i;s.id=`${O.id}-p`,i.htmlFor=s.id;let c=xe(d,"Country code","+",Object.entries(ge).map(([g,m])=>[g,`${g} +${m}`]),(e.country||/-(\w\w)$/.exec(J)?.[1]||"").toUpperCase());c.classList.add("cc"),c.name="hp_cc";let u=d("span","ph");return u.append(c,s),i.append(u),i}function ft(e){let t=r.questions.find(f=>f.key===e.question);if(!t||!ke(t)&&!Array.isArray(t.options))return null;let i=d("fieldset");i.dataset.question=t.key,i.append(d("legend","",t.label??""));let s=n.answers[t.key]??[],c=e.display==="cards"&&t.type==="one";if(ke(t)||c)return Te.then(f=>{if(!f)return i.append(d("p","sm",S.unavailable));if(c)return f.answerCards(i,t,e,d,s,k=>ce(k,"qi",!1,lt(n.size,t),"50vw"),L);f.answerFields(i,t,d,s[0],J),Le.set(i,()=>f.answerOf(i,t,void 0,J))}),i;let u=t.type==="many",g=H(["list","dropdown"],e.display,"buttons"),m=t.options.filter(f=>M(f)&&typeof f.value=="string");if(g==="dropdown"&&!u)return i.append(xe(d,t.label??t.key,"\u2014",m.map(f=>[f.value,f.label??f.value]),s[0])),i;g!=="buttons"&&(i.className="ls");for(let f of m){let k=d("label",g==="buttons"?"ch":"c"),A=d("input");A.type=u?"checkbox":"radio",A.name=`q_${t.key}`,A.value=f.value,A.checked=s.includes(f.value),k.append(A,d("span","",f.label??f.value)),i.append(k)}return i}function ne(){for(let e of n.codes){if(e.replaceChildren(),!n.claim){n.unclaimed&&e.append(d("p","",S.unclaimed));continue}if(!n.claim.code){let s=n.claim.held?S.claimed:n.claim.fallback===!0?S.code:n.claim.prize?.label;s&&e.append(d("p","",s));continue}n.claim.prize?.label&&e.append(d("p","",n.claim.prize.label));let t=d("output");t.textContent=n.claim.code;let i=d("button","btn cp");i.type="button",i.textContent="Copy code",i.addEventListener("click",()=>{navigator.clipboard?.writeText(n.claim.code).then(()=>{i.textContent=S.copied}).catch(()=>{})}),e.append(t,i)}}function mt(e){if(n.claim&&!n.claim.code)return null;let t=d("div","cd");return t.hidden=!0,Te.then(i=>i&&t.isConnected&&n.timers.push(i.countdown(t,e,h,d))),t}function de(e,t){return e.href=t,e.rel="noopener",e.addEventListener("click",i=>{if(h)return i.preventDefault();G("click"),We()}),e}function ht(e){let t=e.label??"Continue";if(e.action==="link"){let s=X(e.href);return s?de(d("a",`btn${nt[e.variant]??""}`,t),s):null}let i=d("button",`btn${nt[e.variant]??""}`,t);return i.type=e.action==="submit"?"submit":"button",i.type==="button"?i.addEventListener("click",()=>re(e)):i.dataset.submit="",i}let qe=(e,t,i)=>(e.classList.add(`x-${H(Pt,t.size,i)}`),qt.includes(t.align)&&e.classList.add(`a-${t.align}`),e);function Ne(e){let t=ce(e,"bi",n.step===a.steps[0]);if(!t)return null;t.style.objectFit=e.fit==="contain"?"contain":"cover";let i=I(e.radius,0,48);i!==null&&(t.style.borderRadius=`${i}px`);let s=I(e.max_height,40,800);if(s!==null&&(t.style.maxHeight=`${s}px`),!t.width&&e.fit!=="contain"&&(t.style.aspectRatio="16 / 9"),e.t==="video"||!X(e.href))return t;let c=de(d("a","bl"),X(e.href));return c.append(t),c}function bt(e){let t=I(e.threshold,.01,1e7);if(!t)return null;let i=d("div","pg"),s=d("p"),c=d("div","tr"),u=d("i");c.append(u),c.setAttribute("role","progressbar"),c.setAttribute("aria-valuemin","0"),c.setAttribute("aria-valuemax",String(t)),i.append(s,c);let g=f=>f.toFixed(2);try{let f=new Intl.NumberFormat(J||void 0,{style:"currency",currency:e.currency});g=k=>f.format(k)}catch{}let m=()=>{let f=Math.max(0,Number(o.basket?.())||0),k=t-f;s.textContent=k>0?String(e.text??"").replace("{amount}",g(k)):e.done??"",u.style.transform=`scaleX(${Math.min(1,f/t)})`,c.setAttribute("aria-valuenow",String(Math.min(f,t))),s.id||(s.id=Se("pg")),c.setAttribute("aria-labelledby",s.id)};return m(),n.timers.push(setInterval(m,2e3)),i}function gt(e){let t=d("div","pr");return o.loadProducts?.().then(i=>{t.isConnected&&n.timers.push(i.mountProducts(t,e,{el:d,lang:J,root:L,placement:r.slot,preview:h,client:!h&&p.analytics()&&x,engaged:G,seen:n.seen}))}).catch(()=>{}),t}let je={heading(e){let t=qe(d("h2","",e.text),e,"xl");return t.id=Se("h"),t.tabIndex=-1,y.hasAttribute("aria-labelledby")||(y.setAttribute("aria-labelledby",t.id),n.step===a.steps[0]&&Je.includes(n.mode)&&!h&&(t.autofocus=!0)),t},text:e=>qe(d("p","",e.text),e,"md"),email:e=>Pe(e,"email"),phone:e=>Pe(e,"tel"),consent(e){let t=C(n.step)?.text;if(typeof t!="string")return null;if(e.required!==!0)return d("p","sm",t);let i=d("label","c"),s=d("input");return s.type="checkbox",s.name="hp_consent",s.required=!0,s.setAttribute("aria-describedby",O.id),i.append(s,d("span","",t)),i},question:ft,wheel(){let e=d("div","wh");return o.loadWheel().then(t=>{n.closed||(n.wheel=t.mountWheel(e,r.prizes))}).catch(()=>{}),e},code(){let e=d("div","k");return e.setAttribute("aria-live","polite"),n.codes.push(e),e},button:ht,decline(e){let t=d("button","btn no",e.label??"No thanks");return t.type="button",t.addEventListener("click",()=>D("decline")),t},countdown:mt,progress:bt,products:gt,image:Ne,video:Ne,spacer(e){let t=d("div","sp");return t.style.height=`${et[e.size]??et.md}px`,t.setAttribute("aria-hidden","true"),t},divider:()=>d("hr")};function xt(e,t){F.replaceChildren();let i=e.media,s=!i||t&&e.template!=="image-only";if(n.size=st(v,e),_.className=`w t-${e.template} z-${n.size}${e.side==="right"?" right":""}${v.text_align==="center"?" ta-center":""}${s?" nm":""}`,_.style.setProperty("--sc",String(e.scrim)),E.className=`f pd-${e.padding}`,F.hidden=s,F.hidden)return;let c=ce(i,"",n.step===a.steps[0],e.template==="split"?.46:1);if(!c)return;if(c.width?_.style.setProperty("--ar",`${c.width} / ${c.height}`):_.style.removeProperty("--ar"),e.template!=="image-only"){c.tagName==="IMG"&&e.template==="overlay"&&(c.alt=""),F.append(c);return}let u=X(i.href),g=u?de(d("a","io"),u):d("button","io");u||(g.type="button",g.addEventListener("click",()=>re({action:"next"}))),g.append(c),F.append(g)}function yt(e){let t=e.blocks.find(c=>c?.t==="heading"),i=e.blocks.find(c=>c?.t==="button"&&c.action==="next"),s=d("button","tb");return s.textContent=t?d("b","",t.text).textContent:i?.label??"Open",s.type="button",s.addEventListener("click",()=>re(i??{action:"next"})),s}function R(e,t=new Set){let i=a.steps.find(z=>z.id===e);if(!i)return D("done");if(i.kind==="question"&&!h&&!p.analytics()&&!t.has(i.id))return R(ee(i,n.answers),t.add(i.id));let s=n.step!==null,c=s&&(L.activeElement||document.activeElement===document.body),u=s&&!h?{mode:n.mode,w:_.offsetWidth,h:_.offsetHeight,top:_.offsetTop}:null;n.step=i,n.touched=!1;for(let z of n.timers.splice(0))it(z);n.codes=[],n.videos=[],n.wheel=null;let g=$==="teaser"&&i===a.steps[0];if(n.mode=$==="teaser"&&!g?"popup":$,$==="teaser"&&w.tab?.(r.slot,g),B&&B.setAttribute("aria-label",g?S.closeOffer:"Close"),Oe(),y.removeAttribute("aria-labelledby"),u){let z=Ce();E.replaceWith(z),E=z}let m=rt(i);xt(m,g);let f=u?.mode==="popup"&&n.mode==="popup";if(pe(),u?.mode===n.mode&&u.h>0&&!f&&(_.style.setProperty("--lw",`${u.w}px`),_.style.setProperty("--lh",`${u.h}px`),_.classList.add("lk")),E.replaceChildren(),g&&m.template!=="image-only")E.append(yt(i));else for(let[z,P]of i.blocks.entries()){let q=M(P)&&Object.hasOwn(je,P.t)?je[P.t](P):null;q&&(h&&(q.dataset.hpBlock=String(z)),E.append(q))}let k=E.querySelector("[data-submit]"),A=E.querySelector("[name=hp_consent]")?.parentNode;k&&A&&k.before(A),E.hidden=E.childElementCount===0,N(null),ne(),y.hasAttribute("aria-labelledby")?y.removeAttribute("aria-label"):y.setAttribute("aria-label",m.media?.alt?.trim?.()||"Sign up"),f&&u.h>0&&vt(u),s&&Re(),le(),h||wt(i),c&&E.querySelector("h2")?.focus()}function pe(){_.classList.remove("lk","an"),_.style.removeProperty("--tp")}function vt(e){let t=_.offsetHeight;_.classList.add("an");let i=_.offsetTop,s=Math.max(0,e.top-i);if(s+t>y.clientHeight-2*i)return pe();_.style.setProperty("--tp",`${s}px`)}function wt(e){let t=e.next??{};for(let c of[t.default,...Object.values(M(t.answers)?t.answers:{}),...e.blocks.map(u=>u?.next),...jt])typeof c=="string"&&n.toWarm.add(c);if(n.warming)return;n.warming=!0;let i=()=>{if(n.warming=!1,!n.closed&&T.isConnected)for(let c of n.toWarm)ze(r,a,c,n.warmed);n.toWarm.clear()},s=()=>globalThis.requestIdleCallback?requestIdleCallback(i,{timeout:2e3}):setTimeout(i,200);document.readyState==="complete"?s():window.addEventListener("load",s,{once:!0})}function Re(){if(!j)return;let e=Je.includes(n.mode);if(!(y.open&&n.modal===e)){try{y.open&&y.close()}catch{}if(n.modal=e,y.setAttribute("aria-modal",String(e)),e&&typeof y.showModal=="function")y.showModal();else if(typeof y.show=="function"){let t=document.activeElement;y.show(),t&&t!==document.body?t.focus?.({preventScroll:!0}):T.blur()}else y.setAttribute("open","");!e||typeof y.showModal!="function"?y.setAttribute("role","dialog"):y.removeAttribute("role")}}function De(){for(let e of E.querySelectorAll("fieldset[data-question]")){let t=e.dataset.question,i=Le.get(e)?.()??{};if(i.error)return i;let s=[i.value,...[...e.querySelectorAll("input:checked,select:not([name])")].map(c=>c.value)].filter(Boolean);s.length?(n.answers[t]=s,n.answeredOn[t]=n.step.id):delete n.answers[t]}}function Ue(){let e=Object.entries(n.answers).map(([i,s])=>({question:i,values:s})).filter(i=>!n.sent.has(ue(i))),t=({question:i})=>n.answeredOn[i];if(n.signedUp){for(let i of new Set(e.map(t))){let s=e.filter(c=>t(c)===i);for(let c of s)n.sent.add(ue(c));b.answers({anonymousId:p.anonymousId(),sessionId:p.sessionId()??void 0,slot:l.slot,arm:l.arm??void 0,decision_id:l.decision_id??void 0,step:i,...n.signedUp,answers:s,context:Fe()})}return}if(p.analytics())for(let i of e)n.sent.add(ue(i)),x.preferencesStated({...i,source:"onsite",slot:l.slot,arm:l.arm??null,decision_id:l.decision_id??null,step:t(i)})}let ue=({question:e,values:t})=>`${e}=${t.join(",")}`,We=()=>{ae&&(De(),Ue())},Fe=()=>({page:{url:p.pageUrl()},locale:p.locale()??void 0,consent:p.consent()}),ie=e=>{!h&&(n.receipt||ae)&&Ue(),R(ee(n.step,n.answers,e))};async function kt(e){let t=n.step,i=E.querySelector("input[name=email],input[name=phone]");if(!i)return ie(e.next);let s=i.name==="email"?"email":"sms",c=E.querySelector("select[name=hp_cc]")?.value,u=s==="email"?Ke(i.value.trim())?i.value.trim():null:Xe(i.value,c);if(!u)return N(s==="email"?S.email:c?S.phone:S.intl,i);let g=E.querySelector("input[name=hp_consent]");if(g&&!g.checked)return N(S.consent,g);N(null),V(!0);let m=await Ie();n.pow=null;let f=Object.entries(n.answers).map(([U,he])=>({question:U,values:he})),k=s==="sms"?r.sms_consent_text:r.consent_text,A=await b.capture({anonymousId:p.anonymousId(),sessionId:p.sessionId()??void 0,slot:l.slot,arm:l.arm??void 0,decision_id:l.decision_id??void 0,step:t.id,channel:s,[s==="email"?"email":"phone"]:u,...s==="sms"&&n.signedUp,consent_text:k?{id:k.id,version:k.version}:void 0,...f.length?{answers:f}:{},...m?{altcha:m}:{},context:Fe()}),z=A.body?.status,P=(A.status===202||A.status===200)&&Mt.includes(z);if(n.closed&&!P)return;P||V(!1);let q=A.status===400?A.body?.field:null;if(q==="email"||q==="phone")return N(S[q],i);if(!P)return N(A.status===429?S.busy:S.failed,i);i.value="";for(let[U,he]of Object.entries(n.answers))n.sent.add(`${U}=${he.join(",")}`);n.receipt=typeof A.body.receipt=="string"?A.body.receipt:null,s==="email"&&(n.signedUp={email:u,email_receipt:n.receipt}),n.submitted=!0,w.submitted(r.slot),G("submit",t.id),n.owed=s==="email"&&r.prizes.length>0;let Y=n.owed?fe([]):null;Y||o.emit?.("submitted",{coupon:null});let $t=Y&&await Promise.race([Y,new Promise(U=>setTimeout(U,Dt))]);if(n.closed)return;if(V(!1),$t?.held)return R(oe("held"));let _t=z!=="ok"&&a.steps.some(U=>U.id===z);R(_t?z:ee(t,n.answers,e.next));let zt=n.step;Y?.then(U=>{U?.held&&!n.closed&&n.step===zt&&!n.touched&&R(oe("held"))})}function oe(e){if(a.steps.some(s=>s.id===e))return e;let t={t:"button",label:S.shop,action:"close"},i=e==="unclaimed"?[{t:"heading",text:S.thanks},{t:"text",text:S.unclaimed},t]:e==="fallback"||n.claim?.code?[{t:"heading",text:e==="fallback"?S.thanks:S.yours},{t:"code"}]:[{t:"heading",text:S.held},{t:"text",text:r.code_relayed===!0?S.resent:S.inbox},t];return a.steps.push({id:e,blocks:i}),e}function Ye(e){n.owed&&(n.owed=!1,o.emit?.("submitted",{coupon:e?{code:e.code??null,prize:e.prize?.key}:null}))}function fe(e=Rt){let t=n.receipt;return n.claiming??(n.claiming=(async()=>{n.unclaimed=!1;let i;for(let g of[0,...e])if(g&&await new Promise(m=>setTimeout(m,g)),i=await b.claim({slot:l.slot,decision_id:l.decision_id??void 0,receipt:t}),i.status!==503)break;let s=i.body,c=s?.fallback===!0&&!s.code;if(i.status!==200||!(M(s?.prize)||c))return n.claiming=null,!e.length&&i.status===503?fe():(Ye(null),n.unclaimed=!0,n.closed||ne(),null);let u=s.held&&!s.code?w.code?.():null;return u&&(s={...s,code:u}),n.claim=s,typeof s.code=="string"&&w.code?.(s.code),Ye(s),n.closed||ne(),s})()),n.claiming}async function At(e){if(!n.receipt)return N(S.spin);V(!0);let t=await fe();if(n.closed)return;if(!t)return V(!1),n.misses+=1,n.misses<2?N(S.retry):R(oe("unclaimed"));let i=t.fallback===!0&&!t.code,s=t.held?-1:r.prizes.findIndex(g=>g.key===t.prize?.key&&g.label===t.prize?.label);if(n.wheel&&s>=0&&!i){if(await n.wheel.spinTo(s),n.closed)return;O.className="e won",O.textContent=`${S.won} ${t.prize.label}`,await new Promise(g=>setTimeout(g,Ut))}if(n.closed)return;V(!1);let c=i?"fallback":s<0?"held":null,u=c?oe(c):ee(n.step,n.answers,e.next);u?R(u):ne()}function re(e){if(e.action==="close")return D("close");let t=De();return h?ie(e.next):t?N(t.error,t.input):(ae&&n.step.blocks.some(i=>n.answers[i?.question])&&G("click"),e.action==="apply"?(o.emit?.("apply",{coupon:n.claim?.code?{code:n.claim.code}:null}),G("click"),ie(e.next)):e.action==="submit"?kt(e):e.action==="spin"?At(e):ie(e.next))}function St(e){if(e.preventDefault(),E.getAttribute("aria-busy")==="true")return;let t=n.step.blocks.find(i=>i?.t==="button"&&i.action==="submit");re(t??{action:"next"})}function me(e=!1){n.closed=!0;for(let i of n.timers.splice(0))it(i);document.removeEventListener("visibilitychange",le),Q?.removeEventListener?.("change",Me);let t=()=>{try{y.open&&y.close()}catch{}T.remove()};if(e||!j||Ae())return t();y.classList.add("out"),setTimeout(t,Nt)}function D(e){n.closed||h||(We(),!n.submitted&&e!=="done"&&G("dismiss"),w.closed(r.slot),w.tab?.(r.slot,!1),me(),o.onClose?.(e))}for(let e of["pointerdown","keydown","input"])y.addEventListener(e,()=>{n.touched=!0});y.addEventListener("cancel",e=>{e.preventDefault(),D("esc")}),y.addEventListener("keydown",e=>{e.key==="Escape"&&!n.modal&&$!=="inline"&&D("esc"),e.key==="Tab"&&n.modal&&Et(e)});function Et(e){let t=[...L.querySelectorAll("input[type=radio]:checked")],i=new Set,s=[...L.querySelectorAll("a[href],button,input,select,textarea")].filter(f=>{if(f.disabled||!f.getClientRects().length)return!1;if(f.type!=="radio")return!0;let k=t.find(A=>A.name===f.name);return(k?f!==k:i.has(f.name))?!1:(i.add(f.name),!0)});if(!s.length)return;let c=e.shiftKey,u=L.activeElement;u?.type==="radio"&&(u=s.find(f=>f.type==="radio"&&f.name===u.name)??u);let g=s.indexOf(u),m=null;if(g<0){let f=k=>u&&u.compareDocumentPosition(k)&4;m=c?s.findLast(k=>!f(k))??s.at(-1):s.find(f)??s[0]}else(c?g===0:g===s.length-1)&&(m=s.at(c?-1:0));m&&(e.preventDefault(),m.focus())}se.addEventListener("pointerdown",e=>{if(!n.mobile||n.mode!=="sheet")return;let t=e.clientY,i=0,s=u=>{i=Math.max(0,u.clientY-t),_.style.transform=`translateY(${i}px)`},c=()=>{document.removeEventListener("pointermove",s),document.removeEventListener("pointerup",c),_.style.transform="",i>80&&D("close")};document.addEventListener("pointermove",s),document.addEventListener("pointerup",c)});try{R(h?.step&&a.steps.some(e=>e.id===h.step)?h.step:a.steps[0].id),(o.container??document.body).append(T),Re()}catch(e){throw me(!0),e}return{close:D,root:L,host:T,show:R,step:()=>n.step?.id??null,modal:()=>!n.closed&&n.modal,destroy:()=>!n.closed&&me()}}window[Symbol.for("@thg-agentic/hyper-personalisation-web.onsite.render")]={mountForm:ut,warm:ze};})();
|
package/dist/onsite-wheel.min.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
(()=>{function
|
|
1
|
+
(()=>{function v(e,o,n=5){let s=360/o;return n*360+(360-(e+.5)*s)}var w="http://www.w3.org/2000/svg",L=4500,S=.22,F=.95,P=.105,z=.082,A=.062,I=.62,O=1.15,$="var(--hp-accent,#111)",k="var(--hp-on-accent,#fff)",g="var(--hp-bg,#fff)",N="var(--hp-text,#111)";function c(e,o={}){let n=document.createElementNS(w,e);for(let[s,i]of Object.entries(o))n.setAttribute(s,String(i));return n}function d(e,o,n,s=1){return e.style.fill=o,s<1&&(e.style.fillOpacity=String(s)),n&&(e.style.stroke=n),e}var q=()=>globalThis.matchMedia?.("(prefers-reduced-motion: reduce)")?.matches===!0,T=(e,o=1)=>{let n=(e-90)*Math.PI/180;return`${(o*Math.cos(n)).toFixed(4)} ${(o*Math.sin(n)).toFixed(4)}`};function j(e,o){let n=F-S,s=2*.35*Math.sin(Math.min(Math.PI/o,Math.PI/2)),i=t=>Math.max(z,Math.min(P,s/(t*O))),a=t=>n/(Math.max(1,t.length)*I),r=[...e.matchAll(/ /g)].map(t=>t.index),u=e.length/2,p=r.length?r.reduce((t,l)=>Math.abs(l-u)<Math.abs(t-u)?l:t):-1,h=p<0?null:[e.slice(0,p),e.slice(p+1)];for(let t of[z,A]){let l=a(e);if(l>=t)return{lines:[e],size:Math.min(i(1),l)};if(h){let m=Math.min(i(2),...h.map(a));if(m>=t)return{lines:h,size:m}}}let f=Math.floor(n/(A*I));return{lines:[`${e.slice(0,f-1).trimEnd()}\u2026`],size:A}}function C(e){let o=F-S,n=s=>s.getComputedTextLength?.()??0;for(let s of e){let i=[...s.querySelectorAll("tspan")],a=Math.max(0,...i.map(n));if(!(a>o))continue;let r=Math.max(A,Number(s.getAttribute("font-size"))*o/a);s.setAttribute("font-size",r.toFixed(4)),i.forEach((u,p)=>{u.setAttribute("y",((p-(i.length-1)/2)*r*O).toFixed(4)),n(u)>o&&(u.setAttribute("textLength",o.toFixed(4)),u.setAttribute("lengthAdjust","spacingAndGlyphs"))})}}function R(e,o){let n=(Array.isArray(o)?o:[]).map(f=>String(f?.label??f?.key??"")),s=n.length;if(s<2)return null;let i=360/s,a=c("svg",{viewBox:"-1.2 -1.2 2.4 2.4",role:"img","aria-label":`Prize wheel: ${n.join(", ")}`}),r=c("g");r.style.transformBox="fill-box",r.style.transformOrigin="50% 50%";let u=[[1,k],[.14,N],[.72,k]];r.append(d(c("circle",{r:1}),g));let p=[],h=[];return n.forEach((f,t)=>{let[l,m]=u[s%2===1&&t===s-1?2:t%2];r.append(d(c("path",{d:`M0 0L${T(t*i)}A1 1 0 ${i>180?1:0} 1 ${T((t+1)*i)}Z`,"stroke-width":.012}),$,g,l));let b=(t+.5)*i-90,x=j(f,s),_=d(c("text",{transform:`rotate(${b}) translate(${(S+F)/2} 0)${b>90&&b<270?" rotate(180)":""}`,"text-anchor":"middle","dominant-baseline":"central","font-size":x.size.toFixed(4),"font-weight":700,"aria-hidden":"true"}),m);x.lines.forEach((E,M)=>{let y=c("tspan",{x:0,y:((M-(x.lines.length-1)/2)*x.size*O).toFixed(4)});y.textContent=E,_.append(y)}),r.append(_),h.push(_);for(let E of[t*i,(t+.5)*i]){let[M,y]=T(E,1.075).split(" ");p.push(d(c("circle",{cx:M,cy:y,r:.024}),g))}}),a.append(d(c("circle",{r:1.13}),N),...p,r,d(c("circle",{r:.17,"stroke-width":.035}),g,N),d(c("circle",{r:.065}),$),d(c("path",{d:"M-0.12 -1.2L0.12 -1.2L0 -0.86Z","stroke-width":.03,"stroke-linejoin":"round"}),$,g)),e.append(a),C(h),globalThis.requestAnimationFrame?.(()=>C(h)),{spinTo(f){let t=q();return r.style.transition=t?"none":`transform ${L}ms cubic-bezier(.15,.7,.1,1)`,r.style.transform=`rotate(${v(f,n.length,t?0:5)}deg)`,t?Promise.resolve():new Promise(l=>{let m=setTimeout(l,L+200);r.addEventListener("transitionend",()=>{clearTimeout(m),l()},{once:!0})})},remove:()=>a.remove()}}window[Symbol.for("@thg-agentic/hyper-personalisation-web.onsite.wheel")]={mountWheel:R};})();
|
package/dist/onsite.min.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
(()=>{function _(e){let s=typeof document>"u"?null:document.currentScript?.src;return s?new URL(e,s).href:null}var X=new Map;function A(e,s){return window[s]?Promise.resolve(window[s]):e?(X.has(s)||X.set(s,new Promise((n,i)=>{let c=document.createElement("script");c.src=e,c.async=!0,c.onload=()=>window[s]?n(window[s]):i(new Error(`${e} did not register`)),c.onerror=()=>i(new Error(`${e} did not load`)),document.head.append(c)}).finally(()=>X.delete(s))),X.get(s)):Promise.reject(new Error("the CDN script\u2019s own URL is unknown"))}var He=_("onsite-answers.min.js"),ue=()=>A(He,Symbol.for("@thg-agentic/hyper-personalisation-web.onsite.answers"));var Xe="/v1/capture/challenge",ze=e=>typeof e=="string"&&/^\/v1\/[\w/-]+$/.test(e)?e:Xe;function de(e,s={}){let n=s.fetch??globalThis.fetch?.bind(globalThis),i=s.servingHost??e.servingHost,c=s.gatewayHost??e.gatewayHost;async function r(d,{method:p="GET",body:o,consent:l=!1,timeoutMs:a}={}){if(!n)return{status:0,body:null};try{let w=await n(d,{method:p,credentials:"omit",signal:a&&AbortSignal.timeout?.(a),headers:{accept:"application/json",authorization:`Bearer ${e.writeKey}`,...o?{"content-type":"application/json"}:{},...l?e.headers():{}},...o?{body:JSON.stringify(o)}:{}}),b=null;try{b=await w.json()}catch{}return{status:w.status,body:b}}catch{return{status:0,body:null}}}return{decide:(d,p,{visitAudiences:o,visitCampaign:l,visitContext:a}={})=>r(`${i}/v1/decisions`,{method:"POST",consent:!0,body:{slots:[p?{key:d,pin:{experiment:p[0],arm:p[1],split:p[2]}}:d],identifier_value:e.anonymousId()??void 0,session_id:e.sessionId()??void 0,identity_token:e.identityToken?.()??void 0,...e.preview?{preview:e.preview}:{},...o?{visit_audiences:o}:{},...l?{visit_campaign:l}:{},...a?{visit_context:a}:{}}}),datafile:()=>r(`${i}/v1/audiences/datafile`,{timeoutMs:1500}),challenge:()=>r(`${c}${ze(s.challenge)}`),capture:d=>r(`${c}/v1/capture`,{method:"POST",body:d}),answers:d=>r(`${c}/v1/capture/answers`,{method:"POST",body:d}),claim:d=>r(`${i}/v1/offers/claim`,{method:"POST",consent:!0,body:d,timeoutMs:8e3})}}var Ve=_("onsite-audiences.min.js"),pe=()=>A(Ve,Symbol.for("@thg-agentic/hyper-personalisation-web.onsite.audiences"));function fe(e,s){let n={},i=()=>{try{let r=JSON.parse(e().getItem(s));r&&typeof r=="object"&&(n=r)}catch{}return n};return{read:i,write:r=>{let d=i();r(d),n=d;try{e().setItem(s,JSON.stringify(d))}catch{}}}}function he(e,s=()=>!0){let n=fe(()=>sessionStorage,e),i=fe(()=>localStorage,e),c=()=>s()?i:n,r=()=>{let o=i.read();(o.sub!==void 0||o.k!==void 0)&&i.write(l=>{delete l.sub,delete l.k})},d=()=>s()?[n.read(),i.read()]:(r(),[n.read()]),p=(o,l)=>{var a;return o.f??(o.f={}),(a=o.f)[l]??(a[l]={}),o.f[l]};return{seen(o){let l=i.read().f?.[o]??{};return{session:n.read().f?.[o]?.n??0,lifetime:l.n??0,closedAt:l.c??null,submitted:l.s===1}},subscribed:()=>d().some(o=>o.sub===1),shown(o){n.write(l=>{let a=p(l,o);a.n=(a.n??0)+1}),i.write(l=>{let a=p(l,o);a.n=(a.n??0)+1})},closed(o,l=Date.now()){i.write(a=>{p(a,o).c=l})},tab(o,l){n.write(a=>{let w=p(a,o);l?w.t=1:delete w.t})},tabOut:o=>n.read().f?.[o]?.t===1,pin(o,l){if(l===void 0)return n.read().f?.[o]?.p??null;n.write(a=>{p(a,o).p=l})},coveredAt:()=>n.read().o??null,covered(o=Date.now()){n.write(l=>{l.o=o})},code(o,l=Date.now()){if(o===void 0){let[a]=d().flatMap(w=>w.k?[w.k]:[]).sort((w,b)=>b.at-w.at);return a&&l-a.at<14*864e5?a.c:null}return c().write(a=>{a.k={c:o,at:l}}),o},submitted(o){i.write(l=>{p(l,o).s=1}),c().write(l=>{l.sub=1})}}}var Ge=_("onsite-products.min.js"),z=()=>A(Ge,Symbol.for("@thg-agentic/hyper-personalisation-web.onsite.products"));var Be=_("onsite-render.min.js"),ge=()=>A(Be,Symbol.for("@thg-agentic/hyper-personalisation-web.onsite.render"));var qe=["source","medium","campaign","content","term"];var me=e=>String(e).trim().toLowerCase();function Je(e,s,n){let i=me(e),c=me(n);return s==="is"?i===c:s==="contains"&&c!==""&&i.includes(c)}function we(e,s){return(Array.isArray(e)?e:[]).every(n=>{let i=s?.[n?.field];return!qe.includes(n?.field)||typeof i!="string"?!1:[].concat(n.values??[]).some(c=>Je(i,n.match,c))})}var _e=["popup","sheet","bar","teaser","inline","fullscreen"],Ze=["entry","exit","scroll","time","idle","inline","manual"],ee=e=>e!=="inline",Ae=e=>e==="popup"||e==="sheet"||e==="fullscreen",S=e=>e!==null&&typeof e=="object"&&!Array.isArray(e),k=e=>Array.isArray(e)?e.filter(s=>typeof s=="string"):[],ye=e=>Number.isInteger(e)&&e>=0?e:null,Qe={field:null,match:null,values:[]},et=e=>e==null?[]:Array.isArray(e)&&e.every(S)?e:[Qe];function ve(e){if(!S(e)||typeof e.slot!="string"||e.slot==="")return null;let s=S(e.trigger)?e.trigger:{};if(!_e.includes(e.format)||!Ze.includes(s.type))return null;let n=S(e.caps)?e.caps:{};return{...e,trigger:s,priority:Number.isFinite(e.priority)?e.priority:0,pages:S(e.pages)?e.pages:{},devices:k(e.devices),aliases:k(e.aliases),audiences:k(e.audiences),arrived_from:et(e.arrived_from),caps:{per_session:ye(n.per_session),lifetime:ye(n.lifetime),after_close_days:Number.isFinite(n.after_close_days)?n.after_close_days:null},window:S(e.window)?e.window:{},questions:Array.isArray(e.questions)?e.questions.filter(S):[],prizes:Array.isArray(e.prizes)?e.prizes.filter(S):[]}}var tt=/^[a-z][a-z0-9_-]{0,31}$/;function Ee(e){if(!S(e)||e.v!==1||!Array.isArray(e.steps))return null;let s=e.steps.filter(n=>S(n)&&tt.test(n.id)&&Array.isArray(n.blocks));return s.length===0?null:{format:_e.includes(e.format)?e.format:null,theme:S(e.theme)?e.theme:{},steps:s}}function be(e,s){let n=String(e).split("*").map(i=>i.replace(/[.+?^${}()|[\]\\]/g,"\\$&")).join(".*");return new RegExp(`^${n}$`,"i").test(s)}function nt(e,s){let n=k(e?.include);return(!n.length||n.some(i=>be(i,s)))&&!k(e?.exclude).some(i=>be(i,s))}function xe(e){return e.matchMedia?.("(hover: none) and (pointer: coarse)")?.matches===!0||e.innerWidth<768?"mobile":"desktop"}var Se=e=>typeof e=="string"?Date.parse(e):Number.NaN,F=e=>e.trigger.type==="manual";function te(e,s){let n=[];nt(e.pages,s.path)||n.push("page not included"),e.devices.length&&!e.devices.includes(s.device)&&n.push(`not on ${s.device}`),we(e.arrived_from,s.campaign)||n.push("not from its campaign");let i=Se(e.window.starts_at),c=Se(e.window.ends_at);if((s.now<i||s.now>=c)&&n.push("outside its dates"),e.audiences.length&&!s.preview&&(s.personalisation?s.audiences&&!e.audiences.some(p=>s.audiences.includes(p))&&n.push("not in its audiences"):n.push("audiences need personalisation consent")),s.preview||s.asked||F(e))return n;let{seen:r}=s,{caps:d}=e;return r.submitted&&n.push("already submitted"),e.exclude_subscribed===!0&&s.subscribed&&n.push("already subscribed"),d.per_session!==null&&r.session>=d.per_session&&n.push("per_session cap"),d.lifetime!==null&&r.lifetime>=d.lifetime&&n.push("lifetime cap"),d.after_close_days!==null&&r.closedAt&&s.now-r.closedAt<d.after_close_days*864e5&&n.push("closed recently"),n}var Te=(e,s)=>s.priority-e.priority;var st=["mousemove","pointerdown","keydown","scroll","touchstart","wheel"];function ot(){let e=[];return{on:(i,c,r,d={passive:!0})=>{i.addEventListener(c,r,d),e.push(()=>i.removeEventListener(c,r,d))},later:(i,c)=>{let r=setTimeout(i,c);e.push(()=>clearTimeout(r))},stop:()=>{for(let i of e.splice(0))i()}}}var Ie=(e,s)=>{let n=s.documentElement.scrollHeight||0;return n>0?(e.scrollY+e.innerHeight)/n:0},it=e=>{let s=e.activeElement;return!!(s&&(/^(INPUT|TEXTAREA|SELECT)$/.test(s.tagName)||s.isContentEditable))};function rt({on:e,later:s},n,i,c,r){let d=!1,p=!1,o=null,l=0;s(()=>{d=!0},i.delay_ms??5e3),e(r,"mousemove",a=>{a.clientY>c.innerHeight*.1&&(p=!0),o!==null&&(l=a.clientY-o),o=a.clientY}),e(r,"mouseout",a=>{d&&p&&!a.relatedTarget&&a.clientY<=0&&l<0&&!it(r)&&n("exit")})}function lt({on:e,later:s},n,i,c,r){let d=!1,p=0,o=c.scrollY,l=Date.now(),a=null,w=null;s(()=>{d=!0},i.delay_ms??5e3),e(c,"scroll",()=>{let b=c.scrollY,v=Date.now();if(p=Math.max(p,Ie(c,r)),b<o){(!a||v-a.t>300)&&(a={y:o,t:l});let E=a.y-b;d&&p>=.3&&E>=120&&E/Math.max(1,v-a.t)>=.5&&n("exit_scroll")}else a=null;o=b,l=v}),e(r,"visibilitychange",()=>{r.visibilityState==="hidden"?w=Date.now():w!==null&&Date.now()-w>=1e4&&n("return"),r.visibilityState!=="hidden"&&(w=null)})}function Me(e,s,{device:n,win:i=window,doc:c=document}){let r=ot(),d=(e.seconds??30)*1e3;if(e.type==="entry"&&r.later(()=>s("entry"),e.delay_ms??0),e.type==="time"&&r.later(()=>s("time"),d),e.type==="exit"&&(n==="mobile"?lt:rt)(r,s,e,i,c),e.type==="scroll"){let p=e.depth??.5;r.on(i,"scroll",()=>Ie(i,c)>=p&&s("scroll"))}if(e.type==="idle"){let p=null,o=()=>{clearTimeout(p),p=setTimeout(()=>s("idle"),d)};o();for(let l of st)r.on(l==="scroll"?i:c,l,o);return r.on(c,"visibilitychange",o),()=>{clearTimeout(p),r.stop()}}return r.stop}var at=_("onsite-wheel.min.js"),Ce=()=>A(at,Symbol.for("@thg-agentic/hyper-personalisation-web.onsite.wheel"));var Oe=Symbol.for("@thg-agentic/hyper-personalisation-web.onsite-access"),j=Symbol.for("@thg-agentic/hyper-personalisation-web.onsite"),ct=Symbol.for("@thg-agentic/hyper-personalisation-web.onsite.pending"),ut=Symbol.for("@thg-agentic/hyper-personalisation-web.onsite.listeners"),Pe=Symbol.for("@thg-agentic/hyper-personalisation-web.onsite.suppressed"),$e={seen:()=>({session:0,lifetime:0,closedAt:null,submitted:!1}),subscribed:()=>!1,shown(){},closed(){},submitted(){},tab(){},tabOut:()=>!1,pin:()=>null,coveredAt:()=>null,covered(){},code:()=>null},dt=1500,pt=50,ft=300,ht=()=>{try{return new URLSearchParams(location.search).get("hp_debug")==="onsite"}catch{return!1}},gt=e=>Array.isArray(e?.steps)&&e.steps.some(s=>Array.isArray(s?.blocks)&&s.blocks.some(n=>n?.t==="products"));function Ne(e,s={}){if(typeof window>"u"||typeof document>"u")return null;if(window[j])return window[j];let n=typeof e?.[Oe]=="function"?e[Oe]():null;if(!n)return console.warn("[hp] onsite: startOnsite needs the client bootstrap or createAnalytics made"),null;let i=s.settings??n.settings??{},c=de(n,{...s,challenge:i.capture?.challenge}),r=n.preview?$e:he(n.storageKey,n.personalisation),d=()=>n.campaign?.()??null,p=new Map,o=()=>window[Pe]?.size>0,l=(t,u)=>{for(let f of window[ut]?.[t]??[])try{f(u)}catch(g){console.warn(`[hp] onsite ${t} listener failed:`,g)}},a=xe(window),w=n.debug||s.debug===!0||ht(),b=new Map,v=new Map,E=[];for(let t of Array.isArray(i.forms)?i.forms:[]){let u=ve(t);u?E.push(u):b.set(String(t?.slot??`form ${b.size+1}`),{slot:String(t?.slot??""),state:"invalid",reasons:["not a form this SDK can show"]})}let ne=()=>pe().catch(t=>(console.warn("[hp] onsite audiences not loaded:",t?.message??t),null));n.personalisation()&&E.some(t=>t.audiences.length>0)&&ne().then(t=>t?.prefetch(c));let x=new Map,U=new Map,C=null,se=new Set,Re=t=>{for(let u of x.keys()){let f=p.get(u);if(!t||!f||f.modal?.())return u}return null},W=[],V=Number.isInteger(i.overlay_gap_minutes)?i.overlay_gap_minutes:0,De=()=>{let t=r.coveredAt();if(!(V>0)||typeof t!="number")return null;let u=Math.max(0,Math.floor((Date.now()-t)/6e4));return u<V?`a popup showed ${u} min ago; ${V} min between them`:null},N=new Set,K=new Map,m=(t,u,f=[])=>(b.set(t.slot,{slot:t.slot,format:t.format,trigger:t.trigger.type,priority:t.priority,state:u,reasons:f}),w&&console.info(`[hp] onsite ${t.slot}: ${u}${f.length?` (${f.join("; ")})`:""}`),u),oe=()=>{try{let t=s.audiences?.();return Array.isArray(t)?t:null}catch{return null}},ie=t=>({path:location.pathname,device:a,campaign:d(),now:Date.now(),seen:r.seen(t.slot),subscribed:r.subscribed()||s.subscribed?.()===!0,personalisation:n.personalisation(),preview:!!n.preview,audiences:oe()}),G=t=>{v.get(t.slot)?.(),v.delete(t.slot)};function R(t,u,f=!1,g=F(t)){return p.has(t.slot)?Promise.resolve("shown"):(U.has(t.slot)||U.set(t.slot,Le(t,u,f,g).finally(()=>U.delete(t.slot))),U.get(t.slot))}async function Le(t,u,f,g){if(o())return m(t,"not shown",[`suppressed: ${[...window[Pe]].join(", ")}`]);let O=te(t,{...ie(t),...f?{seen:$e.seen()}:{},asked:g});if(O.length)return m(t,"not eligible",O);let T=Ae(t.format)&&!f,Y=T&&!g&&De();if(Y)return m(t,"not shown",[Y]);if(T&&!n.preview&&n.consentAnswered?.()===!1)return K.set(t,g),m(t,"not shown",["waiting for the consent banner"]);let I=ee(t.format),L=I&&Re(g);if(L)return m(t,"not shown",[`${L} is showing`]);if(I&&C&&!g)return m(t,"not shown",[`${C} already showed on this page view`]);let P=null;if(!I){try{P=document.querySelector(t.trigger.selector??"")}catch{P=null}if(!P)return m(t,"not shown",["no element matches its selector"])}I&&x.set(t.slot,t),G(t),m(t,"asking for a decision",[u]);let je=ge().catch(h=>(console.warn("[hp] onsite renderer not loaded:",h?.message??h),null)),H=t.visit_context===!0?z().catch(()=>null):null,q=oe()??[],le=[...new Set([...t.audiences,...q])].filter(h=>q.includes(h)).slice(0,100),Ue=t.audiences.length>0&&!n.preview&&n.personalisation()?await Promise.race([ne().then(h=>h?h.visitAudiences(c,n.sessionSignals,t.audiences,q):le),new Promise(h=>setTimeout(h,dt,le))]):null,$=await c.decide(t.slot,r.pin(t.slot),{visitAudiences:Ue,visitCampaign:t.arrived_from.length?d():null,visitContext:t.visit_context===!0?n.visitContext?.()??null:null}),y=$.status===200?$.body?.decisions?.find(h=>h?.slot===t.slot):null;y?.experiment&&y.arm&&y.split&&r.pin(t.slot,[y.experiment,y.arm,y.split]);let M=y&&y.holdout!==!0?Ee(y.payload):null,ae=M?.steps[0].blocks??[],ce=y?.offer?.code??(n.preview?"PREVIEW":r.code()),We=n.basketValue?.()??null,J=ae.some(h=>h?.t==="code")&&!ce&&"no code to remind of"||ae.some(h=>h?.t==="progress")&&!(We>0)&&"the basket is empty";if(J)return x.delete(t.slot),J==="the basket is empty"&&N.add(t),m(t,"not shown",[J]);if(N.delete(t),!M)return y?.holdout===!0&&n.analytics()&&e.recordExposure($.body),x.delete(t.slot),I&&y?.holdout===!0&&(C??(C=t.slot)),y?.holdout===!0&&!g&&l("held",{slot:t.slot,arm:y.arm??null,format:t.format}),m(t,y?.holdout===!0?"held out":"no decision",[$.status===200?"no creative for this visitor":`decisions answered ${$.status}`]);let Z=await je;if(!Z)return x.delete(t.slot),m(t,"not shown",["the renderer did not load"]);if(gt(M)&&(H??(H=z().catch(()=>null)),!await H))return x.delete(t.slot),m(t,"not shown",["its products did not load"]);if(await Promise.race([Z.warm?.(t,M,M.steps[0].id,se),new Promise(h=>setTimeout(h,ft))]),o())return x.delete(t.slot),m(t,"not shown",["suppressed"]);f||r.shown(t.slot),T&&r.covered(),I&&(C??(C=t.slot));let Q=(h,Ye={})=>l(h,{slot:t.slot,arm:y.arm??null,format:M.format??t.format,...Ye}),Ke=Z.mountForm({form:t,creative:M,decision:y,access:n,client:e,api:c,counters:r,loadWheel:Ce,loadAnswers:ue,loadProducts:()=>H??z(),container:P,warmed:se,coupon:ce,basket:()=>n.basketValue?.()??null,emit:Q,onClose(h){p.delete(t.slot),x.delete(t.slot),m(t,"closed",[h]),Q("closed",{reason:h})}});return p.set(t.slot,Ke),n.analytics()&&e.recordExposure($.body),m(t,"shown",[u]),Q("shown"),"shown"}function B(t,u,f=F(t)){if(!ee(t.format))return R(t,u,!1,f);W.push([t,u,f]),!(W.length>1)&&setTimeout(async()=>{let g=W.sort(([O],[T])=>Te(O,T));W=[];for(let[O,[T,Y,I]]of g.entries()){let L=await R(T,Y,!1,I);if(L==="shown"||L==="held out"){for(let[P]of g.slice(O+1))m(P,"not shown",[`${T.slot} has a higher priority`]);return}}},pt)}for(let t of E){if(t.format==="teaser"&&r.tabOut(t.slot)){R(t,"tab kept from an earlier page",!0);continue}let u=te(t,ie(t));if(u.length){m(t,"not eligible",u);continue}let f=t.trigger.type;f==="manual"?m(t,"waiting for hp.onsite.open"):f==="inline"||t.format==="inline"?R(t,"inline"):re(t)}function re(t){G(t),v.set(t.slot,Me(t.trigger,u=>{G(t),B(t,u)},{device:a})),m(t,"armed",[`${t.trigger.type} on ${a}`])}let ke=n.onConsentAnswered?.(()=>{let t=[...K];K.clear();for(let[u,f]of t)p.has(u.slot)||(f?B(u,"manual",f):re(u))}),Fe=n.onBasket?.(()=>{if(!((n.basketValue?.()??0)>0))return;let t=[...N];N.clear();for(let u of t)p.has(u.slot)||B(u,"the basket changed")}),D=Object.freeze({open(t){let u=E.find(g=>g.slot===t),f=u??E.find(g=>g.aliases.includes(t));return f?p.has(f.slot)?Promise.resolve(!0):R(f,"manual",!1,F(f)||!u).then(g=>g==="shown"):Promise.resolve(!1)},suppress(){for(let[t,u]of p){u.destroy(),p.delete(t),x.delete(t);let f=E.find(g=>g.slot===t);f&&m(f,"closed",["suppressed"])}},debug:()=>[...b.values()].map(t=>({...t,reasons:[...t.reasons]})),stop(){for(let t of v.values())t();v.clear(),Fe?.(),ke?.(),N.clear(),K.clear(),window[j]===D&&delete window[j]}});window[j]=D;for(let{slot:t,resolve:u}of window[ct]?.splice(0)??[])u(D.open(t));return w&&console.table?.(D.debug()),D}window[Symbol.for("@thg-agentic/hyper-personalisation-web.onsite.module")]={startOnsite:Ne};})();
|
|
1
|
+
(()=>{function E(e){let s=typeof document>"u"?null:document.currentScript?.src;return s?new URL(e,s).href:null}var G=new Map;function x(e,s){return window[s]?Promise.resolve(window[s]):e?(G.has(s)||G.set(s,new Promise((n,i)=>{let u=document.createElement("script");u.src=e,u.async=!0,u.onload=()=>window[s]?n(window[s]):i(new Error(`${e} did not register`)),u.onerror=()=>i(new Error(`${e} did not load`)),document.head.append(u)}).finally(()=>G.delete(s))),G.get(s)):Promise.reject(new Error("the CDN script\u2019s own URL is unknown"))}var nt=E("onsite-answers.min.js"),ge=()=>x(nt,Symbol.for("@thg-agentic/hyper-personalisation-web.onsite.answers"));var st="/v1/capture/challenge",ot=e=>typeof e=="string"&&/^\/v1\/[\w/-]+$/.test(e)?e:st;function we(e,s={}){let n=s.fetch??globalThis.fetch?.bind(globalThis),i=s.servingHost??e.servingHost,u=s.gatewayHost??e.gatewayHost;async function r(p,{method:f="GET",body:o,consent:a=!1,timeoutMs:c}={}){if(!n)return{status:0,body:null};try{let y=await n(p,{method:f,credentials:"omit",signal:c&&AbortSignal.timeout?.(c),headers:{accept:"application/json",authorization:`Bearer ${e.writeKey}`,...o?{"content-type":"application/json"}:{},...a?e.headers():{}},...o?{body:JSON.stringify(o)}:{}}),_=null;try{_=await y.json()}catch{}return{status:y.status,body:_}}catch{return{status:0,body:null}}}return{decide:(p,f,{visitAudiences:o,visitCampaign:a,visitContext:c,timeoutMs:y=3e3}={})=>r(`${i}/v1/decisions`,{method:"POST",consent:!0,timeoutMs:Math.max(1,y),body:{slots:[f?{key:p,pin:{experiment:f[0],arm:f[1],split:f[2]}}:p],library:e.library,identifier_value:e.anonymousId()??void 0,session_id:e.sessionId()??void 0,identity_token:e.identityToken?.()??void 0,...e.preview?{preview:e.preview}:{},...o?{visit_audiences:o}:{},...a?{visit_campaign:a}:{},...c?{visit_context:c}:{}}}),datafile:()=>r(`${i}/v1/audiences/datafile`,{timeoutMs:1500}),challenge:()=>r(`${u}${ot(s.challenge)}`),capture:p=>r(`${u}/v1/capture`,{method:"POST",body:p}),answers:p=>r(`${u}/v1/capture/answers`,{method:"POST",body:p}),claim:p=>r(`${i}/v1/offers/claim`,{method:"POST",consent:!0,body:p,timeoutMs:8e3})}}var it=E("onsite-audiences.min.js"),ye=()=>x(it,Symbol.for("@thg-agentic/hyper-personalisation-web.onsite.audiences"));function be(e,s){let n={},i=()=>{try{let r=JSON.parse(e().getItem(s));r&&typeof r=="object"&&(n=r)}catch{}return n};return{read:i,write:r=>{let p=i();r(p),n=p;try{e().setItem(s,JSON.stringify(p))}catch{}}}}function Se(e,s=()=>!0){let n=be(()=>sessionStorage,e),i=be(()=>localStorage,e),u=()=>s()?i:n,r=()=>{let o=i.read();(o.sub!==void 0||o.k!==void 0)&&i.write(a=>{delete a.sub,delete a.k})},p=()=>s()?[n.read(),i.read()]:(r(),[n.read()]),f=(o,a)=>{var c;return o.f??(o.f={}),(c=o.f)[a]??(c[a]={}),o.f[a]};return{seen(o){let a=i.read().f?.[o]??{};return{session:n.read().f?.[o]?.n??0,lifetime:a.n??0,closedAt:a.c??null,submitted:a.s===1}},subscribed:()=>p().some(o=>o.sub===1),shown(o){n.write(a=>{let c=f(a,o);c.n=(c.n??0)+1}),i.write(a=>{let c=f(a,o);c.n=(c.n??0)+1})},closed(o,a=Date.now()){i.write(c=>{f(c,o).c=a})},tab(o,a){n.write(c=>{let y=f(c,o);a?y.t=1:delete y.t})},tabOut:o=>n.read().f?.[o]?.t===1,pin(o,a){if(a===void 0)return n.read().f?.[o]?.p??null;n.write(c=>{f(c,o).p=a})},coveredAt:()=>n.read().o??null,covered(o=Date.now()){n.write(a=>{a.o=o})},code(o,a=Date.now()){if(o===void 0){let[c]=p().flatMap(y=>y.k?[y.k]:[]).sort((y,_)=>_.at-y.at);return c&&a-c.at<14*864e5?c.c:null}return u().write(c=>{c.k={c:o,at:a}}),o},submitted(o){i.write(a=>{f(a,o).s=1}),u().write(a=>{a.sub=1})}}}var rt=E("onsite-products.min.js"),V=()=>x(rt,Symbol.for("@thg-agentic/hyper-personalisation-web.onsite.products"));var lt=E("onsite-render.min.js"),_e=()=>x(lt,Symbol.for("@thg-agentic/hyper-personalisation-web.onsite.render"));var at=["source","medium","campaign","content","term"];var Ae=e=>String(e).trim().toLowerCase();function ct(e,s,n){let i=Ae(e),u=Ae(n);return s==="is"?i===u:s==="contains"&&u!==""&&i.includes(u)}function ve(e,s){return(Array.isArray(e)?e:[]).every(n=>{let i=s?.[n?.field];return!at.includes(n?.field)||typeof i!="string"?!1:[].concat(n.values??[]).some(u=>ct(i,n.match,u))})}var Me=["popup","sheet","bar","teaser","inline","fullscreen"],ut=["entry","exit","scroll","time","idle","inline","manual"],oe=e=>e!=="inline",Ie=e=>e==="popup"||e==="sheet"||e==="fullscreen",v=e=>e!==null&&typeof e=="object"&&!Array.isArray(e),j=e=>Array.isArray(e)?e.filter(s=>typeof s=="string"):[],Ee=e=>Number.isInteger(e)&&e>=0?e:null,dt={field:null,match:null,values:[]},pt=e=>e==null?[]:Array.isArray(e)&&e.every(v)?e:[dt];function Ce(e){if(!v(e)||typeof e.slot!="string"||e.slot==="")return null;let s=v(e.trigger)?e.trigger:{};if(!Me.includes(e.format)||!ut.includes(s.type))return null;let n=v(e.caps)?e.caps:{};return{...e,trigger:s,priority:Number.isFinite(e.priority)?e.priority:0,pages:v(e.pages)?e.pages:{},devices:j(e.devices),aliases:j(e.aliases),audiences:j(e.audiences),arrived_from:pt(e.arrived_from),caps:{per_session:Ee(n.per_session),lifetime:Ee(n.lifetime),after_close_days:Number.isFinite(n.after_close_days)?n.after_close_days:null},window:v(e.window)?e.window:{},questions:Array.isArray(e.questions)?e.questions.filter(v):[],prizes:Array.isArray(e.prizes)?e.prizes.filter(v):[]}}var ft=/^[a-z][a-z0-9_-]{0,31}$/;function Oe(e){if(!v(e)||e.v!==1||!Array.isArray(e.steps))return null;let s=e.steps.filter(n=>v(n)&&ft.test(n.id)&&Array.isArray(n.blocks));return s.length===0?null:{format:Me.includes(e.format)?e.format:null,theme:v(e.theme)?e.theme:{},steps:s}}function xe(e,s){let n=String(e).split("*").map(i=>i.replace(/[.+?^${}()|[\]\\]/g,"\\$&")).join(".*");return new RegExp(`^${n}$`,"i").test(s)}function ht(e,s){let n=j(e?.include);return(!n.length||n.some(i=>xe(i,s)))&&!j(e?.exclude).some(i=>xe(i,s))}function De(e){return e.matchMedia?.("(hover: none) and (pointer: coarse)")?.matches===!0||e.innerWidth<768?"mobile":"desktop"}var Te=e=>typeof e=="string"?Date.parse(e):Number.NaN,U=e=>e.trigger.type==="manual";function ie(e,s){let n=[];ht(e.pages,s.path)||n.push("page not included"),e.devices.length&&!e.devices.includes(s.device)&&n.push(`not on ${s.device}`),ve(e.arrived_from,s.campaign)||n.push("not from its campaign");let i=Te(e.window.starts_at),u=Te(e.window.ends_at);if((s.now<i||s.now>=u)&&n.push("outside its dates"),e.audiences.length&&!s.preview&&(s.personalisation?s.audiences&&!e.audiences.some(f=>s.audiences.includes(f))&&n.push("not in its audiences"):n.push("audiences need personalisation consent")),s.preview||s.asked||U(e))return n;let{seen:r}=s,{caps:p}=e;return r.submitted&&n.push("already submitted"),e.exclude_subscribed===!0&&s.subscribed&&n.push("already subscribed"),p.per_session!==null&&r.session>=p.per_session&&n.push("per_session cap"),p.lifetime!==null&&r.lifetime>=p.lifetime&&n.push("lifetime cap"),p.after_close_days!==null&&r.closedAt&&s.now-r.closedAt<p.after_close_days*864e5&&n.push("closed recently"),n}var $e=(e,s)=>s.priority-e.priority;var mt=["mousemove","pointerdown","keydown","scroll","touchstart","wheel"];function gt(){let e=[];return{on:(i,u,r,p={passive:!0})=>{i.addEventListener(u,r,p),e.push(()=>i.removeEventListener(u,r,p))},later:(i,u)=>{let r=setTimeout(i,u);e.push(()=>clearTimeout(r))},stop:()=>{for(let i of e.splice(0))i()}}}var Ne=(e,s)=>{let n=s.documentElement.scrollHeight||0;return n>0?(e.scrollY+e.innerHeight)/n:0},wt=e=>{let s=e.activeElement;return!!(s&&(/^(INPUT|TEXTAREA|SELECT)$/.test(s.tagName)||s.isContentEditable))};function yt({on:e,later:s},n,i,u,r){let p=!1,f=!1,o=null,a=0;s(()=>{p=!0},i.delay_ms??5e3),e(r,"mousemove",c=>{c.clientY>u.innerHeight*.1&&(f=!0),o!==null&&(a=c.clientY-o),o=c.clientY}),e(r,"mouseout",c=>{p&&f&&!c.relatedTarget&&c.clientY<=0&&a<0&&!wt(r)&&n("exit")})}function bt({on:e,later:s},n,i,u,r){let p=!1,f=0,o=u.scrollY,a=Date.now(),c=null,y=null;s(()=>{p=!0},i.delay_ms??5e3),e(u,"scroll",()=>{let _=u.scrollY,T=Date.now();if(f=Math.max(f,Ne(u,r)),_<o){(!c||T-c.t>300)&&(c={y:o,t:a});let M=c.y-_;p&&f>=.3&&M>=120&&M/Math.max(1,T-c.t)>=.5&&n("exit_scroll")}else c=null;o=_,a=T}),e(r,"visibilitychange",()=>{r.visibilityState==="hidden"?y=Date.now():y!==null&&Date.now()-y>=1e4&&n("return"),r.visibilityState!=="hidden"&&(y=null)})}function Pe(e,s,{device:n,win:i=window,doc:u=document}){let r=gt(),p=(e.seconds??30)*1e3;if(e.type==="entry"&&r.later(()=>s("entry"),e.delay_ms??0),e.type==="time"&&r.later(()=>s("time"),p),e.type==="exit"&&(n==="mobile"?bt:yt)(r,s,e,i,u),e.type==="scroll"){let f=e.depth??.5;r.on(i,"scroll",()=>Ne(i,u)>=f&&s("scroll"))}if(e.type==="idle"){let f=null,o=()=>{clearTimeout(f),f=setTimeout(()=>s("idle"),p)};o();for(let a of mt)r.on(a==="scroll"?i:u,a,o);return r.on(u,"visibilitychange",o),()=>{clearTimeout(f),r.stop()}}return r.stop}var St=E("onsite-wheel.min.js"),ke=()=>x(St,Symbol.for("@thg-agentic/hyper-personalisation-web.onsite.wheel"));var Le=Symbol.for("@thg-agentic/hyper-personalisation-web.onsite-access"),W=Symbol.for("@thg-agentic/hyper-personalisation-web.onsite"),_t=Symbol.for("@thg-agentic/hyper-personalisation-web.onsite.pending"),At=Symbol.for("@thg-agentic/hyper-personalisation-web.onsite.listeners"),Re=Symbol.for("@thg-agentic/hyper-personalisation-web.onsite.suppressed"),Fe={seen:()=>({session:0,lifetime:0,closedAt:null,submitted:!1}),subscribed:()=>!1,shown(){},closed(){},submitted(){},tab(){},tabOut:()=>!1,pin:()=>null,coveredAt:()=>null,covered(){},code:()=>null},vt=new Set(["decision-failed","no-creative","no-code","renderer-failed","products-failed","error"]),je=3e3,Ue={status:0,body:null},Et=1500,We=50,xt=300,Tt=()=>{try{return new URLSearchParams(location.search).get("hp_debug")==="onsite"}catch{return!1}},Mt=e=>Array.isArray(e?.steps)&&e.steps.some(s=>Array.isArray(s?.blocks)&&s.blocks.some(n=>n?.t==="products"));function Ke(e,s={}){if(typeof window>"u"||typeof document>"u")return null;if(window[W])return window[W];let n=typeof e?.[Le]=="function"?e[Le]():null;if(!n)return console.warn("[hp] onsite: startOnsite needs the client bootstrap or createAnalytics made"),null;let i=s.settings??n.settings??{},u=we(n,{...s,challenge:i.capture?.challenge}),r=n.preview?Fe:Se(n.storageKey,n.personalisation),p=()=>n.campaign?.()??null,f=new Map,o=()=>window[Re]?.size>0,a=(t,l)=>{for(let d of window[At]?.[t]??[])try{d(l)}catch(h){console.warn(`[hp] onsite ${t} listener failed:`,h)}},c=De(window),y=n.debug||s.debug===!0||Tt(),_=new Map,T=new Map,M=[];for(let t of Array.isArray(i.forms)?i.forms:[]){let l=Ce(t);l?M.push(l):_.set(String(t?.slot??`form ${_.size+1}`),{slot:String(t?.slot??""),state:"invalid",code:"invalid",reasons:["not a form this SDK can show"]})}let re=()=>ye().catch(t=>(console.warn("[hp] onsite audiences not loaded:",t?.message??t),null));n.personalisation()&&M.some(t=>t.audiences.length>0)&&re().then(t=>t?.prefetch(u));let N=new Map,K=new Map,I=null,le=!1,ae=new Set,He=t=>{for(let l of N.keys()){let d=f.get(l);if(!t||!d||d.modal?.())return l}return null},H=null,q=new Set,B=Number.isInteger(i.overlay_gap_minutes)?i.overlay_gap_minutes:0,Ye=()=>{let t=r.coveredAt();if(!(B>0)||typeof t!="number")return null;let l=Math.max(0,Math.floor((Date.now()-t)/6e4));return l<B?`a popup showed ${l} min ago; ${B} min between them`:null},P=new Set,Y=new Map,b=(t,l,d,h=[])=>(_.set(t.slot,{slot:t.slot,format:t.format,trigger:t.trigger.type,priority:t.priority,state:l,code:d,reasons:h}),y&&console.info(`[hp] onsite ${t.slot}: ${l}${h.length?` (${h.join("; ")})`:""}`),{state:l,code:d}),D=(t,l,d,h)=>(N.delete(t.slot),b(t,l,d,h)),k=(t,l,d)=>{let h;return Promise.race([t,new Promise(w=>{h=setTimeout(w,l-Date.now(),d)})]).then(w=>Date.now()>l?d:w).finally(()=>clearTimeout(h))},Xe=(t,l)=>{le||o()||(I??(I=t.slot),a("nothing",{slot:t.slot,format:t.format,code:l}))},ce=()=>{try{let t=s.audiences?.();return Array.isArray(t)?t:null}catch{return null}},ue=t=>({path:location.pathname,device:c,campaign:p(),now:Date.now(),seen:r.seen(t.slot),subscribed:r.subscribed()||s.subscribed?.()===!0,personalisation:n.personalisation(),preview:!!n.preview,audiences:ce()}),J=t=>{T.get(t.slot)?.(),T.delete(t.slot)};function L(t,l,d=!1,h=U(t),w=Date.now()+je){if(f.has(t.slot))return Promise.resolve({state:"shown",code:"shown",asked:h});let g=K.get(t.slot);return g?(g.asked||(g.asked=h),g.done):(g={asked:h},g.done=ze(t,l,d,h,w).catch(A=>f.has(t.slot)?{state:"shown",code:"shown"}:(console.warn("[hp] onsite form failed:",A?.message??A),D(t,"not shown","error",[`failed: ${A?.message??A}`]))).then(A=>(K.delete(t.slot),{...A,asked:g.asked||g.opened})),K.set(t.slot,g),g.done)}async function ze(t,l,d,h,w){if(o())return b(t,"not shown","suppressed",[`suppressed: ${[...window[Re]].join(", ")}`]);let g=ie(t,{...ue(t),...d?{seen:Fe.seen()}:{},asked:h});if(g.length)return b(t,"not eligible","not-eligible",g);let A=Ie(t.format)&&!d,C=A&&!h&&Ye();if(C)return b(t,"not shown","overlay-gap",[C]);if(A&&!n.preview&&n.consentAnswered?.()===!1)return Y.set(t,h),b(t,"not shown","awaiting-consent",["waiting for the consent banner"]);let O=oe(t.format),pe=O&&He(h);if(pe)return b(t,"not shown","another-showing",[`${pe} is showing`]);if(O&&I&&!h)return b(t,"not shown","allowance-spent",[`${I} already showed on this page view`]);let X=null;if(!O){try{X=document.querySelector(t.trigger.selector??"")}catch{X=null}if(!X)return b(t,"not shown","no-element",["no element matches its selector"])}O&&N.set(t.slot,t),J(t),b(t,"asking for a decision","deciding",[l]);let Be=_e().catch(m=>(console.warn("[hp] onsite renderer not loaded:",m?.message??m),null)),z=t.visit_context===!0?V().catch(()=>null):null,Q=ce()??[],fe=[...new Set([...t.audiences,...Q])].filter(m=>Q.includes(m)).slice(0,100),Je=t.audiences.length>0&&!n.preview&&n.personalisation()?await k(re().then(m=>m?m.visitAudiences(u,n.sessionSignals,t.audiences,Q):fe),Math.min(w,Date.now()+Et),fe):null,F=Date.now()<w?await k(u.decide(t.slot,r.pin(t.slot),{visitAudiences:Je,visitCampaign:t.arrived_from.length?p():null,visitContext:t.visit_context===!0?n.visitContext?.()??null:null,timeoutMs:w-Date.now()}),w,Ue):Ue,ee=F.status===200?F.body?.decisions:null,S=Array.isArray(ee)?ee.find(m=>m?.slot===t.slot):null;S?.experiment&&S.arm&&S.split&&r.pin(t.slot,[S.experiment,S.arm,S.split]);let $=S&&S.holdout!==!0?Oe(S.payload):null,he=$?.steps[0].blocks??[],me=S?.offer?.code??(n.preview?"PREVIEW":r.code()),Ze=n.basketValue?.()??null,te=he.some(m=>m?.t==="code")&&!me&&"no code to remind of"||he.some(m=>m?.t==="progress")&&!(Ze>0)&&"the basket is empty";if(te){let m=te==="the basket is empty";return m&&P.add(t),D(t,"not shown",m?"empty-basket":"no-code",[te])}if(P.delete(t),!$){let m=S?.holdout===!0;return m&&n.analytics()&&e.recordExposure(F.body),O&&m&&(I??(I=t.slot)),m&&!h&&a("held",{slot:t.slot,arm:S.arm??null,format:t.format}),m||Array.isArray(ee)?D(t,m?"held out":"no decision",m?"held-out":"no-creative",["no creative for this visitor"]):D(t,"no decision","decision-failed",[`decisions answered ${F.status}`])}let ne=await k(Be,w,null);if(!ne)return D(t,"not shown","renderer-failed",["the renderer did not load"]);if(Mt($)&&(z??(z=V().catch(()=>null)),!await k(z,w,null)))return D(t,"not shown","products-failed",["its products did not load"]);if(await k(ne.warm?.(t,$,$.steps[0].id,ae),Math.min(w,Date.now()+xt)),o())return D(t,"not shown","suppressed",["suppressed"]);let se=(m,tt={})=>a(m,{slot:t.slot,arm:S.arm??null,format:$.format??t.format,...tt}),Qe=ne.mountForm({form:t,creative:$,decision:S,access:n,client:e,api:u,counters:r,loadWheel:ke,loadAnswers:ge,loadProducts:()=>z??V(),container:X,warmed:ae,coupon:me,basket:()=>n.basketValue?.()??null,emit:se,onClose(m){f.delete(t.slot),N.delete(t.slot),b(t,"closed","closed",[m]),se("closed",{reason:m})}});f.set(t.slot,Qe),d||r.shown(t.slot),A&&r.covered(),O&&(I??(I=t.slot)),n.analytics()&&e.recordExposure(F.body);let et=b(t,"shown","shown",[l]);return se("shown"),et}function Z(t,l,d=U(t)){if(!oe(t.format))return L(t,l,!1,d);if(!H){let h={forms:[],taken:new Set,deadline:Date.now()+We+je};H=h,q.add(h),setTimeout(()=>{H=null,Ge(h)},We)}H.forms.push([t,l,d])}async function Ge(t){let l=t.forms.sort(([h],[w])=>$e(h,w)),d=null;for(let[h,[w,g,A]]of l.entries()){if(t.taken.has(w))continue;let C=await L(w,g,!1,A,t.deadline);if(!d&&vt.has(C.code)&&!C.asked&&(d=[w,C.code]),C.state==="shown"||C.state==="held out"){for(let[O]of l.slice(h+1))b(O,"not shown","lower-priority",[`${w.slot} has a higher priority`]);d=null;break}}q.delete(t),d&&Xe(...d)}for(let t of M){if(t.format==="teaser"&&r.tabOut(t.slot)){L(t,"tab kept from an earlier page",!0);continue}let l=ie(t,ue(t));if(l.length){b(t,"not eligible","not-eligible",l);continue}let d=t.trigger.type;d==="manual"?b(t,"waiting for hp.onsite.open","waiting-for-open"):d==="inline"||t.format==="inline"?L(t,"inline"):de(t)}function de(t){J(t),T.set(t.slot,Pe(t.trigger,l=>{J(t),Z(t,l)},{device:c})),b(t,"armed","armed",[`${t.trigger.type} on ${c}`])}let Ve=n.onConsentAnswered?.(()=>{let t=[...Y];Y.clear();for(let[l,d]of t)f.has(l.slot)||(d?Z(l,"manual",d):de(l))}),qe=n.onBasket?.(()=>{if(!((n.basketValue?.()??0)>0))return;let t=[...P];P.clear();for(let l of t)f.has(l.slot)||Z(l,"the basket changed")}),R=Object.freeze({open(t){let l=M.find(g=>g.slot===t),d=l??M.find(g=>g.aliases.includes(t));if(!d)return Promise.resolve(!1);if(f.has(d.slot))return Promise.resolve(!0);for(let g of q)g.taken.add(d);let h=L(d,"manual",!1,U(d)||!l),w=K.get(d.slot);return w&&(w.opened=!0),h.then(({state:g})=>g==="shown")},suppress(){for(let[t,l]of f){l.destroy(),f.delete(t),N.delete(t);let d=M.find(h=>h.slot===t);d&&b(d,"closed","suppressed",["suppressed"])}},debug:()=>[..._.values()].map(t=>({...t,reasons:[...t.reasons]})),stop(){le=!0;for(let t of T.values())t();T.clear(),qe?.(),Ve?.(),P.clear(),Y.clear(),window[W]===R&&delete window[W]}});window[W]=R;for(let{slot:t,resolve:l}of window[_t]?.splice(0)??[])l(R.open(t));return y&&console.table?.(R.debug()),R}window[Symbol.for("@thg-agentic/hyper-personalisation-web.onsite.module")]={startOnsite:Ke};})();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@thg-agentic/hyper-personalisation-web",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.30.0",
|
|
4
4
|
"description": "Browser SDK for the THG Hyper-Personalisation event specification: event tracking from a write key and remote settings, strict CMP-agnostic consent, a GA4 dataLayer bridge and in-session audience evaluation. Dependency-free ESM on the Segment wire protocol, a CDN script (dist/hp.min.js), and an optional @segment/analytics-next plugin path.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./src/index.js",
|
|
@@ -92,7 +92,7 @@
|
|
|
92
92
|
"esbuild": "^0.28.2",
|
|
93
93
|
"jsdom": "^30.1.1",
|
|
94
94
|
"typescript": "^7.0.2",
|
|
95
|
-
"@thg-agentic/hyper-personalisation-spec": "1.
|
|
95
|
+
"@thg-agentic/hyper-personalisation-spec": "1.22.0"
|
|
96
96
|
},
|
|
97
97
|
"scripts": {
|
|
98
98
|
"test": "node --test tests/*.test.mjs",
|
package/src/index.js
CHANGED
|
@@ -1183,6 +1183,8 @@ export function createAnalytics(options) {
|
|
|
1183
1183
|
[ONSITE_ACCESS]() {
|
|
1184
1184
|
return {
|
|
1185
1185
|
writeKey: cfg.writeKey,
|
|
1186
|
+
// Sent with a form's decision: the server answers no form for a design this SDK cannot show.
|
|
1187
|
+
library: { name: LIB, version: VERSION },
|
|
1186
1188
|
storageKey: storageKey(storageName('onsite'), cfg.propertyId),
|
|
1187
1189
|
gatewayHost: cfg.apiHost,
|
|
1188
1190
|
servingHost: cfg.servingHost ?? cfg.apiHost,
|
package/src/onsite/answers.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Date and number questions in an onsite form (ADR 0064 part 6): their fields, and the answer each
|
|
3
3
|
* holds in its stored form (packages/control-plane/src/onsite/question-answers.ts), which the
|
|
4
|
-
* gateway checks again and never takes from the browser on trust.
|
|
4
|
+
* gateway checks again and never takes from the browser on trust. And a single choice shown as
|
|
5
|
+
* picture cards, whose answer is a checked radio button like any other choice's.
|
|
5
6
|
*
|
|
6
7
|
* A birthday is a day and a month, and a year when asked, as separate fields (Klaviyo's birthday
|
|
7
8
|
* block; GOV.UK's date input for a date someone knows, never a calendar): `--MM-DD` without the
|
|
@@ -9,7 +10,14 @@
|
|
|
9
10
|
* field with a numeric keyboard, which takes a comma for the point.
|
|
10
11
|
*/
|
|
11
12
|
|
|
12
|
-
import {
|
|
13
|
+
import { countdown as tick } from './countdown.js';
|
|
14
|
+
import {
|
|
15
|
+
cardColumns,
|
|
16
|
+
choiceInput,
|
|
17
|
+
isObject,
|
|
18
|
+
optionsOf,
|
|
19
|
+
select,
|
|
20
|
+
} from './rules.js';
|
|
13
21
|
|
|
14
22
|
const pad = (n) => String(n).padStart(2, '0');
|
|
15
23
|
const OLDEST_AGE = 120;
|
|
@@ -175,3 +183,77 @@ export function answerOf(set, q, now = Date.now(), locale = undefined) {
|
|
|
175
183
|
? { value }
|
|
176
184
|
: wrong(y);
|
|
177
185
|
}
|
|
186
|
+
|
|
187
|
+
// Picture cards and a countdown (its block lays out as its label and timer, and its timer), so the renderer every form loads does not carry them.
|
|
188
|
+
// Cards: two a row, or up to four (`--n`) where the form is wide enough to keep each picture
|
|
189
|
+
// large. The radio button lies over the card, so the stylesheet's :focus-visible ring shows focus;
|
|
190
|
+
// the picture's ring and tick show the choice.
|
|
191
|
+
const CSS = `.cd{display:contents}
|
|
192
|
+
.cd>.x-md{color:var(--mu)}
|
|
193
|
+
.tm{font-size:40px;line-height:1;font-weight:800;letter-spacing:.02em;font-variant-numeric:tabular-nums;text-align:center}
|
|
194
|
+
.qw{container-type:inline-size;width:100%}
|
|
195
|
+
.qc{display:grid;width:100%;grid-template-columns:1fr 1fr;gap:12px}
|
|
196
|
+
@container (min-width:520px){.qc{grid-template-columns:repeat(var(--n),1fr)}}
|
|
197
|
+
.qk{position:relative;display:flex;flex-direction:column;gap:8px}
|
|
198
|
+
.qk input{appearance:none;position:absolute;inset:0;z-index:1;margin:0;border-radius:var(--ir);cursor:pointer}
|
|
199
|
+
.qf{position:relative;aspect-ratio:4/5;overflow:hidden;border-radius:var(--ir);background:color-mix(in srgb,var(--t) 7%,var(--b));box-shadow:0 1px 3px rgb(0 0 0/.12)}
|
|
200
|
+
.qi{display:block;width:100%;height:100%;object-fit:cover;transition:transform .5s}
|
|
201
|
+
.qk:hover .qi{transform:scale(1.05)}
|
|
202
|
+
.qk :checked~.qf{box-shadow:0 0 0 2px var(--b),0 0 0 4px var(--a)}
|
|
203
|
+
.qk :checked~.qf::after{content:"✓";position:absolute;top:8px;right:8px;display:grid;place-content:center;width:26px;height:26px;border-radius:50%;background:var(--a);color:var(--ot);font:700 15px/1 sans-serif}
|
|
204
|
+
.ql{font-size:15px;font-weight:600;line-height:1.3;text-align:center}
|
|
205
|
+
@media (prefers-reduced-motion:reduce){.qi{transition:none}}`;
|
|
206
|
+
|
|
207
|
+
/** The shadow roots that already hold this chunk's stylesheet. */
|
|
208
|
+
const styled = new WeakSet();
|
|
209
|
+
|
|
210
|
+
/** This chunk's stylesheet into a form's shadow root, once however many blocks use it. */
|
|
211
|
+
function style(root, make) {
|
|
212
|
+
if (styled.has(root)) return;
|
|
213
|
+
styled.add(root);
|
|
214
|
+
const node = make('style');
|
|
215
|
+
node.textContent = CSS;
|
|
216
|
+
root.append(node);
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
/** A countdown block into the renderer's `box`: its label, then its timer, ticked (./countdown.js). */
|
|
220
|
+
export function countdown(box, block, preview, make) {
|
|
221
|
+
style(box.getRootNode(), make);
|
|
222
|
+
if (block.label) box.append(make('p', 'x-md', block.label));
|
|
223
|
+
const timer = make('p', 'tm');
|
|
224
|
+
timer.setAttribute('role', 'timer');
|
|
225
|
+
box.append(timer);
|
|
226
|
+
return tick(box, block, preview);
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
/**
|
|
230
|
+
* A single choice `q` as picture cards into its fieldset: each option a radio button, its picture
|
|
231
|
+
* from the question block's `pictures` (by option value) drawn by the renderer's `picture`, and its
|
|
232
|
+
* label under it; the whole card is the choice. Two a row in a narrow form, up to four in a wide
|
|
233
|
+
* one.
|
|
234
|
+
*/
|
|
235
|
+
export function answerCards(set, q, block, make, chosen, picture, root) {
|
|
236
|
+
const { pictures } = block;
|
|
237
|
+
const options = optionsOf(q);
|
|
238
|
+
style(root, make);
|
|
239
|
+
const grid = make('div', 'qc');
|
|
240
|
+
grid.style.setProperty('--n', String(cardColumns(q)));
|
|
241
|
+
// The cards' width is the form's, measured on a box that always fills it: the fieldset itself
|
|
242
|
+
// may shrink to fit its content, which a container's size cannot depend on.
|
|
243
|
+
const wide = make('div', 'qw');
|
|
244
|
+
wide.append(grid);
|
|
245
|
+
for (const x of options) {
|
|
246
|
+
const frame = make('span', 'qf');
|
|
247
|
+
const p = isObject(pictures) ? pictures[x.value] : null;
|
|
248
|
+
const img = isObject(p) && picture(p);
|
|
249
|
+
if (img) frame.append(img);
|
|
250
|
+
const card = make('label', 'qk');
|
|
251
|
+
card.append(
|
|
252
|
+
choiceInput(make, q, x, chosen, 'radio'),
|
|
253
|
+
frame,
|
|
254
|
+
make('span', 'ql', x.label ?? x.value),
|
|
255
|
+
);
|
|
256
|
+
grid.append(card);
|
|
257
|
+
}
|
|
258
|
+
set.append(wide);
|
|
259
|
+
}
|
package/src/onsite/api.js
CHANGED
|
@@ -17,6 +17,8 @@ const challengePath = (path) =>
|
|
|
17
17
|
|
|
18
18
|
/** How long one claim request may take before it counts as failed. */
|
|
19
19
|
const CLAIM_TIMEOUT_MS = 8000;
|
|
20
|
+
/** The longest a decision request may take before it counts as failed (status 0). */
|
|
21
|
+
const DECISION_TIMEOUT_MS = 3000;
|
|
20
22
|
/** How long a limited form waits for the audience datafile before it is decided without a claim. */
|
|
21
23
|
const DATAFILE_TIMEOUT_MS = 1500;
|
|
22
24
|
|
|
@@ -66,11 +68,22 @@ export function createApi(access, options = {}) {
|
|
|
66
68
|
* session audiences it meets; for a form that names a campaign, `visitCampaign`, the campaign
|
|
67
69
|
* the visit arrived from. The server holds either form back unless its rules hold. For a form
|
|
68
70
|
* that shows products, `visitContext`: the page and the visit its products are filled from.
|
|
71
|
+
* Bounded by `timeoutMs`, at most DECISION_TIMEOUT_MS.
|
|
69
72
|
*/
|
|
70
|
-
decide: (
|
|
73
|
+
decide: (
|
|
74
|
+
slot,
|
|
75
|
+
pin,
|
|
76
|
+
{
|
|
77
|
+
visitAudiences,
|
|
78
|
+
visitCampaign,
|
|
79
|
+
visitContext,
|
|
80
|
+
timeoutMs = DECISION_TIMEOUT_MS,
|
|
81
|
+
} = {},
|
|
82
|
+
) =>
|
|
71
83
|
call(`${serving}/v1/decisions`, {
|
|
72
84
|
method: 'POST',
|
|
73
85
|
consent: true,
|
|
86
|
+
timeoutMs: Math.max(1, timeoutMs),
|
|
74
87
|
body: {
|
|
75
88
|
slots: [
|
|
76
89
|
pin
|
|
@@ -80,6 +93,8 @@ export function createApi(access, options = {}) {
|
|
|
80
93
|
}
|
|
81
94
|
: slot,
|
|
82
95
|
],
|
|
96
|
+
// This SDK and its version: a form whose design needs a later one is answered as none.
|
|
97
|
+
library: access.library,
|
|
83
98
|
identifier_value: access.anonymousId() ?? undefined,
|
|
84
99
|
session_id: access.sessionId() ?? undefined,
|
|
85
100
|
// What a promo reminder's code is answered for under a publishable key (ADR 0067).
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* An onsite form's countdown block, ticking in the node the renderer made: to a deadline
|
|
3
|
+
* (`ends_at`), one moment for every shopper, and hidden with its label once it has passed, as an offer that has
|
|
4
|
+
* ended no longer hurries anyone; else `minutes` from when it is first shown, such as how long a
|
|
5
|
+
* claimed code is held. A preview shows a deadline not yet set, or passed, at zero. It comes with
|
|
6
|
+
* the answers chunk (./answers.js), loaded when a step shows one.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Tick the timer in `box` for `block` every second, from now, showing the box the renderer drew
|
|
11
|
+
* hidden, and hiding it again once a deadline has passed.
|
|
12
|
+
*
|
|
13
|
+
* @param {HTMLElement} box The block: its label, if any, then its `role=timer` paragraph.
|
|
14
|
+
* @param {{ ends_at?: string, minutes?: number }} block
|
|
15
|
+
* @param {boolean} preview
|
|
16
|
+
* @returns {() => void} Stops it, for when the step changes.
|
|
17
|
+
*/
|
|
18
|
+
export function countdown(box, block, preview) {
|
|
19
|
+
const node = box.lastChild;
|
|
20
|
+
const deadline = 'ends_at' in block;
|
|
21
|
+
const ends = deadline
|
|
22
|
+
? Date.parse(block.ends_at)
|
|
23
|
+
: Date.now() + Math.max(0, Number(block.minutes) || 0) * 60_000;
|
|
24
|
+
const tick = () => {
|
|
25
|
+
const left = Math.max(0, ends - Date.now()) || 0;
|
|
26
|
+
const days = Math.floor(left / 864e5);
|
|
27
|
+
// mm:ss; hh:mm:ss from an hour; and the days before them from a day.
|
|
28
|
+
node.textContent = `${days ? `${days}d ` : ''}${new Date(left).toISOString().slice(left < 36e5 ? 14 : 11, 19)}`;
|
|
29
|
+
box.hidden = !left && deadline && !preview;
|
|
30
|
+
if (!left) clearInterval(id);
|
|
31
|
+
};
|
|
32
|
+
const id = setInterval(tick, 1000);
|
|
33
|
+
tick();
|
|
34
|
+
return () => clearInterval(id);
|
|
35
|
+
}
|