@thg-agentic/hyper-personalisation-web 3.31.0 → 3.34.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 +71 -11
- package/dist/hp.min.js +3 -3
- package/dist/onsite-answers.min.js +2 -2
- package/dist/onsite-products.min.js +2 -2
- package/dist/onsite-render.min.js +2 -2
- package/dist/onsite-values.min.js +1 -0
- package/dist/onsite-wheel.min.js +1 -1
- package/dist/onsite.min.js +1 -1
- package/package.json +3 -2
- package/src/index.js +38 -1
- package/src/onsite/answers.js +6 -3
- package/src/onsite/api.js +5 -2
- package/src/onsite/countdown.js +21 -11
- package/src/onsite/index.js +100 -23
- package/src/onsite/money.js +11 -0
- package/src/onsite/page-facts.js +61 -0
- package/src/onsite/preview.js +27 -12
- package/src/onsite/products.js +3 -9
- package/src/onsite/render.js +14 -9
- package/src/onsite/rich-text.js +12 -1
- package/src/onsite/rules.js +47 -8
- package/src/onsite/values-loader.js +6 -0
- package/src/onsite/values.js +218 -0
- package/src/onsite-facade.js +57 -2
- package/src/session/record.js +18 -0
- package/src/session/signals.js +4 -0
- package/src/version.js +1 -1
- package/types/onsite-preview.d.ts +40 -0
- package/types/onsite.d.ts +73 -3
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
(()=>{async function Be(
|
|
1
|
+
(()=>{async function Be(i,r,a){let l=b=>Array.from(new Uint8Array(b),w=>w.toString(16).padStart(2,"0")).join(""),p=new TextEncoder,x=i.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(i.salt+C)));let h=(await Promise.all(w)).findIndex(C=>l(C)===i.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(i=>setTimeout(i,0)),Ye=(i,r)=>Be(i,Ct,r);function Tt(i,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:i.challenge,salt:i.salt,maxnumber:i.maxnumber})})}var Ot=i=>i&&i.algorithm==="SHA-256"&&typeof i.challenge=="string"&&typeof i.salt=="string"&&typeof i.signature=="string";async function Ge(i){if(!Ot(i)||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(i,a.signal).catch(()=>Ye(i,a.signal)):Ye(i,a.signal),b=await Promise.race([x,p]);return clearTimeout(l),a.abort(),typeof b!="number"?null:btoa(JSON.stringify({algorithm:i.algorithm,challenge:i.challenge,number:b,salt:i.salt,signature:i.signature,took:Date.now()-r}))}function X(i){if(typeof i!="string")return null;try{let r=new URL(i);return r.protocol==="https:"?r.href:null}catch{return null}}function K(i){if(typeof i!="string")return null;try{let r=new URL(i);return r.protocol==="https:"||r.protocol==="http:"&&r.hostname==="localhost"?r.href:null}catch{return null}}function be(i,r,a,l){if(typeof r=="string"){i.append(a.createTextNode(r));return}if(l>6||r===null)return;if(Array.isArray(r)){for(let w of r)be(i,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?i:a.createElement(p);x&&(b.setAttribute("href",x),b.setAttribute("rel","noopener")),be(b,r[p],a,l+1),b!==i&&i.append(b)}function Ve(i,r=document){let a=r.createDocumentFragment();return be(a,i,r,0),a}var I=i=>i!==null&&typeof i=="object"&&!Array.isArray(i);function ee(i,r,a){if(typeof a=="string"&&a)return a;let l=I(i?.next?.answers)?i.next.answers:{};for(let p of i?.blocks??[])for(let x of r[p?.question]??[]){let b=l[`${p.question}=${x}`];if(typeof b=="string")return b}return typeof i?.next?.default=="string"?i.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(i,r){let a=String(i??"").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=i=>/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(i);function xe(i,r,a,l,p){let x=i("select","i");x.setAttribute("aria-label",r);for(let[b,w]of[["",a],...l]){let h=i("option","",w);h.value=b,h.selected=b===p,x.append(h)}return x}var Ze=i=>{let r=i.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}
|
|
@@ -178,4 +178,4 @@ hr{width:100%;margin:4px 0;border:0;border-top:1px solid var(--ln)}
|
|
|
178
178
|
@keyframes hp-down{from{transform:translateY(-100%)}}
|
|
179
179
|
@keyframes hp-out{to{opacity:0;transform:translateY(12px) scale(.98)}}
|
|
180
180
|
@media (prefers-reduced-motion:reduce){.s .w,.s .ov,.f>*{animation:hp-fade .15s ease both!important}.btn{transition:none}}
|
|
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};})();
|
|
181
|
+
`;var Lt=/^#(?:[0-9a-f]{3}){1,2}$/i,Je=["popup","fullscreen"],It=["ok","verify","already"],Mt=["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"],Dt=[500,1500],Rt=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"},Y=(i,r,a)=>i.includes(r)?r:a,P=(i,r,a)=>Number.isFinite(i)?Math.min(Math.max(i,r),a):null,ke=i=>i.type==="date"||i.type==="number",Ae=()=>globalThis.matchMedia?.("(prefers-reduced-motion: reduce)")?.matches===!0;function rt(i){let r=I(i.layout)?i.layout:{},a=I(r.media)?r.media:null,l=Y(Mt,r.template,"stack"),p=a?.side==="right"?"right":"left";return!a&&I(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:P(r.scrim,0,.9)??.45,padding:Y(["none","sm","md","lg"],r.padding,"md")}}var st=(i,r)=>Y(["sm","md","lg","full"],i.size,null)??(r.template==="split"||r.template==="overlay"?"lg":"md"),at=(i,r,a=1,l="100vw")=>{if(i==="fullscreen"||r==="full")return l;let p=i==="teaser"?220:i==="sheet"?400:tt[r]??tt.md;return`(max-width: 639px) ${l}, ${Math.round(p*a)}px`},lt=(i,r)=>i==="lg"?1/Ze(r):.5,ct=(i,r,a)=>{if(!a||!Array.isArray(i.widths)||!r.endsWith(".webp"))return null;let l=i.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=(i,r)=>i.format==="inline"?"inline":r.format&&r.format!=="inline"?r.format:i.format,Ee=i=>i.kind==="video"||i.t==="video",_e={webm:"video/webm",mp4:"video/mp4",m4v:"video/mp4",mov:"video/quicktime",ogv:"video/ogg"},$e=i=>_e[i.split(/[?#]/)[0].split(".").pop().toLowerCase()],Wt=(i,r)=>[...new Set([r,...Array.isArray(i.sources)?i.sources.map(K):[]])].filter(Boolean).sort((a,l)=>($e(l)===_e.webm)-($e(a)===_e.webm));function ze(i,r,a,l=new Set){let p=r.steps.find(v=>v.id===a);if(!p)return Promise.resolve();let x=dt(i,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 F=v?.display==="cards"&&i.questions.find(T=>T.key===v.question&&T.type==="one");return F?Object.values(v.pictures??{}).filter(I).map(T=>[T,lt(C,F),"50vw"]):[]});return b.media&&!(w&&b.template!=="image-only")&&_.push([b.media,b.template==="split"?.46:1]),Promise.all(_.map(([v,F,T])=>{let O=K(Ee(v)?v.poster:v.asset);if(!O)return null;let D=document.createElement("img"),y=!Ee(v)&&ct(v,O,P(v.width,1,8192));y&&(D.sizes=at(h,C,F,T),D.srcset=y);let Z=`${D.sizes} ${y||O}`;return l.has(Z)?null:(l.add(Z),D.src=O,D.decode?.().catch(()=>{}))}))}var ot=i=>i?.call?i():clearInterval(i),Ft=0,Se=i=>`hp-${i}-${++Ft}`;function d(i,r,a){let l=document.createElement(i);return r&&(l.className=r),a!==void 0&&l.append(Ve(a)),l}var pt=i=>{let r=i.length===4?[...i.slice(1)].map(a=>a+a).join(""):i.slice(1);return[0,2,4].map(a=>Number.parseInt(r.slice(a,a+2),16))},te=i=>{let[r,a,l]=pt(i).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},it=(i,r=4.5)=>{let a=te(i)+.05,l=1.05/a;return l>=r?"#fff":a/(te("#111")+.05)>l?"#111":"#fff"};function Ht(i,r){let a=(_,v)=>v&&i.style.setProperty(_,v),l=_=>Lt.test(_??"")?_:null;a("--hp-accent",l(r.accent)),a("--hp-bg",l(r.background)),a("--hp-text",l(r.text));let p=P(r.radius,0,48);p!==null&&a("--hp-radius",`${p}px`),a("--hp-font",r.font==="site"?i.ownerDocument.defaultView.getComputedStyle(i.parentElement??i.ownerDocument.body).fontFamily:Object.hasOwn(ve,r.font)?ve[r.font]:null),l(r.accent)&&(a("--hp-on-accent",it(r.accent,3)),a("--hp-on-accent-text",it(r.accent))),l(r.background)&&te(r.background)<.18&&(a("--hp-field","#fff"),a("--hp-field-text","#111"));let x=I(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} / ${P(x.opacity,0,1)??.6})`)}function Yt(i){try{let r=new CSSStyleSheet;r.replaceSync(we),i.adoptedStyleSheets=[r]}catch{let r=document.createElement("style");r.textContent=we,i.append(r)}}function ut(i){let{form:r,creative:a,decision:l,access:p,client:x,api:b,counters:w}=i,h=i.preview??null,C=e=>{let t=e.blocks.find(o=>o?.t==="email"||o?.t==="phone");return t?.t==="phone"||!t&&!r.consent_text?r.sms_consent_text:r.consent_text},_=dt(r,a),v=a.theme,F=Y(Qe[_]??[],v.position,Qe[_]?.[0]),T=document.createElement("hp-onsite");h&&T.setAttribute("preview",""),Ht(T,v);let O=T.attachShadow({mode:"open"});Yt(O);let D=_!=="inline"&&!h,y=d(D?"dialog":_==="inline"?"section":"div"),Z=d("div","ov"),$=d("div","w"),H=d("div","m");h&&(H.dataset.hpMedia="");let Ce=()=>{let e=d("form","f");return e.noValidate=!0,e.addEventListener("submit",St),e.addEventListener("input",()=>{L.textContent&&E.getAttribute("aria-busy")!=="true"&&N(null)}),e},E=Ce(),L=d("p","e");L.id=Se("err"),L.setAttribute("aria-live","assertive");let se=d("div","hd");se.setAttribute("aria-hidden","true"),$.append(se,H,E),y.append(Z,$);let B=_!=="inline"&&d("button","x");B&&(B.type="button",B.addEventListener("click",()=>U("close")),$.append(B),Z.addEventListener("click",()=>U("close"))),O.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:i.coupon?{code:i.coupon}:h?{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},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")))&&i.loadAnswers().catch(()=>null),Oe=new WeakMap,Le=()=>{let e=I(v.button)?v.button:{};y.className=`s ${n.mode}${F?` p-${F}`:""} b-${Y(["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)"),Ie=()=>{n.mobile=Q?.matches===!0,pe(),Le()};Q&&(n.mobile=Q.matches===!0,Q.addEventListener?.("change",Ie));let ae=!r.channels?.length,G=(e,t,o={})=>{if(!(h||!l.decision_id||!p.analytics())){if(e==="click"){let s=n.clicked;if(n.clicked=!0,s&&!o.products)return}x.slotEngaged({decision_id:l.decision_id,slot:l.slot,arm:l.arm??null,engagement:e,step:t??n.step?.id??null,...o})}},N=(e,t)=>{L.className="e",L.textContent=e??"";for(let s of E.querySelectorAll("[aria-invalid]"))s.removeAttribute("aria-invalid");let o=t?.closest("label,fieldset");o&&E.contains(o)?o.after(L):E.append(L),t&&(t.setAttribute("aria-invalid","true"),t.setAttribute("aria-describedby",L.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},Me=()=>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,o,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 j=Wt(e,u);if(j.length>1)for(let z of j){let M=d("source");M.src=z;let q=$e(z);q&&(M.type=q),m.append(M)}else m.src=u;n.videos.push(m)}else{m=d("img",t),m.alt=g,m.decoding="async",m.loading=o?"eager":"lazy",o&&(m.fetchPriority="high");let A=ct(e,u,P(e.width,1,8192));A&&(m.sizes=at(n.mode,n.size,s,c),m.srcset=A),m.src=u}let f=P(e.width,1,8192),k=P(e.height,1,8192);return f&&k&&(m.width=f,m.height=k),I(e.focal)&&(m.style.objectPosition=`${P(e.focal.x,0,100)??50}% ${P(e.focal.y,0,100)??50}%`),m}function Pe(e,t){let o=d("label","l");o.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",L.id),s.addEventListener("focus",Me,{once:!0}),t!=="tel")return o.append(s),o;s.id=`${L.id}-p`,o.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),o.append(u),o}function ft(e){let t=r.questions.find(f=>f.key===e.question);if(!t||!ke(t)&&!Array.isArray(t.options))return null;let o=d("fieldset");o.dataset.question=t.key,o.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 o.append(d("p","sm",S.unavailable));if(c)return f.answerCards(o,t,e,d,s,k=>ce(k,"qi",!1,lt(n.size,t),"50vw"),O);f.answerFields(o,t,d,s[0],J),Oe.set(o,()=>f.answerOf(o,t,void 0,J))}),o;let u=t.type==="many",g=Y(["list","dropdown"],e.display,"buttons"),m=t.options.filter(f=>I(f)&&typeof f.value=="string");if(g==="dropdown"&&!u)return o.append(xe(d,t.label??t.key,"\u2014",m.map(f=>[f.value,f.label??f.value]),s[0])),o;g!=="buttons"&&(o.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)),o.append(k)}return o}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 o=d("button","btn cp");o.type="button",o.textContent="Copy code",o.addEventListener("click",()=>{navigator.clipboard?.writeText(n.claim.code).then(()=>{o.textContent=S.copied}).catch(()=>{})}),e.append(t,o)}}function mt(e){if(n.claim&&!n.claim.code)return null;let t=d("div","cd");return t.hidden=!0,Te.then(o=>o&&t.isConnected&&n.timers.push(o.countdown(t,e,h,d,r.window.daily?.next))),t}function de(e,t){return e.href=t,e.rel="noopener",e.addEventListener("click",o=>{if(h)return o.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 o=d("button",`btn${nt[e.variant]??""}`,t);return o.type=e.action==="submit"?"submit":"button",o.type==="button"?o.addEventListener("click",()=>re(e)):o.dataset.submit="",o}let qe=(e,t,o)=>(e.classList.add(`x-${Y(Pt,t.size,o)}`),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 o=P(e.radius,0,48);o!==null&&(t.style.borderRadius=`${o}px`);let s=P(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=P(e.threshold,.01,1e7);if(!t)return null;let o=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)),o.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(i.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)),o}function gt(e){let t=d("div","pr");return i.loadProducts?.().then(o=>{t.isConnected&&n.timers.push(o.mountProducts(t,e,{el:d,lang:J,root:O,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 o=d("label","c"),s=d("input");return s.type="checkbox",s.name="hp_consent",s.required=!0,s.setAttribute("aria-describedby",L.id),o.append(s,d("span","",t)),o},question:ft,wheel(){let e=d("div","wh");return i.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",()=>U("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){H.replaceChildren();let o=e.media,s=!o||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}`,H.hidden=s,H.hidden)return;let c=ce(o,"",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=""),H.append(c);return}let u=X(o.href),g=u?de(d("a","io"),u):d("button","io");u||(g.type="button",g.addEventListener("click",()=>re({action:"next"}))),g.append(c),H.append(g)}function yt(e){let t=e.find(c=>c?.t==="heading"),o=e.find(c=>c?.t==="button"&&c.action==="next"),s=d("button","tb");return s.textContent=t?d("b","",t.text).textContent:o?.label??"Open",s.type="button",s.addEventListener("click",()=>re(o??{action:"next"})),s}function R(e,t=new Set){let o=a.steps.find(z=>z.id===e);if(!o)return U("done");if(o.kind==="question"&&!h&&!p.analytics()&&!t.has(o.id))return R(ee(o,n.answers),t.add(o.id));let s=n.step!==null,c=s&&(O.activeElement||document.activeElement===document.body),u=s&&!h?{mode:n.mode,w:$.offsetWidth,h:$.offsetHeight,top:$.offsetTop}:null;n.step=o,n.touched=!1;for(let z of n.timers.splice(0))ot(z);n.codes=[],n.videos=[],n.wheel=null;let g=_==="teaser"&&o===a.steps[0];if(n.mode=_==="teaser"&&!g?"popup":_,_==="teaser"&&w.tab?.(r.slot,g),B&&B.setAttribute("aria-label",g?S.closeOffer:"Close"),Le(),y.removeAttribute("aria-labelledby"),u){let z=Ce();E.replaceWith(z),E=z}let m=rt(o);xt(m,g);let f=u?.mode==="popup"&&n.mode==="popup";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();let k=o.blocks.map(z=>i.fill?.(z,n.answers)??z);if(g&&m.template!=="image-only")E.append(yt(k));else for(let[z,M]of k.entries()){let q=I(M)&&Object.hasOwn(je,M.t)?je[M.t](M):null;q&&(h&&(q.dataset.hpBlock=String(z)),E.append(q))}let A=E.querySelector("[data-submit]"),j=E.querySelector("[name=hp_consent]")?.parentNode;A&&j&&A.before(j),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&&De(),le(),h||wt(o),c&&E.querySelector("h2")?.focus()}function pe(){$.classList.remove("lk","an"),$.style.removeProperty("--tp")}function vt(e){let t=$.offsetHeight;$.classList.add("an");let o=$.offsetTop,s=Math.max(0,e.top-o);if(s+t>y.clientHeight-2*o)return pe();$.style.setProperty("--tp",`${s}px`)}function wt(e){let t=e.next??{};for(let c of[t.default,...Object.values(I(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 o=()=>{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(o,{timeout:2e3}):setTimeout(o,200);document.readyState==="complete"?s():window.addEventListener("load",s,{once:!0})}function De(){if(!D)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 Re(){for(let e of E.querySelectorAll("fieldset[data-question]")){let t=e.dataset.question,o=Oe.get(e)?.()??{};if(o.error)return o;let s=[o.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(([o,s])=>({question:o,values:s})).filter(o=>!n.sent.has(ue(o))),t=({question:o})=>n.answeredOn[o];if(n.signedUp){for(let o of new Set(e.map(t))){let s=e.filter(c=>t(c)===o);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:o,...n.signedUp,answers:s,context:Fe()})}return}if(p.analytics())for(let o of e)n.sent.add(ue(o)),x.preferencesStated({...o,source:"onsite",slot:l.slot,arm:l.arm??null,decision_id:l.decision_id??null,step:t(o)})}let ue=({question:e,values:t})=>`${e}=${t.join(",")}`,We=()=>{ae&&(Re(),Ue())},Fe=()=>({page:{url:p.pageUrl()},locale:p.locale()??void 0,consent:p.consent()}),oe=e=>{!h&&(n.receipt||ae)&&Ue(),R(ee(n.step,n.answers,e))};async function kt(e){let t=n.step,o=E.querySelector("input[name=email],input[name=phone]");if(!o)return oe(e.next);let s=o.name==="email"?"email":"sms",c=E.querySelector("select[name=hp_cc]")?.value,u=s==="email"?Ke(o.value.trim())?o.value.trim():null:Xe(o.value,c);if(!u)return N(s==="email"?S.email:c?S.phone:S.intl,o);let g=E.querySelector("input[name=hp_consent]");if(g&&!g.checked)return N(S.consent,g);N(null),V(!0);let m=await Me();n.pow=null;let f=Object.entries(n.answers).map(([W,he])=>({question:W,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()}),j=A.body?.status,z=(A.status===202||A.status===200)&&It.includes(j);if(n.closed&&!z)return;z||V(!1);let M=A.status===400?A.body?.field:null;if(M==="email"||M==="phone")return N(S[M],o);if(!z)return N(A.status===429?S.busy:S.failed,o);o.value="";for(let[W,he]of Object.entries(n.answers))n.sent.add(`${W}=${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 q=n.owed?fe([]):null;q||i.emit?.("submitted",{coupon:null});let _t=q&&await Promise.race([q,new Promise(W=>setTimeout(W,Rt))]);if(n.closed)return;if(V(!1),_t?.held)return R(ie("held"));let $t=j!=="ok"&&a.steps.some(W=>W.id===j);R($t?j:ee(t,n.answers,e.next));let zt=n.step;q?.then(W=>{W?.held&&!n.closed&&n.step===zt&&!n.touched&&R(ie("held"))})}function ie(e){if(a.steps.some(s=>s.id===e))return e;let t={t:"button",label:S.shop,action:"close"},o=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:o}),e}function He(e){n.owed&&(n.owed=!1,i.emit?.("submitted",{coupon:e?{code:e.code??null,prize:e.prize?.key}:null}))}function fe(e=Dt){let t=n.receipt;return n.claiming??(n.claiming=(async()=>{n.unclaimed=!1;let o;for(let g of[0,...e])if(g&&await new Promise(m=>setTimeout(m,g)),o=await b.claim({slot:l.slot,decision_id:l.decision_id??void 0,receipt:t}),o.status!==503)break;let s=o.body,c=s?.fallback===!0&&!s.code;if(o.status!==200||!(I(s?.prize)||c))return n.claiming=null,!e.length&&o.status===503?fe():(He(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),He(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(ie("unclaimed"));let o=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&&!o){if(await n.wheel.spinTo(s),n.closed)return;L.className="e won",L.textContent=`${S.won} ${t.prize.label}`,await new Promise(g=>setTimeout(g,Ut))}if(n.closed)return;V(!1);let c=o?"fallback":s<0?"held":null,u=c?ie(c):ee(n.step,n.answers,e.next);u?R(u):ne()}function re(e){if(e.action==="close")return U("close");let t=Re();return h?oe(e.next):t?N(t.error,t.input):(ae&&n.step.blocks.some(o=>n.answers[o?.question])&&G("click"),e.action==="apply"?(i.emit?.("apply",{coupon:n.claim?.code?{code:n.claim.code}:null}),G("click"),oe(e.next)):e.action==="submit"?kt(e):e.action==="spin"?At(e):oe(e.next))}function St(e){if(e.preventDefault(),E.getAttribute("aria-busy")==="true")return;let t=n.step.blocks.find(o=>o?.t==="button"&&o.action==="submit");re(t??{action:"next"})}function me(e=!1){n.closed=!0;for(let o of n.timers.splice(0))ot(o);document.removeEventListener("visibilitychange",le),Q?.removeEventListener?.("change",Ie);let t=()=>{try{y.open&&y.close()}catch{}T.remove()};if(e||!D||Ae())return t();y.classList.add("out"),setTimeout(t,Nt)}function U(e){n.closed||h||(We(),!n.submitted&&e!=="done"&&G("dismiss"),w.closed(r.slot),w.tab?.(r.slot,!1),me(),i.onClose?.(e))}for(let e of["pointerdown","keydown","input"])y.addEventListener(e,()=>{n.touched=!0});y.addEventListener("cancel",e=>{e.preventDefault(),U("esc")}),y.addEventListener("keydown",e=>{e.key==="Escape"&&!n.modal&&_!=="inline"&&U("esc"),e.key==="Tab"&&n.modal&&Et(e)});function Et(e){let t=[...O.querySelectorAll("input[type=radio]:checked")],o=new Set,s=[...O.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:o.has(f.name))?!1:(o.add(f.name),!0)});if(!s.length)return;let c=e.shiftKey,u=O.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,o=0,s=u=>{o=Math.max(0,u.clientY-t),$.style.transform=`translateY(${o}px)`},c=()=>{document.removeEventListener("pointermove",s),document.removeEventListener("pointerup",c),$.style.transform="",o>80&&U("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),(i.container??document.body).append(T),De()}catch(e){throw me(!0),e}return{close:U,root:O,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};})();
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
(()=>{function v(n,r){try{return new Intl.NumberFormat(n||void 0,{style:"currency",currency:r})}catch{return null}}var A=(n,r=0)=>r<=6&&typeof n=="object"&&!!n&&(Array.isArray(n)?n.some(o=>A(o,r+1)):typeof n.v=="string"||A(n.b??n.i??n.a,r+1));var $=Symbol.for("@thg-agentic/hyper-personalisation-web.onsite.page-values"),F=60,I=new RegExp("[\\u0000-\\u001f\\u007f-\\u009f\\u200b-\\u200f\\u202a-\\u202e\\u2060-\\u206f\\ufeff]","g"),N={basket_value:{style:"money"},basket_items:{style:"number",plural:{one:"item",other:"items"}}},M="answer.",S=["first_name"],_=[["year",31536e6],["month",2592e6],["week",6048e5],["day",864e5],["hour",36e5],["minute",6e4]];function E(n){let r=[...String(n).replace(I,"").replace(/\s+/g," ").trim()];return r.length>F?`${r.slice(0,F-1).join("").trimEnd()}\u2026`:r.join("")}function P(n){try{return Intl.getCanonicalLocales(n||[])[0]}catch{return}}var T=new Map,y=(n,r)=>(T.has(n)||T.set(n,r()),T.get(n));function d(n,r,{lang:o,currency:c,plural:h,now:a}={}){if(n==null||n==="")return null;try{if(r==="date"||r==="relative"){let t=typeof n=="number"?n:Date.parse(n);if(!Number.isFinite(t))return null;if(r==="date")return y(`date ${o}`,()=>new Intl.DateTimeFormat(o,{dateStyle:"medium"})).format(t);let u=t-(a??Date.now()),[i,s]=_.find(([,l])=>Math.abs(u)>=l)??["minute",6e4];return y(`relative ${o}`,()=>new Intl.RelativeTimeFormat(o,{numeric:"auto"})).format(Math.round(u/s),i)}if(r!=="number"&&r!=="money")return E(n)||null;if(typeof n!="number"||!Number.isFinite(n))return null;let m=r==="money"?y(`money ${o} ${c}`,()=>v(o,c)):y(`number ${o}`,()=>new Intl.NumberFormat(o));if(!m)return null;let g=m.format(n);if(!h)return g;let w=y(`plural ${o}`,()=>new Intl.PluralRules(o)).select(n)==="one";return E(`${g} ${(w?h.one:h.other)??""}`)}catch{return null}}function j(n,r,o){let c=P(n.locale||globalThis.document?.documentElement.lang),h=new Map((Array.isArray(n.questions)?n.questions:[]).map(t=>[t?.key,t])),a=null,m=()=>{if(!a){let t=globalThis.window?.[$]??o??{};a={...r.values?.()};for(let u of S)typeof t[u]=="string"&&(a[u]=t[u]);queueMicrotask(()=>{a=null})}return a},g=(t,u)=>{let i=h.get(t),{answers:s}=m();if(!i||!s)return null;let l=u?.[t]??s[t],e=(Array.isArray(l)?l:[]).flatMap(b=>{let f=i.options?.find(p=>p?.value===b)?.label;return typeof f=="string"&&f?[E(f)]:[]});if(!e.length)return null;try{return y(`list ${c}`,()=>new Intl.ListFormat(c,{type:"conjunction"})).format(e)}catch{return e.join(", ")}},w=(t,u)=>{let i=t.v,s=t.format&&typeof t.format=="object"?t.format:N[i],l=i.startsWith(M)?g(i.slice(M.length),u):m()[i];return d(l,s?.style??"text",{lang:c,currency:m().currency,plural:s?.plural})};return(t,u)=>{if(t?.t!=="heading"&&t?.t!=="text"||!A(t.text))return t;let i=!1,s=(e,b)=>{if(typeof e=="string"||b>6)return e;if(Array.isArray(e))return e.map(p=>s(p,b+1));if(!e||typeof e!="object")return e;if(typeof e.v=="string"){let p=w(e,u);return p===null&&(i=!0),p??E(e.fallback??"")}let f="b"in e?"b":"i"in e?"i":"a"in e?"a":null;return f?{...e,[f]:s(e[f],b+1)}:e},l=s(t.text,0);return i&&t.missing==="hide"?!1:{...t,text:l}}}window[Symbol.for("@thg-agentic/hyper-personalisation-web.onsite.values")]={fillFor:j};})();
|
package/dist/onsite-wheel.min.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
(()=>{function
|
|
1
|
+
(()=>{function F(e,o,s=5){let n=360/o;return s*360+(360-(e+.5)*n)}var P="http://www.w3.org/2000/svg",I=4500,T=.22,O=.95,R=.105,L=.082,A=.062,z=.62,w=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 s=document.createElementNS(P,e);for(let[n,i]of Object.entries(o))s.setAttribute(n,String(i));return s}function f(e,o,s,n=1){return e.style.fill=o,n<1&&(e.style.fillOpacity=String(n)),s&&(e.style.stroke=s),e}var D=()=>globalThis.matchMedia?.("(prefers-reduced-motion: reduce)")?.matches===!0,S=(e,o=1)=>{let s=(e-90)*Math.PI/180;return`${(o*Math.cos(s)).toFixed(4)} ${(o*Math.sin(s)).toFixed(4)}`};function q(e,o){let s=O-T,n=2*.35*Math.sin(Math.min(Math.PI/o,Math.PI/2)),i=t=>Math.max(L,Math.min(R,n/(t*w))),a=t=>s/(Math.max(1,t.length)*z),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[L,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 d=Math.floor(s/(A*z));return{lines:[`${e.slice(0,d-1).trimEnd()}\u2026`],size:A}}function C(e){let o=O-T,s=n=>n.getComputedTextLength?.()??0;for(let n of e){let i=[...n.querySelectorAll("tspan")],a=Math.max(0,...i.map(s));if(!(a>o))continue;let r=Math.max(A,Number(n.getAttribute("font-size"))*o/a);n.setAttribute("font-size",r.toFixed(4)),i.forEach((u,p)=>{u.setAttribute("y",((p-(i.length-1)/2)*r*w).toFixed(4)),s(u)>o&&(u.setAttribute("textLength",o.toFixed(4)),u.setAttribute("lengthAdjust","spacingAndGlyphs"))})}}function v(e,o){let s=(Array.isArray(o)?o:[]).map(d=>String(d?.label??d?.key??"")),n=s.length;if(n<2)return null;let i=360/n,a=c("svg",{viewBox:"-1.2 -1.2 2.4 2.4",role:"img","aria-label":`Prize wheel: ${s.join(", ")}`}),r=c("g");r.style.transformBox="fill-box",r.style.transformOrigin="50% 50%";let u=[[1,k],[.14,N],[.72,k]];r.append(f(c("circle",{r:1}),g));let p=[],h=[];return s.forEach((d,t)=>{let[l,m]=u[n%2===1&&t===n-1?2:t%2];r.append(f(c("path",{d:`M0 0L${S(t*i)}A1 1 0 ${i>180?1:0} 1 ${S((t+1)*i)}Z`,"stroke-width":.012}),$,g,l));let _=(t+.5)*i-90,x=q(d,n),b=f(c("text",{transform:`rotate(${_}) translate(${(T+O)/2} 0)${_>90&&_<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*w).toFixed(4)});y.textContent=E,b.append(y)}),r.append(b),h.push(b);for(let E of[t*i,(t+.5)*i]){let[M,y]=S(E,1.075).split(" ");p.push(f(c("circle",{cx:M,cy:y,r:.024}),g))}}),a.append(f(c("circle",{r:1.13}),N),...p,r,f(c("circle",{r:.17,"stroke-width":.035}),g,N),f(c("circle",{r:.065}),$),f(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(d){let t=D();return r.style.transition=t?"none":`transform ${I}ms cubic-bezier(.15,.7,.1,1)`,r.style.transform=`rotate(${F(d,s.length,t?0:5)}deg)`,t?Promise.resolve():new Promise(l=>{let m=setTimeout(l,I+200);r.addEventListener("transitionend",()=>{clearTimeout(m),l()},{once:!0})})},remove:()=>a.remove()}}window[Symbol.for("@thg-agentic/hyper-personalisation-web.onsite.wheel")]={mountWheel:v};})();
|
package/dist/onsite.min.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
(()=>{function x(e){let s=typeof document>"u"?null:document.currentScript?.src;return s?new URL(e,s).href:null}var G=new Map;function T(e,s){return window[s]?Promise.resolve(window[s]):e?(G.has(s)||G.set(s,new Promise((n,r)=>{let p=document.createElement("script");p.src=e,p.async=!0,p.onload=()=>window[s]?n(window[s]):r(new Error(`${e} did not register`)),p.onerror=()=>r(new Error(`${e} did not load`)),document.head.append(p)}).finally(()=>G.delete(s))),G.get(s)):Promise.reject(new Error("the CDN script\u2019s own URL is unknown"))}var nt=x("onsite-answers.min.js"),ge=()=>T(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 me(e,s={}){let n=s.fetch??globalThis.fetch?.bind(globalThis),r=s.servingHost??e.servingHost,p=s.gatewayHost??e.gatewayHost;async function l(c,{method:o="GET",body:i,consent:u=!1,timeoutMs:y}={}){if(!n)return{status:0,body:null};try{let S=await n(c,{method:o,credentials:"omit",signal:y&&AbortSignal.timeout?.(y),headers:{accept:"application/json",authorization:`Bearer ${e.writeKey}`,...i?{"content-type":"application/json"}:{},...u?e.headers():{}},...i?{body:JSON.stringify(i)}:{}}),A=null;try{A=await S.json()}catch{}return{status:S.status,body:A}}catch{return{status:0,body:null}}}let h=(c,o)=>l(`${p}/v1/capture${c}`,{method:"POST",body:o}).then(i=>(i.status>=200&&i.status<300&&e.answered?.(o.answers,o.slot),i));return{decide:(c,o,{visitAudiences:i,visitCampaign:u,visitContext:y,timeoutMs:S=3e3}={})=>l(`${r}/v1/decisions`,{method:"POST",consent:!0,timeoutMs:Math.max(1,S),body:{slots:[o?{key:c,pin:{experiment:o[0],arm:o[1],split:o[2]}}:c],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}:{},...i&&{visit_audiences:i.claims,...i.answered?.length&&{answered_audiences:i.answered}},...u?{visit_campaign:u}:{},...y?{visit_context:y}:{}}}),datafile:()=>l(`${r}/v1/audiences/datafile`,{timeoutMs:1500}),challenge:()=>l(`${p}${ot(s.challenge)}`),capture:c=>h("",c),answers:c=>h("/answers",c),claim:c=>l(`${r}/v1/offers/claim`,{method:"POST",consent:!0,body:c,timeoutMs:8e3})}}var it=x("onsite-audiences.min.js"),ye=()=>T(it,Symbol.for("@thg-agentic/hyper-personalisation-web.onsite.audiences"));function be(e,s){let n={},r=()=>{try{let l=JSON.parse(e().getItem(s));l&&typeof l=="object"&&(n=l)}catch{}return n};return{read:r,write:l=>{let h=r();l(h),n=h;try{e().setItem(s,JSON.stringify(h))}catch{}}}}function Se(e,s=()=>!0){let n=be(()=>sessionStorage,e),r=be(()=>localStorage,e),p=()=>s()?r:n,l=()=>{let o=r.read();(o.sub!==void 0||o.k!==void 0)&&r.write(i=>{delete i.sub,delete i.k})},h=()=>s()?[n.read(),r.read()]:(l(),[n.read()]),c=(o,i)=>{var u;return o.f??(o.f={}),(u=o.f)[i]??(u[i]={}),o.f[i]};return{seen(o){let i=r.read().f?.[o]??{};return{session:n.read().f?.[o]?.n??0,lifetime:i.n??0,closedAt:i.c??null,submitted:i.s===1}},subscribed:()=>h().some(o=>o.sub===1),shown(o){n.write(i=>{let u=c(i,o);u.n=(u.n??0)+1}),r.write(i=>{let u=c(i,o);u.n=(u.n??0)+1})},closed(o,i=Date.now()){r.write(u=>{c(u,o).c=i})},tab(o,i){n.write(u=>{let y=c(u,o);i?y.t=1:delete y.t})},tabOut:o=>n.read().f?.[o]?.t===1,pin(o,i){if(i===void 0)return n.read().f?.[o]?.p??null;n.write(u=>{c(u,o).p=i})},coveredAt:()=>n.read().o??null,covered(o=Date.now()){n.write(i=>{i.o=o})},code(o,i=Date.now()){if(o===void 0){let[u]=h().flatMap(y=>y.k?[y.k]:[]).sort((y,S)=>S.at-y.at);return u&&i-u.at<14*864e5?u.c:null}return p().write(u=>{u.k={c:o,at:i}}),o},submitted(o){r.write(i=>{c(i,o).s=1}),p().write(i=>{i.sub=1})}}}var rt=x("onsite-products.min.js"),V=()=>T(rt,Symbol.for("@thg-agentic/hyper-personalisation-web.onsite.products"));var lt=x("onsite-render.min.js"),_e=()=>T(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 r=Ae(e),p=Ae(n);return s==="is"?r===p:s==="contains"&&p!==""&&r.includes(p)}function ve(e,s){return(Array.isArray(e)?e:[]).every(n=>{let r=s?.[n?.field];return!at.includes(n?.field)||typeof r!="string"?!1:[].concat(n.values??[]).some(p=>ct(r,n.match,p))})}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",E=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(E)?e:[dt];function Ce(e){if(!E(e)||typeof e.slot!="string"||e.slot==="")return null;let s=E(e.trigger)?e.trigger:{};if(!Me.includes(e.format)||!ut.includes(s.type))return null;let n=E(e.caps)?e.caps:{};return{...e,trigger:s,priority:Number.isFinite(e.priority)?e.priority:0,pages:E(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:E(e.window)?e.window:{},questions:Array.isArray(e.questions)?e.questions.filter(E):[],prizes:Array.isArray(e.prizes)?e.prizes.filter(E):[]}}var ft=/^[a-z][a-z0-9_-]{0,31}$/;function Oe(e){if(!E(e)||e.v!==1||!Array.isArray(e.steps))return null;let s=e.steps.filter(n=>E(n)&&ft.test(n.id)&&Array.isArray(n.blocks));return s.length===0?null:{format:Me.includes(e.format)?e.format:null,theme:E(e.theme)?e.theme:{},steps:s}}function xe(e,s){let n=String(e).split("*").map(r=>r.replace(/[.+?^${}()|[\]\\]/g,"\\$&")).join(".*");return new RegExp(`^${n}$`,"i").test(s)}function ht(e,s){let n=j(e?.include);return(!n.length||n.some(r=>xe(r,s)))&&!j(e?.exclude).some(r=>xe(r,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 r=Te(e.window.starts_at),p=Te(e.window.ends_at);if((s.now<r||s.now>=p)&&n.push("outside its dates"),e.audiences.length&&!s.preview&&(s.personalisation?s.audiences&&!e.audiences.some(c=>s.audiences.includes(c))&&n.push("not in its audiences"):n.push("audiences need personalisation consent")),s.preview||s.asked||U(e))return n;let{seen:l}=s,{caps:h}=e;return l.submitted&&n.push("already submitted"),e.exclude_subscribed===!0&&s.subscribed&&n.push("already subscribed"),h.per_session!==null&&l.session>=h.per_session&&n.push("per_session cap"),h.lifetime!==null&&l.lifetime>=h.lifetime&&n.push("lifetime cap"),h.after_close_days!==null&&l.closedAt&&s.now-l.closedAt<h.after_close_days*864e5&&n.push("closed recently"),n}var $e=(e,s)=>s.priority-e.priority;var wt=["mousemove","pointerdown","keydown","scroll","touchstart","wheel"];function gt(){let e=[];return{on:(r,p,l,h={passive:!0})=>{r.addEventListener(p,l,h),e.push(()=>r.removeEventListener(p,l,h))},later:(r,p)=>{let l=setTimeout(r,p);e.push(()=>clearTimeout(l))},stop:()=>{for(let r of e.splice(0))r()}}}var Ne=(e,s)=>{let n=s.documentElement.scrollHeight||0;return n>0?(e.scrollY+e.innerHeight)/n:0},mt=e=>{let s=e.activeElement;return!!(s&&(/^(INPUT|TEXTAREA|SELECT)$/.test(s.tagName)||s.isContentEditable))};function yt({on:e,later:s},n,r,p,l){let h=!1,c=!1,o=null,i=0;s(()=>{h=!0},r.delay_ms??5e3),e(l,"mousemove",u=>{u.clientY>p.innerHeight*.1&&(c=!0),o!==null&&(i=u.clientY-o),o=u.clientY}),e(l,"mouseout",u=>{h&&c&&!u.relatedTarget&&u.clientY<=0&&i<0&&!mt(l)&&n("exit")})}function bt({on:e,later:s},n,r,p,l){let h=!1,c=0,o=p.scrollY,i=Date.now(),u=null,y=null;s(()=>{h=!0},r.delay_ms??5e3),e(p,"scroll",()=>{let S=p.scrollY,A=Date.now();if(c=Math.max(c,Ne(p,l)),S<o){(!u||A-u.t>300)&&(u={y:o,t:i});let M=u.y-S;h&&c>=.3&&M>=120&&M/Math.max(1,A-u.t)>=.5&&n("exit_scroll")}else u=null;o=S,i=A}),e(l,"visibilitychange",()=>{l.visibilityState==="hidden"?y=Date.now():y!==null&&Date.now()-y>=1e4&&n("return"),l.visibilityState!=="hidden"&&(y=null)})}function Pe(e,s,{device:n,win:r=window,doc:p=document}){let l=gt(),h=(e.seconds??30)*1e3;if(e.type==="entry"&&l.later(()=>s("entry"),e.delay_ms??0),e.type==="time"&&l.later(()=>s("time"),h),e.type==="exit"&&(n==="mobile"?bt:yt)(l,s,e,r,p),e.type==="scroll"){let c=e.depth??.5;l.on(r,"scroll",()=>Ne(r,p)>=c&&s("scroll"))}if(e.type==="idle"){let c=null,o=()=>{clearTimeout(c),c=setTimeout(()=>s("idle"),h)};o();for(let i of wt)l.on(i==="scroll"?r:p,i,o);return l.on(p,"visibilitychange",o),()=>{clearTimeout(c),l.stop()}}return l.stop}var St=x("onsite-wheel.min.js"),ke=()=>T(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 r=s.settings??n.settings??{};n.started?.(r);let p=me(n,{...s,challenge:r.capture?.challenge}),l=n.preview?Fe:Se(n.storageKey,n.personalisation),h=()=>n.campaign?.()??null,c=new Map,o=()=>window[Re]?.size>0,i=(t,a)=>{for(let d of window[At]?.[t]??[])try{d(a)}catch(f){console.warn(`[hp] onsite ${t} listener failed:`,f)}},u=De(window),y=n.debug||s.debug===!0||Tt(),S=new Map,A=new Map,M=[];for(let t of Array.isArray(r.forms)?r.forms:[]){let a=Ce(t);a?M.push(a):S.set(String(t?.slot??`form ${S.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(p));let N=new Map,K=new Map,I=null,le=!1,ae=new Set,He=t=>{for(let a of N.keys()){let d=c.get(a);if(!t||!d||d.modal?.())return a}return null},H=null,q=new Set,B=Number.isInteger(r.overlay_gap_minutes)?r.overlay_gap_minutes:0,Ye=()=>{let t=l.coveredAt();if(!(B>0)||typeof t!="number")return null;let a=Math.max(0,Math.floor((Date.now()-t)/6e4));return a<B?`a popup showed ${a} min ago; ${B} min between them`:null},P=new Set,Y=new Map,b=(t,a,d,f=[])=>(S.set(t.slot,{slot:t.slot,format:t.format,trigger:t.trigger.type,priority:t.priority,state:a,code:d,reasons:f}),y&&console.info(`[hp] onsite ${t.slot}: ${a}${f.length?` (${f.join("; ")})`:""}`),{state:a,code:d}),D=(t,a,d,f)=>(N.delete(t.slot),b(t,a,d,f)),k=(t,a,d)=>{let f;return Promise.race([t,new Promise(m=>{f=setTimeout(m,a-Date.now(),d)})]).then(m=>Date.now()>a?d:m).finally(()=>clearTimeout(f))},Xe=(t,a)=>{le||o()||(I??(I=t.slot),i("nothing",{slot:t.slot,format:t.format,code:a}))},ce=()=>{try{let t=s.audiences?.();return Array.isArray(t)?t:null}catch{return null}},ue=t=>({path:location.pathname,device:u,campaign:h(),now:Date.now(),seen:l.seen(t.slot),subscribed:l.subscribed()||s.subscribed?.()===!0,personalisation:n.personalisation(),preview:!!n.preview,audiences:ce()}),J=t=>{A.get(t.slot)?.(),A.delete(t.slot)};function L(t,a,d=!1,f=U(t),m=Date.now()+je){if(c.has(t.slot))return Promise.resolve({state:"shown",code:"shown",asked:f});let g=K.get(t.slot);return g?(g.asked||(g.asked=f),g.done):(g={asked:f},g.done=ze(t,a,d,f,m).catch(v=>c.has(t.slot)?{state:"shown",code:"shown"}:(console.warn("[hp] onsite form failed:",v?.message??v),D(t,"not shown","error",[`failed: ${v?.message??v}`]))).then(v=>(K.delete(t.slot),{...v,asked:g.asked||g.opened})),K.set(t.slot,g),g.done)}async function ze(t,a,d,f,m){if(o())return b(t,"not shown","suppressed",[`suppressed: ${[...window[Re]].join(", ")}`]);let g=ie(t,{...ue(t),...d?{seen:Fe.seen()}:{},asked:f});if(g.length)return b(t,"not eligible","not-eligible",g);let v=Ie(t.format)&&!d,C=v&&!f&&Ye();if(C)return b(t,"not shown","overlay-gap",[C]);if(v&&!n.preview&&n.consentAnswered?.()===!1)return Y.set(t,f),b(t,"not shown","awaiting-consent",["waiting for the consent banner"]);let O=oe(t.format),pe=O&&He(f);if(pe)return b(t,"not shown","another-showing",[`${pe} is showing`]);if(O&&I&&!f)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",[a]);let Be=_e().catch(w=>(console.warn("[hp] onsite renderer not loaded:",w?.message??w),null)),z=t.visit_context===!0?V().catch(()=>null):null,Q=ce()??[],fe={claims:[...new Set([...t.audiences,...Q])].filter(w=>Q.includes(w)).slice(0,100)},Je=t.audiences.length>0&&!n.preview&&n.personalisation()?await k(re().then(w=>w?w.visitAudiences(p,n.sessionSignals,t.audiences,Q):fe),Math.min(m,Date.now()+Et),fe):null,F=Date.now()<m?await k(p.decide(t.slot,l.pin(t.slot),{visitAudiences:Je,visitCampaign:t.arrived_from.length?h():null,visitContext:t.visit_context===!0?n.visitContext?.()??null:null,timeoutMs:m-Date.now()}),m,Ue):Ue,ee=F.status===200?F.body?.decisions:null,_=Array.isArray(ee)?ee.find(w=>w?.slot===t.slot):null;_?.experiment&&_.arm&&_.split&&l.pin(t.slot,[_.experiment,_.arm,_.split]);let $=_&&_.holdout!==!0?Oe(_.payload):null,he=$?.steps[0].blocks??[],we=_?.offer?.code??(n.preview?"PREVIEW":l.code()),Ze=n.basketValue?.()??null,te=he.some(w=>w?.t==="code")&&!we&&"no code to remind of"||he.some(w=>w?.t==="progress")&&!(Ze>0)&&"the basket is empty";if(te){let w=te==="the basket is empty";return w&&P.add(t),D(t,"not shown",w?"empty-basket":"no-code",[te])}if(P.delete(t),!$){let w=_?.holdout===!0;return w&&n.analytics()&&e.recordExposure(F.body),O&&w&&(I??(I=t.slot)),w&&!f&&i("held",{slot:t.slot,arm:_.arm??null,format:t.format}),w||Array.isArray(ee)?D(t,w?"held out":"no decision",w?"held-out":"no-creative",["no creative for this visitor"]):D(t,"no decision","decision-failed",[`decisions answered ${F.status}`])}let ne=await k(Be,m,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,m,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(m,Date.now()+xt)),o())return D(t,"not shown","suppressed",["suppressed"]);let se=(w,tt={})=>i(w,{slot:t.slot,arm:_.arm??null,format:$.format??t.format,...tt}),Qe=ne.mountForm({form:t,creative:$,decision:_,access:n,client:e,api:p,counters:l,loadWheel:ke,loadAnswers:ge,loadProducts:()=>z??V(),container:X,warmed:ae,coupon:we,basket:()=>n.basketValue?.()??null,emit:se,onClose(w){c.delete(t.slot),N.delete(t.slot),b(t,"closed","closed",[w]),se("closed",{reason:w})}});c.set(t.slot,Qe),d||l.shown(t.slot),v&&l.covered(),O&&(I??(I=t.slot)),n.analytics()&&e.recordExposure(F.body);let et=b(t,"shown","shown",[a]);return se("shown"),et}function Z(t,a,d=U(t)){if(!oe(t.format))return L(t,a,!1,d);if(!H){let f={forms:[],taken:new Set,deadline:Date.now()+We+je};H=f,q.add(f),setTimeout(()=>{H=null,Ge(f)},We)}H.forms.push([t,a,d])}async function Ge(t){let a=t.forms.sort(([f],[m])=>$e(f,m)),d=null;for(let[f,[m,g,v]]of a.entries()){if(t.taken.has(m))continue;let C=await L(m,g,!1,v,t.deadline);if(!d&&vt.has(C.code)&&!C.asked&&(d=[m,C.code]),C.state==="shown"||C.state==="held out"){for(let[O]of a.slice(f+1))b(O,"not shown","lower-priority",[`${m.slot} has a higher priority`]);d=null;break}}q.delete(t),d&&Xe(...d)}for(let t of M){if(t.format==="teaser"&&l.tabOut(t.slot)){L(t,"tab kept from an earlier page",!0);continue}let a=ie(t,ue(t));if(a.length){b(t,"not eligible","not-eligible",a);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),A.set(t.slot,Pe(t.trigger,a=>{J(t),Z(t,a)},{device:u})),b(t,"armed","armed",[`${t.trigger.type} on ${u}`])}let Ve=n.onConsentAnswered?.(()=>{let t=[...Y];Y.clear();for(let[a,d]of t)c.has(a.slot)||(d?Z(a,"manual",d):de(a))}),qe=n.onBasket?.(()=>{if(!((n.basketValue?.()??0)>0))return;let t=[...P];P.clear();for(let a of t)c.has(a.slot)||Z(a,"the basket changed")}),R=Object.freeze({open(t){let a=M.find(g=>g.slot===t),d=a??M.find(g=>g.aliases.includes(t));if(!d)return Promise.resolve(!1);if(c.has(d.slot))return Promise.resolve(!0);for(let g of q)g.taken.add(d);let f=L(d,"manual",!1,U(d)||!a),m=K.get(d.slot);return m&&(m.opened=!0),f.then(({state:g})=>g==="shown")},suppress(){for(let[t,a]of c){a.destroy(),c.delete(t),N.delete(t);let d=M.find(f=>f.slot===t);d&&b(d,"closed","suppressed",["suppressed"])}},debug:()=>[...S.values()].map(t=>({...t,reasons:[...t.reasons]})),stop(){le=!0;for(let t of A.values())t();A.clear(),qe?.(),Ve?.(),P.clear(),Y.clear(),window[W]===R&&delete window[W]}});window[W]=R;for(let{slot:t,resolve:a}of window[_t]?.splice(0)??[])a(R.open(t));return y&&console.table?.(R.debug()),R}window[Symbol.for("@thg-agentic/hyper-personalisation-web.onsite.module")]={startOnsite:Ke};})();
|
|
1
|
+
(()=>{function E(e){let s=typeof document>"u"?null:document.currentScript?.src;return s?new URL(e,s).href:null}var B=new Map;function T(e,s){return window[s]?Promise.resolve(window[s]):e?(B.has(s)||B.set(s,new Promise((n,o)=>{let u=document.createElement("script");u.src=e,u.async=!0,u.onload=()=>window[s]?n(window[s]):o(new Error(`${e} did not register`)),u.onerror=()=>o(new Error(`${e} did not load`)),document.head.append(u)}).finally(()=>B.delete(s))),B.get(s)):Promise.reject(new Error("the CDN script\u2019s own URL is unknown"))}var St=E("onsite-answers.min.js"),xe=()=>T(St,Symbol.for("@thg-agentic/hyper-personalisation-web.onsite.answers"));var At="/v1/capture/challenge",vt=e=>typeof e=="string"&&/^\/v1\/[\w/-]+$/.test(e)?e:At;function Ie(e,s={}){let n=s.fetch??globalThis.fetch?.bind(globalThis),o=s.servingHost??e.servingHost,u=s.gatewayHost??e.gatewayHost;async function l(c,{method:i="GET",body:r,consent:p=!1,timeoutMs:y}={}){if(!n)return{status:0,body:null};try{let b=await n(c,{method:i,credentials:"omit",signal:y&&AbortSignal.timeout?.(y),headers:{accept:"application/json",authorization:`Bearer ${e.writeKey}`,...r?{"content-type":"application/json"}:{},...p?e.headers():{}},...r?{body:JSON.stringify(r)}:{}}),S=null;try{S=await b.json()}catch{}return{status:b.status,body:S}}catch{return{status:0,body:null}}}let g=(c,i)=>l(`${u}/v1/capture${c}`,{method:"POST",body:i}).then(r=>(r.status>=200&&r.status<300&&e.answered?.(i.answers,i.slot),r));return{decide:(c,i,{visitAudiences:r,visitCampaign:p,visitContext:y,pageFacts:b,timeoutMs:S=3e3}={})=>l(`${o}/v1/decisions`,{method:"POST",consent:!0,timeoutMs:Math.max(1,S),body:{slots:[i?{key:c,pin:{experiment:i[0],arm:i[1],split:i[2]}}:c],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}:{},...r&&{visit_audiences:r.claims,...r.answered?.length&&{answered_audiences:r.answered}},...p?{visit_campaign:p}:{},...y?{visit_context:y}:{},...b?{page_facts:b}:{}}}),datafile:()=>l(`${o}/v1/audiences/datafile`,{timeoutMs:1500}),challenge:()=>l(`${u}${vt(s.challenge)}`),capture:c=>g("",c),answers:c=>g("/answers",c),claim:c=>l(`${o}/v1/offers/claim`,{method:"POST",consent:!0,body:c,timeoutMs:8e3})}}var Et=E("onsite-audiences.min.js"),Me=()=>T(Et,Symbol.for("@thg-agentic/hyper-personalisation-web.onsite.audiences"));function De(e,s){let n={},o=()=>{try{let l=JSON.parse(e().getItem(s));l&&typeof l=="object"&&(n=l)}catch{}return n};return{read:o,write:l=>{let g=o();l(g),n=g;try{e().setItem(s,JSON.stringify(g))}catch{}}}}function Oe(e,s=()=>!0){let n=De(()=>sessionStorage,e),o=De(()=>localStorage,e),u=()=>s()?o:n,l=()=>{let i=o.read();(i.sub!==void 0||i.k!==void 0)&&o.write(r=>{delete r.sub,delete r.k})},g=()=>s()?[n.read(),o.read()]:(l(),[n.read()]),c=(i,r)=>{var p;return i.f??(i.f={}),(p=i.f)[r]??(p[r]={}),i.f[r]};return{seen(i){let r=o.read().f?.[i]??{};return{session:n.read().f?.[i]?.n??0,lifetime:r.n??0,closedAt:r.c??null,submitted:r.s===1}},subscribed:()=>g().some(i=>i.sub===1),shown(i){n.write(r=>{let p=c(r,i);p.n=(p.n??0)+1}),o.write(r=>{let p=c(r,i);p.n=(p.n??0)+1})},closed(i,r=Date.now()){o.write(p=>{c(p,i).c=r})},tab(i,r){n.write(p=>{let y=c(p,i);r?y.t=1:delete y.t})},tabOut:i=>n.read().f?.[i]?.t===1,pin(i,r){if(r===void 0)return n.read().f?.[i]?.p??null;n.write(p=>{c(p,i).p=r})},coveredAt:()=>n.read().o??null,covered(i=Date.now()){n.write(r=>{r.o=i})},code(i,r=Date.now()){if(i===void 0){let[p]=g().flatMap(y=>y.k?[y.k]:[]).sort((y,b)=>b.at-y.at);return p&&r-p.at<14*864e5?p.c:null}return u().write(p=>{p.k={c:i,at:r}}),i},submitted(i){o.write(r=>{c(r,i).s=1}),u().write(r=>{r.sub=1})}}}var Tt=Symbol.for("@thg-agentic/hyper-personalisation-web.onsite.page-facts");function pe(e=globalThis.window){let s=e?.[Tt];return s?.path===e?.location?.pathname?s.facts:{}}var Pe=e=>typeof e=="string"?e.slice(0,100):e,Ce=e=>typeof e=="string"?e.trim().toLowerCase():e,Ne=(e,s)=>e.every(n=>{let o=Pe(s?.[n.fact]),u=Array.isArray(n.values)?n.values:[];if(o==null||typeof o!=typeof u[0]||typeof o=="number"&&!Number.isFinite(o))return!1;let l=u.some(g=>Ce(g)===Ce(o));return n.op==="is"?l:n.op==="is_not"?!l:n.op==="at_least"?o>=u[0]:n.op==="at_most"&&o<=u[0]}),$e=(e,s)=>Object.fromEntries(e.filter(n=>n.fact in s).map(n=>[n.fact,Pe(s[n.fact])]));var xt=E("onsite-products.min.js"),J=()=>T(xt,Symbol.for("@thg-agentic/hyper-personalisation-web.onsite.products"));var It=E("onsite-render.min.js"),ke=()=>T(It,Symbol.for("@thg-agentic/hyper-personalisation-web.onsite.render"));var Z=(e,s=0)=>s<=6&&typeof e=="object"&&!!e&&(Array.isArray(e)?e.some(n=>Z(n,s+1)):typeof e.v=="string"||Z(e.b??e.i??e.a,s+1));var Mt=["source","medium","campaign","content","term"];var Le=e=>String(e).trim().toLowerCase();function Dt(e,s,n){let o=Le(e),u=Le(n);return s==="is"?o===u:s==="contains"&&u!==""&&o.includes(u)}function Fe(e,s){return(Array.isArray(e)?e:[]).every(n=>{let o=s?.[n?.field];return!Mt.includes(n?.field)||typeof o!="string"?!1:[].concat(n.values??[]).some(u=>Dt(o,n.match,u))})}var Q=["the page does not say so","not a product page"],We=["popup","sheet","bar","teaser","inline","fullscreen"],Ot=["entry","exit","scroll","time","idle","inline","manual"],fe=e=>e!=="inline",Xe=e=>e==="popup"||e==="sheet"||e==="fullscreen",x=e=>e!==null&&typeof e=="object"&&!Array.isArray(e),H=e=>Array.isArray(e)?e.filter(s=>typeof s=="string"):[],Re=e=>Number.isInteger(e)&&e>=0?e:null,Ue=(e,s)=>e==null?[]:Array.isArray(e)&&e.every(x)?e:[s];function Ke(e){if(!x(e)||typeof e.slot!="string"||e.slot==="")return null;let s=x(e.trigger)?e.trigger:{};if(!We.includes(e.format)||!Ot.includes(s.type))return null;let n=x(e.caps)?e.caps:{};return{...e,trigger:s,priority:Number.isFinite(e.priority)?e.priority:0,pages:x(e.pages)?e.pages:{},devices:H(e.devices),aliases:H(e.aliases),audiences:H(e.audiences),arrived_from:Ue(e.arrived_from,{field:null,match:null,values:[]}),page_facts:Ue(e.page_facts,{fact:null,op:null,values:[]}),products:e.products===!0,caps:{per_session:Re(n.per_session),lifetime:Re(n.lifetime),after_close_days:Number.isFinite(n.after_close_days)?n.after_close_days:null},window:x(e.window)?e.window:{},questions:Array.isArray(e.questions)?e.questions.filter(x):[],prizes:Array.isArray(e.prizes)?e.prizes.filter(x):[]}}var Ct=/^[a-z][a-z0-9_-]{0,31}$/;function Ve(e){if(!x(e)||e.v!==1||!Array.isArray(e.steps))return null;let s=e.steps.filter(n=>x(n)&&Ct.test(n.id)&&Array.isArray(n.blocks));return s.length===0?null:{format:We.includes(e.format)?e.format:null,theme:x(e.theme)?e.theme:{},steps:s}}function je(e,s){let n=String(e).split("*").map(o=>o.replace(/[.+?^${}()|[\]\\]/g,"\\$&")).join(".*");return new RegExp(`^${n}$`,"i").test(s)}function Pt(e,s){let n=H(e?.include);return(!n.length||n.some(o=>je(o,s)))&&!H(e?.exclude).some(o=>je(o,s))}function Ye(e){return e.matchMedia?.("(hover: none) and (pointer: coarse)")?.matches===!0||e.innerWidth<768?"mobile":"desktop"}var He=e=>typeof e=="string"?Date.parse(e):Number.NaN,W=e=>e.trigger.type==="manual",he="outside its daily window",ze=(e,s)=>{let{daily:n}=e.window;return n.next.find(o=>o>s)-n.within_hours*36e5-s};function ge(e,s){let n=[];Pt(e.pages,s.path)||n.push("page not included"),e.devices.length&&!e.devices.includes(s.device)&&n.push(`not on ${s.device}`),Fe(e.arrived_from,s.campaign)||n.push("not from its campaign"),!s.later&&!s.preview&&(Ne(e.page_facts,s.facts)||n.push(Q[0]),e.products&&!s.product&&n.push(Q[1]));let o=He(e.window.starts_at),u=He(e.window.ends_at);(s.now<o||s.now>=u)&&n.push("outside its dates");let{daily:l}=e.window;if(l&&!s.preview){let i=l.next?.find?.(r=>r>s.now)-s.now;i>0?!s.later&&i>l.within_hours*36e5&&n.push(he):n.push("no cut-off ahead")}if(e.audiences.length&&!s.preview&&(s.personalisation?s.audiences&&!e.audiences.some(i=>s.audiences.includes(i))&&n.push("not in its audiences"):n.push("audiences need personalisation consent")),s.preview||s.asked||W(e))return n;let{seen:g}=s,{caps:c}=e;return g.submitted&&n.push("already submitted"),e.exclude_subscribed===!0&&s.subscribed&&n.push("already subscribed"),c.per_session!==null&&g.session>=c.per_session&&n.push("per_session cap"),c.lifetime!==null&&g.lifetime>=c.lifetime&&n.push("lifetime cap"),c.after_close_days!==null&&g.closedAt&&s.now-g.closedAt<c.after_close_days*864e5&&n.push("closed recently"),n}var Ge=(e,s)=>s.priority-e.priority;var Nt=["mousemove","pointerdown","keydown","scroll","touchstart","wheel"];function $t(){let e=[];return{on:(o,u,l,g={passive:!0})=>{o.addEventListener(u,l,g),e.push(()=>o.removeEventListener(u,l,g))},later:(o,u)=>{let l=setTimeout(o,u);e.push(()=>clearTimeout(l))},stop:()=>{for(let o of e.splice(0))o()}}}var qe=(e,s)=>{let n=s.documentElement.scrollHeight||0;return n>0?(e.scrollY+e.innerHeight)/n:0},kt=e=>{let s=e.activeElement;return!!(s&&(/^(INPUT|TEXTAREA|SELECT)$/.test(s.tagName)||s.isContentEditable))};function Lt({on:e,later:s},n,o,u,l){let g=!1,c=!1,i=null,r=0;s(()=>{g=!0},o.delay_ms??5e3),e(l,"mousemove",p=>{p.clientY>u.innerHeight*.1&&(c=!0),i!==null&&(r=p.clientY-i),i=p.clientY}),e(l,"mouseout",p=>{g&&c&&!p.relatedTarget&&p.clientY<=0&&r<0&&!kt(l)&&n("exit")})}function Ft({on:e,later:s},n,o,u,l){let g=!1,c=0,i=u.scrollY,r=Date.now(),p=null,y=null;s(()=>{g=!0},o.delay_ms??5e3),e(u,"scroll",()=>{let b=u.scrollY,S=Date.now();if(c=Math.max(c,qe(u,l)),b<i){(!p||S-p.t>300)&&(p={y:i,t:r});let I=p.y-b;g&&c>=.3&&I>=120&&I/Math.max(1,S-p.t)>=.5&&n("exit_scroll")}else p=null;i=b,r=S}),e(l,"visibilitychange",()=>{l.visibilityState==="hidden"?y=Date.now():y!==null&&Date.now()-y>=1e4&&n("return"),l.visibilityState!=="hidden"&&(y=null)})}function Be(e,s,{device:n,win:o=window,doc:u=document}){let l=$t(),g=(e.seconds??30)*1e3;if(e.type==="entry"&&l.later(()=>s("entry"),e.delay_ms??0),e.type==="time"&&l.later(()=>s("time"),g),e.type==="exit"&&(n==="mobile"?Ft:Lt)(l,s,e,o,u),e.type==="scroll"){let c=e.depth??.5;l.on(o,"scroll",()=>qe(o,u)>=c&&s("scroll"))}if(e.type==="idle"){let c=null,i=()=>{clearTimeout(c),c=setTimeout(()=>s("idle"),g)};i();for(let r of Nt)l.on(r==="scroll"?o:u,r,i);return l.on(u,"visibilitychange",i),()=>{clearTimeout(c),l.stop()}}return l.stop}var Rt=E("onsite-values.min.js"),Je=()=>T(Rt,Symbol.for("@thg-agentic/hyper-personalisation-web.onsite.values"));var Ut=E("onsite-wheel.min.js"),Ze=()=>T(Ut,Symbol.for("@thg-agentic/hyper-personalisation-web.onsite.wheel"));var Qe=Symbol.for("@thg-agentic/hyper-personalisation-web.onsite-access"),X=Symbol.for("@thg-agentic/hyper-personalisation-web.onsite"),jt=Symbol.for("@thg-agentic/hyper-personalisation-web.onsite.pending"),Ht=Symbol.for("@thg-agentic/hyper-personalisation-web.onsite.listeners"),ee=Symbol.for("@thg-agentic/hyper-personalisation-web.onsite.page-said"),et=Symbol.for("@thg-agentic/hyper-personalisation-web.onsite.suppressed"),tt={seen:()=>({session:0,lifetime:0,closedAt:null,submitted:!1}),subscribed:()=>!1,shown(){},closed(){},submitted(){},tab(){},tabOut:()=>!1,pin:()=>null,coveredAt:()=>null,covered(){},code:()=>null},Wt=new Set(["decision-failed","no-creative","no-code","renderer-failed","products-failed","values-failed","error"]),nt=3e3,st={status:0,body:null},Xt=1500,ot=50,Kt=300,Vt=()=>{try{return new URLSearchParams(location.search).get("hp_debug")==="onsite"}catch{return!1}},it=(e,s)=>e.steps.some(n=>n.blocks.some(s));function rt(e,s={}){if(typeof window>"u"||typeof document>"u")return null;if(window[X])return window[X];let n=typeof e?.[Qe]=="function"?e[Qe]():null;if(!n)return console.warn("[hp] onsite: startOnsite needs the client bootstrap or createAnalytics made"),null;let o=s.settings??n.settings??{};n.started?.(o);let u=Ie(n,{...s,challenge:o.capture?.challenge}),l=n.preview?tt:Oe(n.storageKey,n.personalisation),g=()=>n.campaign?.()??null,c=new Map,i=()=>window[et]?.size>0,r=(t,a)=>{for(let d of window[Ht]?.[t]??[])try{d(a)}catch(h){console.warn(`[hp] onsite ${t} listener failed:`,h)}},p=Ye(window),y=n.debug||s.debug===!0||Vt(),b=new Map,S=new Map,I=[];for(let t of Array.isArray(o.forms)?o.forms:[]){let a=Ke(t);a?I.push(a):b.set(String(t?.slot??`form ${b.size+1}`),{slot:String(t?.slot??""),state:"invalid",code:"invalid",reasons:["not a form this SDK can show"]})}let we=()=>Me().catch(t=>(console.warn("[hp] onsite audiences not loaded:",t?.message??t),null));n.personalisation()&&I.some(t=>t.audiences.length>0)&&we().then(t=>t?.prefetch(u));let k=new Map,L=new Map,M=null,K=!1,me=new Set,at=t=>{for(let a of k.keys()){let d=c.get(a);if(!t||!d||d.modal?.())return a}return null},V=null,te=new Set,ne=Number.isInteger(o.overlay_gap_minutes)?o.overlay_gap_minutes:0,lt=()=>{let t=l.coveredAt();if(!(ne>0)||typeof t!="number")return null;let a=Math.max(0,Math.floor((Date.now()-t)/6e4));return a<ne?`a popup showed ${a} min ago; ${ne} min between them`:null},F=new Set,R=new Set,Y=new Map,_=(t,a,d,h=[])=>(b.set(t.slot,{slot:t.slot,format:t.format,trigger:t.trigger.type,priority:t.priority,state:a,code:d,reasons:h}),y&&console.info(`[hp] onsite ${t.slot}: ${a}${h.length?` (${h.join("; ")})`:""}`),{state:a,code:d}),D=(t,a,d,h)=>(k.delete(t.slot),_(t,a,d,h)),$=(t,a,d)=>{let h;return Promise.race([t,new Promise(m=>{h=setTimeout(m,a-Date.now(),d)})]).then(m=>Date.now()>a?d:m).finally(()=>clearTimeout(h))},ct=(t,a)=>{K||i()||(M??(M=t.slot),r("nothing",{slot:t.slot,format:t.format,code:a}))},ye=()=>{try{let t=s.audiences?.();return Array.isArray(t)?t:null}catch{return null}},be=t=>({path:location.pathname,device:p,campaign:g(),facts:pe(),product:n.pageProduct?.(),now:Date.now(),seen:l.seen(t.slot),subscribed:l.subscribed()||s.subscribed?.()===!0,personalisation:n.personalisation(),preview:!!n.preview,audiences:ye()}),z=t=>{S.get(t.slot)?.(),S.delete(t.slot)};function N(t,a,d=!1,h=W(t),m=Date.now()+nt){if(c.has(t.slot))return Promise.resolve({state:"shown",code:"shown",asked:h});let w=L.get(t.slot);return w?(w.asked||(w.asked=h),w.done):(w={asked:h},w.done=ut(t,a,d,h,m).catch(v=>c.has(t.slot)?{state:"shown",code:"shown"}:(console.warn("[hp] onsite form failed:",v?.message??v),D(t,"not shown","error",[`failed: ${v?.message??v}`]))).then(v=>(L.delete(t.slot),{...v,asked:w.asked||w.opened})),L.set(t.slot,w),w.done)}async function ut(t,a,d,h,m){if(i())return _(t,"not shown","suppressed",[`suppressed: ${[...window[et]].join(", ")}`]);let w=ge(t,{...be(t),...d?{seen:tt.seen()}:{},asked:h});if(w.length){if(d&&w.every(f=>Q.includes(f))&&R.add(t),w.length===1&&w[0]===he&&!h&&!d&&!K){let f=t.trigger.type==="inline"||t.format==="inline";z(t);let de=setTimeout(()=>f?N(t,"inline"):oe(t),ze(t,Date.now()));S.set(t.slot,()=>clearTimeout(de))}return _(t,"not eligible","not-eligible",w)}R.delete(t);let v=Xe(t.format)&&!d,O=v&&!h&<();if(O)return _(t,"not shown","overlay-gap",[O]);if(v&&!n.preview&&n.consentAnswered?.()===!1)return Y.set(t,h),_(t,"not shown","awaiting-consent",["waiting for the consent banner"]);let C=fe(t.format),Se=C&&at(h);if(Se)return _(t,"not shown","another-showing",[`${Se} is showing`]);if(C&&M&&!h)return _(t,"not shown","allowance-spent",[`${M} already showed on this page view`]);let G=null;if(!C){try{G=document.querySelector(t.trigger.selector??"")}catch{G=null}if(!G)return _(t,"not shown","no-element",["no element matches its selector"])}C&&k.set(t.slot,t),z(t),_(t,"asking for a decision","deciding",[a]);let ht=ke().catch(f=>(console.warn("[hp] onsite renderer not loaded:",f?.message??f),null)),q=t.visit_context===!0?J().catch(()=>null):null,ie=ye()??[],Ae={claims:[...new Set([...t.audiences,...ie])].filter(f=>ie.includes(f)).slice(0,100)},gt=t.audiences.length>0&&!n.preview&&n.personalisation()?await $(we().then(f=>f?f.visitAudiences(u,n.sessionSignals,t.audiences,ie):Ae),Math.min(m,Date.now()+Xt),Ae):null,j=Date.now()<m?await $(u.decide(t.slot,l.pin(t.slot),{visitAudiences:gt,visitCampaign:t.arrived_from.length?g():null,visitContext:t.visit_context===!0?n.visitContext?.()??null:t.products?{product_id:n.pageProduct?.()}:null,pageFacts:t.page_facts.length?$e(t.page_facts,pe()):null,timeoutMs:m-Date.now()}),m,st):st,re=j.status===200?j.body?.decisions:null,A=Array.isArray(re)?re.find(f=>f?.slot===t.slot):null;A?.experiment&&A.arm&&A.split&&l.pin(t.slot,[A.experiment,A.arm,A.split]);let P=A&&A.holdout!==!0?Ve(A.payload):null,ve=P?.steps[0].blocks??[],Ee=A?.offer?.code??(n.preview?"PREVIEW":l.code()),wt=n.basketValue?.()??null,ae=ve.some(f=>f?.t==="code")&&!Ee&&"no code to remind of"||ve.some(f=>f?.t==="progress")&&!(wt>0)&&"the basket is empty";if(ae){let f=ae==="the basket is empty";return f&&F.add(t),D(t,"not shown",f?"empty-basket":"no-code",[ae])}if(F.delete(t),!P){let f=A?.holdout===!0;return f&&n.analytics()&&e.recordExposure(j.body),C&&f&&(M??(M=t.slot)),f&&!h&&r("held",{slot:t.slot,arm:A.arm??null,format:t.format}),f||Array.isArray(re)?D(t,f?"held out":"no decision",f?"held-out":"no-creative",["no creative for this visitor"]):D(t,"no decision","decision-failed",[`decisions answered ${j.status}`])}let le=await $(ht,m,null);if(!le)return D(t,"not shown","renderer-failed",["the renderer did not load"]);let Te=it(P,f=>f?.t==="products");Te&&(q??(q=J().catch(()=>null)));let mt=$(le.warm?.(t,P,P.steps[0].id,me),Math.min(m,Date.now()+Kt)),[yt,ce]=await Promise.all([!Te||$(q,m,null),it(P,f=>(f?.t==="heading"||f?.t==="text")&&Z(f.text))&&$(Je().catch(()=>null),m,null)]);if(!yt)return D(t,"not shown","products-failed",["its products did not load"]);if(ce===null)return D(t,"not shown","values-failed",["its values did not load"]);if(await mt,i())return D(t,"not shown","suppressed",["suppressed"]);let ue=(f,de={})=>r(f,{slot:t.slot,arm:A.arm??null,format:P.format??t.format,...de}),bt=le.mountForm({form:t,creative:P,decision:A,access:n,client:e,api:u,counters:l,loadWheel:Ze,loadAnswers:xe,loadProducts:()=>q??J(),container:G,warmed:me,coupon:Ee,basket:()=>n.basketValue?.()??null,fill:ce?ce.fillFor(t,n,s.values):void 0,emit:ue,onClose(f){c.delete(t.slot),k.delete(t.slot),_(t,"closed","closed",[f]),ue("closed",{reason:f})}});c.set(t.slot,bt),d||l.shown(t.slot),v&&l.covered(),C&&(M??(M=t.slot)),n.analytics()&&e.recordExposure(j.body);let _t=_(t,"shown","shown",[a]);return ue("shown"),_t}function se(t,a,d=W(t)){if(!fe(t.format))return N(t,a,!1,d);if(!V){let h={forms:[],taken:new Set,deadline:Date.now()+ot+nt};V=h,te.add(h),setTimeout(()=>{V=null,dt(h)},ot)}V.forms.push([t,a,d])}async function dt(t){let a=t.forms.sort(([h],[m])=>Ge(h,m)),d=null;for(let[h,[m,w,v]]of a.entries()){if(t.taken.has(m))continue;let O=await N(m,w,!1,v,t.deadline);if(!d&&Wt.has(O.code)&&!O.asked&&(d=[m,O.code]),O.state==="shown"||O.state==="held out"){for(let[C]of a.slice(h+1))_(C,"not shown","lower-priority",[`${m.slot} has a higher priority`]);d=null;break}}te.delete(t),d&&ct(...d)}for(let t of I){if(t.format==="teaser"&&l.tabOut(t.slot)){N(t,"tab kept from an earlier page",!0);continue}let a=ge(t,{...be(t),later:!0});if(a.length){_(t,"not eligible","not-eligible",a);continue}let d=t.trigger.type;d==="manual"?_(t,"waiting for hp.onsite.open","waiting-for-open"):d==="inline"||t.format==="inline"?N(t,"inline"):oe(t)}function oe(t){z(t),S.set(t.slot,Be(t.trigger,a=>{z(t),se(t,a)},{device:p})),_(t,"armed","armed",[`${t.trigger.type} on ${p}`])}let pt=n.onConsentAnswered?.(()=>{let t=[...Y];Y.clear();for(let[a,d]of t)c.has(a.slot)||(d?se(a,"manual",d):oe(a))}),_e=()=>{let t=[...R];R.clear();for(let a of t)Promise.resolve(L.get(a.slot)?.done).then(()=>K||c.has(a.slot)||N(a,"tab kept from an earlier page",!0))};(window[ee]??(window[ee]=new Set)).add(_e);let ft=n.onBasket?.(()=>{if(!((n.basketValue?.()??0)>0))return;let t=[...F];F.clear();for(let a of t)c.has(a.slot)||se(a,"the basket changed")}),U=Object.freeze({open(t){let a=I.find(w=>w.slot===t),d=a??I.find(w=>w.aliases.includes(t));if(!d)return Promise.resolve(!1);if(c.has(d.slot))return Promise.resolve(!0);for(let w of te)w.taken.add(d);let h=N(d,"manual",!1,W(d)||!a),m=L.get(d.slot);return m&&(m.opened=!0),h.then(({state:w})=>w==="shown")},suppress(){for(let[t,a]of c){a.destroy(),c.delete(t),k.delete(t);let d=I.find(h=>h.slot===t);d&&_(d,"closed","suppressed",["suppressed"])}},debug:()=>[...b.values()].map(t=>({...t,reasons:[...t.reasons]})),stop(){K=!0;for(let t of S.values())t();S.clear(),ft?.(),pt?.(),F.clear(),Y.clear(),R.clear(),window[ee]?.delete(_e),window[X]===U&&delete window[X]}});window[X]=U;for(let{slot:t,resolve:a}of window[jt]?.splice(0)??[])a(U.open(t));return y&&console.table?.(U.debug()),U}window[Symbol.for("@thg-agentic/hyper-personalisation-web.onsite.module")]={startOnsite:rt};})();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@thg-agentic/hyper-personalisation-web",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.34.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",
|
|
@@ -62,7 +62,8 @@
|
|
|
62
62
|
"dist/onsite-wheel.min.js",
|
|
63
63
|
"dist/onsite-products.min.js",
|
|
64
64
|
"dist/onsite-answers.min.js",
|
|
65
|
-
"dist/onsite-audiences.min.js"
|
|
65
|
+
"dist/onsite-audiences.min.js",
|
|
66
|
+
"dist/onsite-values.min.js"
|
|
66
67
|
],
|
|
67
68
|
"sideEffects": false,
|
|
68
69
|
"license": "MIT",
|
package/src/index.js
CHANGED
|
@@ -53,6 +53,7 @@ import { hostConsent, servingHeaders } from './consent.js';
|
|
|
53
53
|
import { createConsentGate } from './consent-gate.js';
|
|
54
54
|
import {
|
|
55
55
|
buildContext,
|
|
56
|
+
currencyCode,
|
|
56
57
|
getCookie,
|
|
57
58
|
localeTag,
|
|
58
59
|
perRequest,
|
|
@@ -69,6 +70,7 @@ import {
|
|
|
69
70
|
import { guardMethods, InvalidEventError } from './guard.js';
|
|
70
71
|
import { emailSha256, sha256Hex } from './hash.js';
|
|
71
72
|
import { IDENTITY_OPTION } from './identity-option.js';
|
|
73
|
+
import { pageSaid } from './onsite-facade.js';
|
|
72
74
|
import { applyPreview } from './preview.js';
|
|
73
75
|
import {
|
|
74
76
|
forgetVisit,
|
|
@@ -76,7 +78,7 @@ import {
|
|
|
76
78
|
recommendationContextFrom,
|
|
77
79
|
} from './recommendation-context.js';
|
|
78
80
|
import { sampledIn } from './sampling.js';
|
|
79
|
-
import { recordSessionEvent } from './session/record.js';
|
|
81
|
+
import { basketItemsOf, recordSessionEvent } from './session/record.js';
|
|
80
82
|
import {
|
|
81
83
|
clearSessionSignals,
|
|
82
84
|
getSessionSignals,
|
|
@@ -541,6 +543,9 @@ export function createAnalytics(options) {
|
|
|
541
543
|
* Noted before the plan, the sample or beforeSend can drop the event.
|
|
542
544
|
*/
|
|
543
545
|
let pageBasket = null;
|
|
546
|
+
/** How many items it holds, when its lines say, and its currency, when it names one. */
|
|
547
|
+
let pageItems = null;
|
|
548
|
+
let pageCurrency = null;
|
|
544
549
|
/** The product this page is about: the last Product Viewed it sent, for an onsite form's products. */
|
|
545
550
|
let pageProduct = null;
|
|
546
551
|
const basketListeners = new Set();
|
|
@@ -552,9 +557,13 @@ export function createAnalytics(options) {
|
|
|
552
557
|
if (partial.type === 'track' && partial.event === 'Product Viewed') {
|
|
553
558
|
const id = partial.properties?.products?.[0]?.product_id;
|
|
554
559
|
pageProduct = typeof id === 'string' && id ? id : pageProduct;
|
|
560
|
+
pageSaid();
|
|
555
561
|
}
|
|
556
562
|
if (partial.type !== 'track' || partial.event !== 'Cart Updated') return;
|
|
557
563
|
const value = partial.properties?.value;
|
|
564
|
+
const lines = partial.properties?.products;
|
|
565
|
+
pageItems = Array.isArray(lines) ? basketItemsOf(lines) : null;
|
|
566
|
+
pageCurrency = currencyCode(partial.properties?.currency);
|
|
558
567
|
pageBasket =
|
|
559
568
|
typeof value === 'number' && Number.isFinite(value) && value >= 0
|
|
560
569
|
? value
|
|
@@ -1254,6 +1263,32 @@ export function createAnalytics(options) {
|
|
|
1254
1263
|
const value = getSessionSignals().basketValue;
|
|
1255
1264
|
return pageBasket ?? (Number.isFinite(value) ? value : null);
|
|
1256
1265
|
},
|
|
1266
|
+
/**
|
|
1267
|
+
* What a form's text may show (ADR 0064, shopper values): the basket's value and items,
|
|
1268
|
+
* as for a basket bar, in the currency of the basket the value came from (else the
|
|
1269
|
+
* client's), and only under personalisation consent the answers kept (else null).
|
|
1270
|
+
* Drawn as text on this page by the values chunk, never sent.
|
|
1271
|
+
*/
|
|
1272
|
+
values: () => {
|
|
1273
|
+
const { basketValue, basketItems, basketCurrency } =
|
|
1274
|
+
getSessionSignals();
|
|
1275
|
+
const onPage = pageBasket !== null;
|
|
1276
|
+
return {
|
|
1277
|
+
basket_value: onPage
|
|
1278
|
+
? pageBasket
|
|
1279
|
+
: Number.isFinite(basketValue)
|
|
1280
|
+
? basketValue
|
|
1281
|
+
: null,
|
|
1282
|
+
basket_items:
|
|
1283
|
+
pageItems ?? (Number.isInteger(basketItems) ? basketItems : null),
|
|
1284
|
+
currency:
|
|
1285
|
+
(onPage ? pageCurrency : currencyCode(basketCurrency)) ??
|
|
1286
|
+
currencyCode(perRequest(cfg.getCurrency, cfg.currency)),
|
|
1287
|
+
answers: personalisationGranted()
|
|
1288
|
+
? readAnswers(cfg.propertyId)
|
|
1289
|
+
: null,
|
|
1290
|
+
};
|
|
1291
|
+
},
|
|
1257
1292
|
/**
|
|
1258
1293
|
* This visit's session signals, kept only under personalisation consent; else null. The
|
|
1259
1294
|
* campaign is the store's as it stands, so one that has lapsed since the last event is gone.
|
|
@@ -1269,6 +1304,8 @@ export function createAnalytics(options) {
|
|
|
1269
1304
|
answers: readAnswers(cfg.propertyId),
|
|
1270
1305
|
};
|
|
1271
1306
|
},
|
|
1307
|
+
/** The product this page is about (its last Product Viewed), for a form limited to products. */
|
|
1308
|
+
pageProduct: () => pageProduct,
|
|
1272
1309
|
/**
|
|
1273
1310
|
* The visit's context for a form that shows products (`visit_context`): the page's type and
|
|
1274
1311
|
* product, and only under personalisation consent the basket's product ids and the visit's
|
package/src/onsite/answers.js
CHANGED
|
@@ -216,14 +216,17 @@ function style(root, make) {
|
|
|
216
216
|
root.append(node);
|
|
217
217
|
}
|
|
218
218
|
|
|
219
|
-
/**
|
|
220
|
-
|
|
219
|
+
/**
|
|
220
|
+
* A countdown block into the renderer's `box`: its label, then its timer, ticked (./countdown.js),
|
|
221
|
+
* a `daily` one to the next of the form's `cutoffs`.
|
|
222
|
+
*/
|
|
223
|
+
export function countdown(box, block, preview, make, cutoffs) {
|
|
221
224
|
style(box.getRootNode(), make);
|
|
222
225
|
if (block.label) box.append(make('p', 'x-md', block.label));
|
|
223
226
|
const timer = make('p', 'tm');
|
|
224
227
|
timer.setAttribute('role', 'timer');
|
|
225
228
|
box.append(timer);
|
|
226
|
-
return tick(box, block, preview);
|
|
229
|
+
return tick(box, block, preview, cutoffs);
|
|
227
230
|
}
|
|
228
231
|
|
|
229
232
|
/**
|
package/src/onsite/api.js
CHANGED
|
@@ -80,8 +80,9 @@ export function createApi(access, options = {}) {
|
|
|
80
80
|
* what the browser knows of the visit: for a form limited to audiences, `visitAudiences`, the
|
|
81
81
|
* session audiences it meets; for a form that names a campaign, `visitCampaign`, the campaign
|
|
82
82
|
* the visit arrived from. The server holds either form back unless its rules hold. For a form
|
|
83
|
-
* that shows products, `visitContext`: the page and the visit its products are filled from
|
|
84
|
-
*
|
|
83
|
+
* that shows products, `visitContext`: the page and the visit its products are filled from; for
|
|
84
|
+
* one limited to products, the page's product. For a form limited by page facts, `pageFacts`:
|
|
85
|
+
* the facts its rules read. Bounded by `timeoutMs`, at most DECISION_TIMEOUT_MS.
|
|
85
86
|
*/
|
|
86
87
|
decide: (
|
|
87
88
|
slot,
|
|
@@ -90,6 +91,7 @@ export function createApi(access, options = {}) {
|
|
|
90
91
|
visitAudiences,
|
|
91
92
|
visitCampaign,
|
|
92
93
|
visitContext,
|
|
94
|
+
pageFacts,
|
|
93
95
|
timeoutMs = DECISION_TIMEOUT_MS,
|
|
94
96
|
} = {},
|
|
95
97
|
) =>
|
|
@@ -121,6 +123,7 @@ export function createApi(access, options = {}) {
|
|
|
121
123
|
}),
|
|
122
124
|
...(visitCampaign ? { visit_campaign: visitCampaign } : {}),
|
|
123
125
|
...(visitContext ? { visit_context: visitContext } : {}),
|
|
126
|
+
...(pageFacts ? { page_facts: pageFacts } : {}),
|
|
124
127
|
},
|
|
125
128
|
}),
|
|
126
129
|
/** The property's audience definitions: the same for everybody, so no consent header. */
|
package/src/onsite/countdown.js
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
/**
|
|
2
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
|
|
4
|
-
* ended no longer hurries anyone;
|
|
5
|
-
*
|
|
6
|
-
*
|
|
3
|
+
* (`ends_at`), one moment for every shopper, and hidden with its label once it has passed, as an
|
|
4
|
+
* offer that has ended no longer hurries anyone; to the form's next daily cut-off (`daily: true`,
|
|
5
|
+
* the moments the settings' `window.daily` lists), moving on to the next as each passes, and hidden
|
|
6
|
+
* while none is ahead; else `minutes` from when it is first shown, such as how long a claimed code is
|
|
7
|
+
* held. A preview shows a deadline not yet set, or passed, or a cut-off with none ahead, at zero. It
|
|
8
|
+
* comes with the answers chunk (./answers.js), loaded when a step shows one.
|
|
7
9
|
*/
|
|
8
10
|
|
|
9
11
|
/**
|
|
@@ -11,23 +13,31 @@
|
|
|
11
13
|
* hidden, and hiding it again once a deadline has passed.
|
|
12
14
|
*
|
|
13
15
|
* @param {HTMLElement} box The block: its label, if any, then its `role=timer` paragraph.
|
|
14
|
-
* @param {{ ends_at?: string, minutes?: number }} block
|
|
16
|
+
* @param {{ ends_at?: string, minutes?: number, daily?: true }} block
|
|
15
17
|
* @param {boolean} preview
|
|
18
|
+
* @param {number[]} [cutoffs] The form's daily cut-offs (`window.daily.next`), which a `daily` block counts to.
|
|
16
19
|
* @returns {() => void} Stops it, for when the step changes.
|
|
17
20
|
*/
|
|
18
|
-
export function countdown(box, block, preview) {
|
|
21
|
+
export function countdown(box, block, preview, cutoffs) {
|
|
19
22
|
const node = box.lastChild;
|
|
20
|
-
|
|
21
|
-
const
|
|
22
|
-
|
|
23
|
-
|
|
23
|
+
// The next cut-off, read again as each passes; none on a form without, so it is hidden.
|
|
24
|
+
const next =
|
|
25
|
+
block.daily && (() => cutoffs?.find?.((t) => t > Date.now()) || 0);
|
|
26
|
+
const deadline = next || 'ends_at' in block;
|
|
27
|
+
let ends = next
|
|
28
|
+
? next()
|
|
29
|
+
: 'ends_at' in block
|
|
30
|
+
? Date.parse(block.ends_at)
|
|
31
|
+
: Date.now() + Math.max(0, Number(block.minutes) || 0) * 60_000;
|
|
24
32
|
const tick = () => {
|
|
33
|
+
if (next && ends <= Date.now()) ends = next();
|
|
25
34
|
const left = Math.max(0, ends - Date.now()) || 0;
|
|
26
35
|
const days = Math.floor(left / 864e5);
|
|
27
36
|
// mm:ss; hh:mm:ss from an hour; and the days before them from a day.
|
|
28
37
|
node.textContent = `${days ? `${days}d ` : ''}${new Date(left).toISOString().slice(left < 36e5 ? 14 : 11, 19)}`;
|
|
29
38
|
box.hidden = !left && deadline && !preview;
|
|
30
|
-
|
|
39
|
+
// It stops at zero, but for a daily cut-off with another still to come.
|
|
40
|
+
if (!left && !(next && ends)) clearInterval(id);
|
|
31
41
|
};
|
|
32
42
|
const id = setInterval(tick, 1000);
|
|
33
43
|
tick();
|