@thg-agentic/hyper-personalisation-web 3.22.2 → 3.23.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.
@@ -0,0 +1,178 @@
1
+ (()=>{async function Me(o,r,s){let c=h=>Array.from(new Uint8Array(h),v=>v.toString(16).padStart(2,"0")).join(""),f=new TextEncoder,x=o.maxnumber??1e6;for(let h=0;h<=x;h+=256){let v=[];for(let z=h;z<h+256&&z<=x;z++)v.push(crypto.subtle.digest("SHA-256",f.encode(o.salt+z)));let u=(await Promise.all(v)).findIndex(z=>c(z)===o.challenge);if(u>=0)return h+u;if(r&&await r(),s?.aborted)return null}return null}var st=()=>globalThis.scheduler?.postTask?.(()=>{},{priority:"user-visible"})??new Promise(o=>setTimeout(o,0)),Te=(o,r)=>Me(o,st,r);function at(o,r){let s=`onmessage=async(e)=>postMessage(await(${Me})(e.data))`,c=URL.createObjectURL(new Blob([s],{type:"text/javascript"}));return new Promise((f,x)=>{let h;try{h=new Worker(c)}catch(u){URL.revokeObjectURL(c),x(u);return}let v=(u,z)=>{h.terminate(),URL.revokeObjectURL(c),u(z)};r.addEventListener("abort",()=>v(f,null),{once:!0}),h.onmessage=u=>v(f,u.data),h.onerror=u=>{u.preventDefault?.(),v(x,u)},h.postMessage({challenge:o.challenge,salt:o.salt,maxnumber:o.maxnumber})})}var lt=o=>o&&o.algorithm==="SHA-256"&&typeof o.challenge=="string"&&typeof o.salt=="string"&&typeof o.signature=="string";async function Ie(o){if(!lt(o)||typeof crypto?.subtle?.digest!="function")return null;let r=Date.now(),s=new AbortController,c,f=new Promise(v=>{c=setTimeout(()=>v(null),2e4)}),x=typeof Worker=="function"&&typeof Blob=="function"?at(o,s.signal).catch(()=>Te(o,s.signal)):Te(o,s.signal),h=await Promise.race([x,f]);return clearTimeout(c),s.abort(),typeof h!="number"?null:btoa(JSON.stringify({algorithm:o.algorithm,challenge:o.challenge,number:h,salt:o.salt,signature:o.signature,took:Date.now()-r}))}function D(o){if(typeof o!="string")return null;try{let r=new URL(o);return r.protocol==="https:"?r.href:null}catch{return null}}function Z(o){if(typeof o!="string")return null;try{let r=new URL(o);return r.protocol==="https:"||r.protocol==="http:"&&r.hostname==="localhost"?r.href:null}catch{return null}}function re(o,r,s,c){if(typeof r=="string"){o.append(s.createTextNode(r));return}if(c>6||r===null)return;if(Array.isArray(r)){for(let v of r)re(o,v,s,c+1);return}if(typeof r!="object")return;let f="b"in r?"b":"i"in r?"i":"a"in r?"a":null;if(!f)return;let x=f==="a"?D(r.href):null,h=f==="a"&&!x?o:s.createElement(f);x&&(h.setAttribute("href",x),h.setAttribute("rel","noopener")),re(h,r[f],s,c+1),h!==o&&o.append(h)}function Oe(o,r=document){let s=r.createDocumentFragment();return re(s,o,r,0),s}var ct=o=>o!==null&&typeof o=="object"&&!Array.isArray(o);function U(o,r,s){if(typeof s=="string"&&s)return s;let c=ct(o?.next?.answers)?o.next.answers:{};for(let[f,x]of Object.entries(c)){let h=f.indexOf("="),v=r[f.slice(0,h)];if(h>0&&v?.includes(f.slice(h+1)))return x}return typeof o?.next?.default=="string"?o.next.default:null}var se={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 Ne(o,r){let s=String(o??"").replace(/[\s.()-]/g,"");s.startsWith("00")&&(s=`+${s.slice(2)}`);let c=se[String(r??"").toUpperCase()];return!s.startsWith("+")&&c&&(s=`+${c}${s.replace(/^0/,"")}`),/^\+[1-9]\d{7,14}$/.test(s)?s:null}var je=o=>/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(o);function ae(o,r,s,c,f){let x=o("select","i");x.setAttribute("aria-label",r);for(let[h,v]of[["",s],...c]){let u=o("option","",v);u.value=h,u.selected=h===f,x.append(u)}return x}var ce={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'},le="cubic-bezier(.16,1,.3,1)",de=`
2
+ :host{all:initial}
3
+ :host([preview]){display:block;position:relative;width:100%;height:100%;overflow:hidden;contain:layout paint}
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}
5
+ .s *,.s ::before,.s ::after{box-sizing:border-box}
6
+ dialog.s:not([open]){display:none}
7
+ dialog::backdrop{background:none}
8
+ [hidden]{display:none!important}
9
+ .b-pill{--br:999px}
10
+ .b-square{--br:0px;--ir:0px}
11
+ .popup,.fullscreen{position:fixed;inset:0;width:100%;height:100%;display:grid;place-items:center;padding:24px;z-index:2147483646}
12
+ .fullscreen{padding:0}
13
+ .mob.popup{padding:12px}
14
+ .ov{display:none;position:absolute;inset:0;background:var(--hp-ov,rgb(10 10 14/.6));animation:hp-fade .3s ease both}
15
+ .popup>.ov,.fullscreen>.ov{display:block}
16
+ .w{position:relative;display:flex;flex-direction:column;width:min(100%,480px);max-height:100%;min-height:0;overflow:auto;overscroll-behavior:contain;background:var(--b);color:var(--t);border-radius:var(--r);box-shadow:0 24px 48px -24px rgb(0 0 0/.35),0 0 0 1px rgb(0 0 0/.05);animation:hp-pop .44s ${le} both}
17
+ .z-sm{width:min(100%,380px)}
18
+ .z-lg{width:min(100%,880px)}
19
+ .z-full,.fullscreen .w{width:100%;height:100%;max-height:none;border-radius:0;box-shadow:none}
20
+ .m{position:relative;flex:none;overflow:hidden;background:color-mix(in srgb,var(--t) 7%,var(--b))}
21
+ .m img,.m video{display:block;width:100%;height:100%;object-fit:cover}
22
+ .t-stack .m{aspect-ratio:var(--ar,16/9);max-height:280px}
23
+ .t-split{flex-direction:row;min-height:min(500px,100%)}
24
+ .t-split.right{flex-direction:row-reverse}
25
+ .t-split .m{flex:0 0 46%}
26
+ .t-split .m>*{position:absolute;inset:0}
27
+ .mob .t-split,.sheet .t-split{flex-direction:column;min-height:0}
28
+ .mob .t-split .m,.sheet .t-split .m{flex:none;height:190px}
29
+ .t-overlay{justify-content:center;min-height:min(520px,100%)}
30
+ .mob .t-overlay{min-height:min(460px,100%)}
31
+ .t-overlay .m{position:absolute;inset:0}
32
+ .t-overlay .m::after{content:"";position:absolute;inset:0;background:linear-gradient(to top,var(--b),color-mix(in srgb,var(--b) 50%,transparent));opacity:var(--sc,.45)}
33
+ .t-overlay .f{position:relative;z-index:1;flex:none;width:min(100%,560px);margin-inline:auto}
34
+ .t-image-only .m{background:none}
35
+ .t-image-only .m img{height:auto;aspect-ratio:var(--ar,auto)}
36
+ .io{display:block;width:100%;padding:0;border:0;background:none;cursor:pointer;color:inherit}
37
+ .f{display:flex;flex-direction:column;gap:14px;padding:44px 40px 36px;flex:1 0 auto;min-width:0}
38
+ .t-split .f{flex:1 1 0;justify-content:center}
39
+ .lk>.f{justify-content:center}
40
+ .z-full .f,.fullscreen .f{justify-content:center;width:min(100%,560px);margin:auto}
41
+ .pd-none{padding:0}
42
+ .pd-sm{padding:24px}
43
+ .pd-lg{padding:60px 56px 52px}
44
+ .mob .pd-md{padding:34px 24px 24px}
45
+ .ta-center .f{text-align:center}
46
+ .a-left{text-align:left}.a-center{text-align:center}.a-right{text-align:right}
47
+ h2{margin:0;font-weight:700;letter-spacing:-.02em;text-wrap:balance}
48
+ h2:focus{outline:none}
49
+ .nm .f>h2:first-child,.t-split:not(.right) .f>h2:first-child{padding-inline-end:36px}
50
+ .nm.ta-center .f>h2:first-child,.nm .f>h2.a-center:first-child{padding-inline:36px}
51
+ p{margin:0;text-wrap:pretty}
52
+ .f>p{color:var(--mu)}
53
+ h2+p{margin-top:-4px}
54
+ .x-xs{font-size:12px;line-height:1.45}
55
+ .x-sm{font-size:14px;line-height:1.5}
56
+ .x-md{font-size:16px;line-height:1.55}
57
+ .x-lg{font-size:20px;line-height:1.35}
58
+ .x-xl{font-size:32px;line-height:1.1}
59
+ .x-display{font-size:54px;line-height:1;letter-spacing:-.035em;font-weight:800}
60
+ .mob .x-xl{font-size:27px}
61
+ .mob .x-display{font-size:40px}
62
+ a{color:inherit;text-underline-offset:3px}
63
+ .l{display:flex;flex-direction:column;gap:6px;font-size:13px;font-weight:600;letter-spacing:.01em;text-align:left}
64
+ .i{font:inherit;font-size:16px;font-weight:400;letter-spacing:0;width:100%;height:52px;padding:0 18px;border:1.5px solid var(--ln);border-radius:var(--ir);background:var(--fl);color:var(--ft);caret-color:var(--a);outline:none}
65
+ .ph{display:flex;gap:8px}.ph .cc{flex:0 0 auto;width:auto;padding:0 10px}
66
+ .i::placeholder{color:color-mix(in srgb,var(--ft) 72%,var(--fl))}
67
+ ::selection{background:color-mix(in srgb,var(--a) 30%,var(--b))}
68
+ .i:focus{border-color:var(--a);box-shadow:0 0 0 4px color-mix(in srgb,var(--a) 22%,transparent)}
69
+ .i[aria-invalid=true]{border-color:#d93025;box-shadow:0 0 0 4px rgb(217 48 37/.16)}
70
+ .btn{display:inline-flex;align-items:center;justify-content:center;gap:8px;font:inherit;font-size:18.67px;font-weight:700;letter-spacing:.01em;line-height:1.2;min-height:52px;padding:14px 24px;border:1.5px solid var(--a);border-radius:var(--br);background:var(--a);color:var(--oa);cursor:pointer;text-decoration:none;-webkit-tap-highlight-color:transparent;transition:transform .15s,filter .2s}
71
+ .btn:hover{filter:brightness(1.08)}
72
+ .btn:active{transform:scale(.98)}
73
+ .bo .btn{background:transparent;color:var(--a)}
74
+ .btn[disabled]{opacity:.55;cursor:progress;filter:none;transform:none}
75
+ .btn.no{align-self:center;min-height:44px;padding:6px 10px;border:0;background:none;color:var(--mu);font-size:14px;font-weight:500;text-decoration:underline;text-decoration-color:color-mix(in srgb,var(--t) 30%,transparent);text-underline-offset:4px;filter:none}
76
+ .btn.no:hover{color:var(--t)}
77
+ :focus-visible,.ch input:focus-visible+span{outline:2px solid var(--a);outline-offset:3px}
78
+ .x{position:absolute;top:12px;right:12px;z-index:2;display:grid;place-items:center;width:44px;height:44px;padding:0;border:0;border-radius:50%;background:var(--b);box-shadow:0 0 0 1px var(--ln);color:var(--t);cursor:pointer}
79
+ .x::before,.x::after{content:"";grid-area:1/1;width:16px;height:2px;border-radius:2px;background:currentColor;transform:rotate(45deg)}
80
+ .x::after{transform:rotate(-45deg)}
81
+ .c{display:flex;gap:10px;align-items:flex-start;font-size:13px;line-height:1.45;color:var(--mu);text-align:left;cursor:pointer}
82
+ .c input{appearance:none;flex:none;display:grid;place-content:center;width:20px;height:20px;margin:0;border:1.5px solid color-mix(in srgb,var(--t) 50%,var(--b));border-radius:min(var(--r),5px);background:var(--b);cursor:pointer}
83
+ .c input:checked{background:var(--a);border-color:var(--a)}
84
+ .c input:checked::after{content:"";width:10px;height:5px;border:solid var(--ot);border-width:0 0 2px 2px;transform:translateY(-1px) rotate(-45deg)}
85
+ .sm{font-size:12px;line-height:1.5;color:var(--mu)}
86
+ fieldset{display:flex;flex-wrap:wrap;gap:8px;min-width:0;margin:0;padding:0;border:0}
87
+ legend{padding:0;margin-bottom:8px;font-size:13px;font-weight:600}
88
+ .ta-center fieldset{justify-content:center}
89
+ .ch{position:relative;display:inline-flex}
90
+ .ch input{position:absolute;inset:0;margin:0;opacity:0}
91
+ .ch span{display:inline-flex;align-items:center;min-height:44px;padding:10px 18px;border:1.5px solid var(--ln);border-radius:999px;font-size:15px}
92
+ .ch input:checked+span{background:var(--a);border-color:var(--a);color:var(--ot)}
93
+ .ls{flex-direction:column}.ls .c{font-size:15px;color:var(--t)}.ls [type=radio]{border-radius:50%}
94
+ .ph .u{align-self:center;color:var(--mu)}
95
+ .bd{flex-wrap:wrap}.bd .i{min-width:0;padding:0 12px}.bd [name=hp_d]{flex:0 0 5.5em}.bd [name=hp_m]{flex:1 1 8.5em}.bd [name=hp_y]{flex:1 1 8em}
96
+ .e.won{color:var(--t);font-size:18px;font-weight:700;text-align:center}
97
+ .e{color:#d93025;font-size:13px;font-weight:500}
98
+ .e:empty{display:none}
99
+ .k{display:flex;flex-direction:column;align-items:stretch;gap:10px}
100
+ .k:empty{display:none}
101
+ .k output{display:block;padding:16px;border:1.5px dashed var(--a);border-radius:min(var(--r),16px);background:color-mix(in srgb,var(--a) 8%,var(--b));font:700 22px/1.2 Menlo,monospace;letter-spacing:.12em;text-align:center}
102
+ .btn.cp,.btn.b2{background:transparent;border-color:var(--ln);color:var(--t)}
103
+ .pg{display:flex;flex-direction:column;gap:8px}
104
+ .pg p{font-weight:600}
105
+ .tr{height:6px;border-radius:99px;background:color-mix(in srgb,var(--t) 18%,var(--b));overflow:hidden}
106
+ .tr i{display:block;height:100%;border-radius:inherit;background:var(--a);transform:scaleX(0);transform-origin:left;transition:transform .6s ${le}}
107
+ .tm{font-size:40px;line-height:1;font-weight:800;letter-spacing:.02em;font-variant-numeric:tabular-nums;text-align:center}
108
+ .bi{display:block;width:100%;height:auto}
109
+ .bl{display:block;border-radius:var(--br)}
110
+ hr{width:100%;margin:4px 0;border:0;border-top:1px solid var(--ln)}
111
+ .wh{width:min(100%,320px);align-self:center}
112
+ .wh svg{display:block;width:100%;height:auto;filter:drop-shadow(0 16px 24px rgb(0 0 0/.2))}
113
+ .hd{display:none}
114
+ .uc h2{text-transform:uppercase;font-weight:800;letter-spacing:-.01em;line-height:1.02}
115
+ .uc .btn:not(.no),.uc .tb{text-transform:uppercase;letter-spacing:.06em}
116
+ .sheet,.bar,.teaser{position:fixed;inset:auto;z-index:2147483646;display:flex;flex-direction:column}
117
+ .sheet{right:24px;bottom:24px;width:min(400px,calc(100% - 32px));max-height:calc(100% - 48px)}
118
+ .sheet.p-bottom-left{right:auto;left:24px}
119
+ .sheet.p-bottom{right:auto;left:50%;translate:-50% 0}
120
+ .sheet .w,.bar .w{width:100%}
121
+ .mob.sheet{left:0;right:0;bottom:0;translate:none;width:100%;max-height:92%}
122
+ .mob.sheet .w{border-radius:var(--r) var(--r) 0 0;box-shadow:0 -16px 48px -16px rgb(0 0 0/.35);animation-name:hp-up}
123
+ .mob.sheet .hd{display:block;position:absolute;top:0;left:50%;translate:-50% 0;z-index:3;width:96px;height:28px;cursor:grab;touch-action:none}
124
+ .mob.sheet .hd::before{content:"";display:block;width:40px;height:5px;margin:10px auto 0;border-radius:3px;background:color-mix(in srgb,var(--t) 25%,var(--b))}
125
+ .bar{left:0;right:0;bottom:0;width:100%}
126
+ .bar.p-top{bottom:auto;top:0}
127
+ .bar .w{flex-direction:row;border-radius:0;box-shadow:0 -10px 30px -14px rgb(0 0 0/.3);animation-name:hp-up}
128
+ .bar.p-top .w{animation-name:hp-down}
129
+ .bar .m{display:none}
130
+ .bar .f{flex-direction:row;flex-wrap:wrap;align-items:center;justify-content:center;gap:10px 16px;width:min(100%,1200px);margin:auto;padding:14px 68px 14px 24px}
131
+ .bar h2{font-size:18px;padding:0!important}
132
+ .bar .f>p{font-size:15px}
133
+ .bar .l{flex:0 1 300px}
134
+ .bar .lt{position:absolute;width:1px;height:1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap}
135
+ .bar .i,.bar .btn{height:46px;min-height:46px}
136
+ .bar .btn{padding:10px 22px}
137
+ .bar .c,.bar .sm,.bar .e{flex-basis:100%;justify-content:center;text-align:center}
138
+ .bar .pg{flex:0 1 520px;text-align:center}
139
+ .bar .k{flex-direction:row;align-items:center}
140
+ .bar .k output{padding:9px 16px;font-size:16px;border-radius:999px}
141
+ .bar .k .btn{height:44px;min-height:44px;padding:6px 16px;font-size:14px}
142
+ .bar .x{top:50%;right:12px;translate:0 -50%}
143
+ .mob.bar .f{justify-content:flex-start;padding:14px 60px 16px 16px}
144
+ .mob.bar h2,.mob.bar .f>p{flex-basis:100%}
145
+ .mob.bar .l{flex:1 1 160px;min-width:160px}
146
+ .mob.bar .f>.btn:not(.no){flex:1 0 auto}
147
+ .mob.bar .x{top:6px;translate:none}
148
+ .teaser{left:20px;bottom:20px}
149
+ .teaser.p-bottom-right{left:auto;right:20px}
150
+ .teaser.p-left,.teaser.p-right{bottom:auto;top:50%;translate:0 -50%}
151
+ .teaser.p-left{left:0}
152
+ .teaser.p-right{left:auto;right:0}
153
+ .teaser .w{width:auto;overflow:visible;background:none;box-shadow:none;border-radius:0;animation-name:hp-fade}
154
+ .teaser .f{padding:0}
155
+ .teaser .m{overflow:visible}
156
+ .teaser .io img{width:auto;max-width:220px;max-height:220px;border-radius:var(--r);box-shadow:0 16px 40px -12px rgb(0 0 0/.45)}
157
+ .tb{display:inline-flex;align-items:center;gap:10px;padding:15px 24px;border:0;border-radius:var(--br);background:var(--a);color:var(--ot);font:inherit;font-size:15px;font-weight:650;letter-spacing:.01em;cursor:pointer;box-shadow:0 14px 34px -10px rgb(0 0 0/.45)}
158
+ .b-rounded .tb{border-radius:999px}
159
+ .p-left .tb,.p-right .tb{writing-mode:vertical-rl;padding:22px 13px;border-radius:var(--br) 0 0 var(--br)}
160
+ .p-left .tb{transform:rotate(180deg)}
161
+ .b-pill.teaser .tb{border-radius:999px}
162
+ .teaser .x{top:-20px;right:-20px;border:8px solid transparent;background:var(--t) padding-box;color:var(--b)}
163
+ .teaser.p-right .x{right:auto;left:-20px}
164
+ .inline{position:static;display:block;height:100%}
165
+ .inline .w{width:100%;height:100%;box-shadow:none;border:1px solid var(--ln);animation:none}
166
+ .inline .t-stack .m{max-height:none}
167
+ .out .w{animation:hp-out .2s ease-in both}
168
+ .out .ov{animation:hp-fade .2s ease-in reverse both}
169
+ .f>*{animation:hp-rise .5s ${le}}
170
+ .pv .w,.pv .ov,.pv .f>*,.inline .f>*{animation:none}
171
+ @keyframes hp-pop{from{opacity:0;transform:translateY(24px) scale(.96)}}
172
+ @keyframes hp-fade{from{opacity:0}}
173
+ @keyframes hp-rise{from{opacity:0;transform:translateY(10px)}}
174
+ @keyframes hp-up{from{transform:translateY(100%)}}
175
+ @keyframes hp-down{from{transform:translateY(-100%)}}
176
+ @keyframes hp-out{to{opacity:0;transform:translateY(12px) scale(.98)}}
177
+ @media (prefers-reduced-motion:reduce){.s .w,.s .ov,.f>*{animation:hp-fade .15s ease both!important}.btn{transition:none}}
178
+ `;var dt=/^#(?:[0-9a-f]{3}){1,2}$/i,Pe=["popup","fullscreen"],pt=["ok","verify","already"],ut=["stack","split","overlay","image-only"],qe={bar:["bottom","top"],sheet:["bottom-right","bottom-left","bottom"],teaser:["bottom-left","bottom-right","left","right"]},ft=["xs","sm","md","lg","xl","display"],Re={xs:4,sm:8,md:16,lg:28,xl:44},De={sm:380,md:480,lg:880},mt=["left","center","right"],Ue={secondary:" b2",link:" no"},ht=220,bt=[500,1500],xt=1800,$={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.",held:"Your code",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",unavailable:"Not available right now.",won:"You won"},O=o=>o!==null&&typeof o=="object"&&!Array.isArray(o),P=(o,r,s)=>o.includes(r)?r:s,L=(o,r,s)=>Number.isFinite(o)?Math.min(Math.max(o,r),s):null,pe=o=>o.type==="date"||o.type==="number",ue=()=>globalThis.matchMedia?.("(prefers-reduced-motion: reduce)")?.matches===!0;function gt(o){let r=O(o.layout)?o.layout:{},s=O(r.media)?r.media:null,c=P(ut,r.template,"stack"),f=s?.side==="right"?"right":"left";return!s&&O(r.image)&&r.image.side!=="none"&&(s=r.image,r.image.side!=="top"&&(c="split",f=r.image.side==="right"?"right":"left")),(!s||!Z(s.asset))&&(s=null,c="stack"),{template:c,media:s,side:f,scrim:L(r.scrim,0,.9)??.45,padding:P(["none","sm","md","lg"],r.padding,"md")}}var yt=0,fe=o=>`hp-${o}-${++yt}`;function p(o,r,s){let c=document.createElement(o);return r&&(c.className=r),s!==void 0&&c.append(Oe(s)),c}var We=o=>{let r=o.length===4?[...o.slice(1)].map(s=>s+s).join(""):o.slice(1);return[0,2,4].map(s=>Number.parseInt(r.slice(s,s+2),16))},Y=o=>{let[r,s,c]=We(o).map(f=>{let x=f/255;return x<=.04045?x/12.92:((x+.055)/1.055)**2.4});return .2126*r+.7152*s+.0722*c},Fe=(o,r=4.5)=>{let s=Y(o)+.05,c=1.05/s;return c>=r?"#fff":s/(Y("#111")+.05)>c?"#111":"#fff"};function vt(o,r){let s=(S,C)=>C&&o.style.setProperty(S,C),c=S=>dt.test(S??"")?S:null;s("--hp-accent",c(r.accent)),s("--hp-bg",c(r.background)),s("--hp-text",c(r.text));let f=L(r.radius,0,48);f!==null&&s("--hp-radius",`${f}px`),s("--hp-font",r.font==="site"?o.ownerDocument.defaultView.getComputedStyle(o.parentElement??o.ownerDocument.body).fontFamily:Object.hasOwn(ce,r.font)?ce[r.font]:null),c(r.accent)&&(s("--hp-on-accent",Fe(r.accent,3)),s("--hp-on-accent-text",Fe(r.accent))),c(r.background)&&Y(r.background)<.18&&(s("--hp-field","#fff"),s("--hp-field-text","#111"));let x=O(r.overlay)?r.overlay:{},h=[c(r.text),c(r.background)].filter(Boolean).sort((S,C)=>Y(S)-Y(C))[0],[v,u,z]=We(c(x.colour)??h??"#0b0b0f");s("--hp-ov",`rgb(${v} ${u} ${z} / ${L(x.opacity,0,1)??.6})`)}function wt(o){try{let r=new CSSStyleSheet;r.replaceSync(de),o.adoptedStyleSheets=[r]}catch{let r=document.createElement("style");r.textContent=de,o.append(r)}}function He(o){let{form:r,creative:s,decision:c,access:f,client:x,api:h,counters:v}=o,u=o.preview??null,z=e=>{let t=e.blocks.find(n=>n?.t==="email"||n?.t==="phone");return t?.t==="phone"||!t&&!r.consent_text?r.sms_consent_text:r.consent_text},S=r.format==="inline"?"inline":s.format&&s.format!=="inline"?s.format:r.format,C=s.theme,me=P(qe[S]??[],C.position,qe[S]?.[0]),N=document.createElement("hp-onsite");u&&N.setAttribute("preview",""),vt(N,C);let B=N.attachShadow({mode:"open"});wt(B);let J=S!=="inline"&&!u,y=p(J?"dialog":S==="inline"?"section":"div"),he=p("div","ov"),A=p("div","w"),j=p("div","m");u&&(j.dataset.hpMedia="");let be=()=>{let e=p("form","f");return e.noValidate=!0,e.addEventListener("submit",ot),e.addEventListener("input",()=>{_.textContent&&w.getAttribute("aria-busy")!=="true"&&T(null)}),e},w=be(),_=p("p","e");_.id=fe("err"),_.setAttribute("aria-live","assertive");let Q=p("div","hd");if(Q.setAttribute("aria-hidden","true"),A.append(Q,j,w),y.append(he,A),S!=="inline"){let e=p("button","x");e.type="button",e.setAttribute("aria-label","Close"),e.addEventListener("click",()=>M("close")),A.append(e),he.addEventListener("click",()=>M("close"))}B.append(y);let i={step:null,mode:S,size:"md",modal:!1,mobile:u?.device==="mobile",answers:{},sent:new Set,receipt:null,claim:o.coupon?{code:o.coupon}:u?{code:"WELCOME15"}:null,claiming:null,owed:!1,submitted:!1,pow:null,wheel:null,timers:[],codes:[],videos:[],closed:!1},G=r.locale||document.documentElement.lang,Ye=r.questions.some(pe)&&o.loadAnswers().catch(()=>null),xe=new WeakMap,ge=()=>{let e=O(C.button)?C.button:{};y.className=`s ${i.mode}${me?` p-${me}`:""} b-${P(["pill","rounded","square"],e.shape,"rounded")}${i.mobile?" mob":""}${u?" pv":""}${e.style==="outline"?" bo":""}${C.caps===!0?" uc":""}`},F=u?null:globalThis.matchMedia?.("(max-width: 639px)"),ye=()=>{i.mobile=F?.matches===!0,A.classList.remove("lk"),A.style.removeProperty("min-width"),A.style.removeProperty("min-height"),ge()};F&&(i.mobile=F.matches===!0,F.addEventListener?.("change",ye));let X=(e,t)=>{u||!c.decision_id||!f.analytics()||x.slotEngaged({decision_id:c.decision_id,slot:c.slot,arm:c.arm??null,engagement:e,step:t??i.step?.id??null})},T=(e,t)=>{_.className="e",_.textContent=e??"";for(let a of w.querySelectorAll("[aria-invalid]"))a.removeAttribute("aria-invalid");let n=t?.closest("label,fieldset");n&&w.contains(n)?n.after(_):w.append(_),t&&(t.setAttribute("aria-invalid","true"),t.setAttribute("aria-describedby",_.id),t.focus(),t.scrollIntoView?.({block:"nearest"}))},W=e=>{w.setAttribute("aria-busy",String(e));for(let t of w.querySelectorAll("button"))t.disabled=e},ve=()=>u?Promise.resolve(null):(i.pow??(i.pow=h.challenge().then(e=>e.status===200?Ie(e.body):null).catch(()=>null)),i.pow),ee=()=>{for(let e of i.videos)try{document.hidden||ue()?e.pause():e.play()?.catch?.(()=>{})}catch{}};document.addEventListener("visibilitychange",ee);let Be=(e=1)=>{if(i.mode==="fullscreen"||i.size==="full")return"100vw";let t=i.mode==="teaser"?220:i.mode==="sheet"?400:De[i.size]??De.md;return`(max-width: 639px) 100vw, ${Math.round(t*e)}px`},Ge=(e,t,n)=>{if(!n||!Array.isArray(e.widths)||!t.endsWith(".webp"))return null;let a=e.widths.filter(l=>Number.isInteger(l)&&l>0&&l<n);return a.length===0?null:[...a.map(l=>`${t.slice(0,-5)}-${l}w.webp ${l}w`),`${t} ${n}w`].join(",")};function we(e,t,n,a){let l=Z(e.asset);if(!l)return null;let m=typeof e.alt=="string"?e.alt:"",d;if(e.kind==="video"||e.t==="video"){d=p("video",t),d.muted=d.defaultMuted=d.loop=d.playsInline=!0;let k=Z(e.poster);k&&(d.poster=k),m?d.setAttribute("aria-label",m):d.setAttribute("aria-hidden","true"),d.autoplay=!ue()&&!u,d.src=l,i.videos.push(d)}else{d=p("img",t),d.alt=m,d.decoding="async",d.loading=n?"eager":"lazy";let k=Ge(e,l,L(e.width,1,8192));k&&(d.sizes=Be(a),d.srcset=k),d.src=l}let b=L(e.width,1,8192),g=L(e.height,1,8192);return b&&g&&(d.width=b,d.height=g),O(e.focal)&&(d.style.objectPosition=`${L(e.focal.x,0,100)??50}% ${L(e.focal.y,0,100)??50}%`),d}function ke(e,t){let n=p("label","l");n.append(p("span","lt",e.label??(t==="email"?"Email":"Mobile number")));let a=p("input","i");if(a.type=t,a.name=t==="email"?"email":"phone",a.autocomplete=a.inputMode=t,a.required=!0,typeof e.placeholder=="string"&&(a.placeholder=e.placeholder),a.setAttribute("aria-describedby",_.id),a.addEventListener("focus",ve,{once:!0}),t!=="tel")return n.append(a),n;a.id=`${_.id}-p`,n.htmlFor=a.id;let l=ae(p,"Country code","+",Object.entries(se).map(([d,b])=>[d,`${d} +${b}`]),(e.country||/-(\w\w)$/.exec(G)?.[1]||"").toUpperCase());l.classList.add("cc"),l.name="hp_cc";let m=p("span","ph");return m.append(l,a),n.append(m),n}function Xe(e){let t=r.questions.find(b=>b.key===e.question);if(!t||!pe(t)&&!Array.isArray(t.options))return null;let n=p("fieldset");n.dataset.question=t.key,n.append(p("legend","",t.label??""));let a=i.answers[t.key]??[];if(pe(t))return Ye.then(b=>{if(!b)return n.append(p("p","sm",$.unavailable));b.answerFields(n,t,p,a[0],G),xe.set(n,()=>b.answerOf(n,t,void 0,G))}),n;let l=t.type==="many",m=P(["list","dropdown"],e.display,"buttons"),d=t.options.filter(b=>O(b)&&typeof b.value=="string");if(m==="dropdown"&&!l)return n.append(ae(p,t.label??t.key,"\u2014",d.map(b=>[b.value,b.label??b.value]),a[0])),n;m!=="buttons"&&(n.className="ls");for(let b of d){let g=p("input");g.value=b.value,g.checked=a.includes(b.value),g.type=l?"checkbox":"radio",g.name=`q_${t.key}`;let k=p("label",m==="buttons"?"ch":"c");k.append(g,p("span","",b.label??b.value)),n.append(k)}return n}function te(){for(let e of i.codes){if(e.replaceChildren(),!i.claim)continue;if(!i.claim.code){e.append(p("p","",i.claim.held?$.claimed:$.code));continue}let t=p("output");t.textContent=i.claim.code;let n=p("button","btn cp");n.type="button",n.textContent="Copy code",n.addEventListener("click",()=>{navigator.clipboard?.writeText(i.claim.code).then(()=>{n.textContent=$.copied}).catch(()=>{})}),e.append(t,n)}}function Ve(e){if(i.claim&&!i.claim.code)return null;let t=p("p","tm");t.setAttribute("role","timer");let n=Date.now()+Math.max(0,Number(e.minutes)||0)*6e4,a=()=>{let m=Math.max(0,Math.round((n-Date.now())/1e3));t.textContent=`${String(Math.floor(m/60)).padStart(2,"0")}:${String(m%60).padStart(2,"0")}`,m===0&&clearInterval(l)},l=setInterval(a,1e3);return i.timers.push(l),a(),t}function ne(e,t){return e.href=t,e.rel="noopener",e.addEventListener("click",n=>{u?n.preventDefault():X("click")}),e}function Ke(e){let t=e.label??"Continue";if(e.action==="link"){let a=D(e.href);return a?ne(p("a",`btn${Ue[e.variant]??""}`,t),a):null}let n=p("button",`btn${Ue[e.variant]??""}`,t);return n.type=e.action==="submit"?"submit":"button",n.type==="button"?n.addEventListener("click",()=>K(e)):n.dataset.submit="",n}let Ae=(e,t,n)=>(e.classList.add(`x-${P(ft,t.size,n)}`),mt.includes(t.align)&&e.classList.add(`a-${t.align}`),e);function Se(e){let t=we(e,"bi",!1);if(!t)return null;t.style.objectFit=e.fit==="contain"?"contain":"cover";let n=L(e.radius,0,48);n!==null&&(t.style.borderRadius=`${n}px`);let a=L(e.max_height,40,800);if(a!==null&&(t.style.maxHeight=`${a}px`),!t.width&&e.fit!=="contain"&&(t.style.aspectRatio="16 / 9"),e.t==="video"||!D(e.href))return t;let l=ne(p("a","bl"),D(e.href));return l.append(t),l}function Ze(e){let t=L(e.threshold,.01,1e7);if(!t)return null;let n=p("div","pg"),a=p("p"),l=p("div","tr"),m=p("i");l.append(m),l.setAttribute("role","progressbar"),l.setAttribute("aria-valuemin","0"),l.setAttribute("aria-valuemax",String(t)),n.append(a,l);let d=g=>g.toFixed(2);try{let g=new Intl.NumberFormat(G||void 0,{style:"currency",currency:e.currency});d=k=>g.format(k)}catch{}let b=()=>{let g=Math.max(0,Number(o.basket?.())||0),k=t-g;a.textContent=k>0?String(e.text??"").replace("{amount}",d(k)):e.done??"",m.style.transform=`scaleX(${Math.min(1,g/t)})`,l.setAttribute("aria-valuenow",String(Math.min(g,t))),a.id||(a.id=fe("pg")),l.setAttribute("aria-labelledby",a.id)};return b(),i.timers.push(setInterval(b,2e3)),n}let Ee={heading(e){let t=Ae(p("h2","",e.text),e,"xl");return t.id=fe("h"),t.tabIndex=-1,y.hasAttribute("aria-labelledby")||(y.setAttribute("aria-labelledby",t.id),i.step===s.steps[0]&&Pe.includes(i.mode)&&!u&&(t.autofocus=!0)),t},text:e=>Ae(p("p","",e.text),e,"md"),email:e=>ke(e,"email"),phone:e=>ke(e,"tel"),consent(e){let t=z(i.step)?.text;if(typeof t!="string")return null;if(e.required!==!0)return p("p","sm",t);let n=p("label","c"),a=p("input");return a.type="checkbox",a.name="hp_consent",a.required=!0,a.setAttribute("aria-describedby",_.id),n.append(a,p("span","",t)),n},question:Xe,wheel(){let e=p("div","wh");return o.loadWheel().then(t=>{i.closed||(i.wheel=t.mountWheel(e,r.prizes))}).catch(()=>{}),e},code(){let e=p("div","k");return e.setAttribute("aria-live","polite"),i.codes.push(e),e},button:Ke,decline(e){let t=p("button","btn no",e.label??"No thanks");return t.type="button",t.addEventListener("click",()=>M("decline")),t},countdown:Ve,progress:Ze,image:Se,video:Se,spacer(e){let t=p("div","sp");return t.style.height=`${Re[e.size]??Re.md}px`,t.setAttribute("aria-hidden","true"),t},divider:()=>p("hr")};function Je(e,t){j.replaceChildren();let n=e.media,a=P(["sm","md","lg","full"],C.size,null),l=e.template==="split"||e.template==="overlay"?"lg":"md",m=!n||t&&e.template!=="image-only";if(i.size=a??l,A.className=`w t-${e.template} z-${a??l}${e.side==="right"?" right":""}${C.text_align==="center"?" ta-center":""}${m?" nm":""}`,A.style.setProperty("--sc",String(e.scrim)),w.className=`f pd-${e.padding}`,j.hidden=m,j.hidden)return;let d=we(n,"",!0,e.template==="split"?.46:1);if(!d)return;if(d.width?A.style.setProperty("--ar",`${d.width} / ${d.height}`):A.style.removeProperty("--ar"),e.template!=="image-only"){d.tagName==="IMG"&&e.template==="overlay"&&(d.alt=""),j.append(d);return}let b=D(n.href),g=b?ne(p("a","io"),b):p("button","io");b||(g.type="button",g.addEventListener("click",()=>K({action:"next"}))),g.append(d),j.append(g)}function Qe(e){let t=e.blocks.find(l=>l?.t==="heading"),n=e.blocks.find(l=>l?.t==="button"&&l.action==="next"),a=p("button","tb");return a.textContent=t?p("b","",t.text).textContent:n?.label??"Open",a.type="button",a.addEventListener("click",()=>K(n??{action:"next"})),a}function q(e,t=new Set){let n=s.steps.find(E=>E.id===e);if(!n)return M("done");if(n.kind==="question"&&!u&&!f.analytics()&&!t.has(n.id))return q(U(n,i.answers),t.add(n.id));let a=i.step!==null,l=a&&(B.activeElement||document.activeElement===document.body),m=a&&!u?{mode:i.mode,w:A.offsetWidth,h:A.offsetHeight}:null;i.step=n;for(let E of i.timers.splice(0))clearInterval(E);i.codes=[],i.videos=[],i.wheel=null;let d=S==="teaser"&&n===s.steps[0];if(i.mode=S==="teaser"&&!d?"popup":S,S==="teaser"&&v.tab?.(r.slot,d),ge(),y.removeAttribute("aria-labelledby"),m){let E=be();w.replaceWith(E),w=E}let b=gt(n);if(Je(b,d),m?.mode===i.mode&&m.h>0?(A.classList.add("lk"),A.style.minWidth=`${m.w}px`,A.style.minHeight=`${m.h}px`):(A.style.removeProperty("min-width"),A.style.removeProperty("min-height")),w.replaceChildren(),d&&b.template!=="image-only")w.append(Qe(n));else for(let[E,I]of n.blocks.entries()){let R=O(I)&&Object.hasOwn(Ee,I.t)?Ee[I.t](I):null;R&&(u&&(R.dataset.hpBlock=String(E)),w.append(R))}let g=w.querySelector("[data-submit]"),k=w.querySelector("[name=hp_consent]")?.parentNode;g&&k&&g.before(k),w.hidden=w.childElementCount===0,T(null),te(),y.hasAttribute("aria-labelledby")?y.removeAttribute("aria-label"):y.setAttribute("aria-label",b.media?.alt?.trim?.()||"Sign up"),a&&$e(),ee(),l&&w.querySelector("h2")?.focus()}function $e(){if(!J)return;let e=Pe.includes(i.mode);if(!(y.open&&i.modal===e)){try{y.open&&y.close()}catch{}if(i.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}):N.blur()}else y.setAttribute("open","");!e||typeof y.showModal!="function"?y.setAttribute("role","dialog"):y.removeAttribute("role")}}function et(){for(let e of w.querySelectorAll("fieldset[data-question]")){let t=e.dataset.question,n=xe.get(e)?.()??{};if(n.error)return n;let a=[n.value,...[...e.querySelectorAll("input:checked,select:not([name])")].map(l=>l.value)].filter(Boolean);a.length?i.answers[t]=a:delete i.answers[t]}}function tt(){let e=[];for(let[n,a]of Object.entries(i.answers)){let l=`${n}=${a.join(",")}`;i.sent.has(l)||(i.sent.add(l),e.push({question:n,values:a}))}let t=i.step.id;if(i.signedUp&&e.length)return void h.answers({anonymousId:f.anonymousId(),sessionId:f.sessionId()??void 0,slot:c.slot,arm:c.arm??void 0,decision_id:c.decision_id??void 0,step:t,...i.signedUp,answers:e,context:_e()});if(f.analytics())for(let n of e)x.preferencesStated({...n,source:"onsite",slot:c.slot,arm:c.arm??null,decision_id:c.decision_id??null,step:t})}let _e=()=>({page:{url:f.pageUrl()},locale:f.locale()??void 0,consent:f.consent()}),V=e=>{i.receipt&&!u&&tt(),q(U(i.step,i.answers,e))};async function nt(e){let t=i.step,n=w.querySelector("input[name=email],input[name=phone]");if(!n)return V(e.next);let a=n.name==="email"?"email":"sms",l=w.querySelector("select[name=hp_cc]")?.value,m=a==="email"?je(n.value.trim())?n.value.trim():null:Ne(n.value,l);if(!m)return T(a==="email"?$.email:l?$.phone:$.intl,n);let d=w.querySelector("input[name=hp_consent]");if(d&&!d.checked)return T($.consent,d);T(null),W(!0);let b=await ve();i.pow=null;let g=Object.entries(i.answers).map(([H,oe])=>({question:H,values:oe})),k=a==="sms"?r.sms_consent_text:r.consent_text,E=await h.capture({anonymousId:f.anonymousId(),sessionId:f.sessionId()??void 0,slot:c.slot,arm:c.arm??void 0,decision_id:c.decision_id??void 0,step:t.id,channel:a,[a==="email"?"email":"phone"]:m,...a==="sms"&&i.signedUp,consent_text:k?{id:k.id,version:k.version}:void 0,...g.length?{answers:g}:{},...b?{altcha:b}:{},context:_e()}),I=E.body?.status,R=(E.status===202||E.status===200)&&pt.includes(I);if(i.closed&&!R)return;W(!1);let ie=E.status===400?E.body?.field:null;if(ie==="email"||ie==="phone")return T($[ie],n);if(!R)return T(E.status===429?$.busy:$.failed,n);n.value="";for(let[H,oe]of Object.entries(i.answers))i.sent.add(`${H}=${oe.join(",")}`);i.receipt=typeof E.body.receipt=="string"?E.body.receipt:null,a==="email"&&(i.signedUp={email:m,email_receipt:i.receipt}),i.submitted=!0,v.submitted(r.slot),X("submit",t.id),i.owed=a==="email"&&r.prizes.length>0,i.owed?Ce():o.emit?.("submitted",{coupon:null});let rt=I!=="ok"&&s.steps.some(H=>H.id===I);i.closed||q(rt?I:U(t,i.answers,e.next))}function ze(e){i.owed&&(i.owed=!1,o.emit?.("submitted",{coupon:e?{code:e.code??null,prize:e.prize?.key}:null}))}function Ce(){let e=i.receipt;return i.claiming??(i.claiming=(async()=>{let t;for(let l of[0,...bt])if(l&&await new Promise(m=>setTimeout(m,l)),t=await h.claim({slot:c.slot,decision_id:c.decision_id??void 0,receipt:e}),t.status!==503)break;let n=t.body,a=n?.fallback===!0&&!n.code;return t.status!==200||!(O(n?.prize)||a)?(i.claiming=null,ze(null),null):(i.claim=n,typeof n.code=="string"&&v.code?.(n.code),ze(n),i.closed||te(),n)})()),i.claiming}async function it(e){if(!i.receipt)return T($.spin);W(!0);let t=await Ce();if(i.closed)return;if(!t)return W(!1),T($.failed);let n=t.fallback===!0&&!t.code,a=t.held?-1:r.prizes.findIndex(d=>d.key===t.prize?.key&&d.label===t.prize?.label);if(i.wheel&&a>=0&&!n){if(await i.wheel.spinTo(a),i.closed)return;_.className="e won",_.textContent=`${$.won} ${t.prize.label}`,await new Promise(d=>setTimeout(d,xt))}if(i.closed)return;W(!1);let l=n?"fallback":a<0?"held":null;l&&!s.steps.some(d=>d.id===l)&&s.steps.push({id:l,blocks:[{t:"heading",text:n?$.thanks:$.held},{t:"code"}]});let m=l??U(i.step,i.answers,e.next);m?q(m):te()}function K(e){if(e.action==="close")return M("close");let t=et();return u?V(e.next):t?T(t.error,t.input):e.action==="apply"?(o.emit?.("apply",{coupon:i.claim?.code?{code:i.claim.code}:null}),X("click"),U(i.step,i.answers,e.next)?V(e.next):M("done")):e.action==="submit"?nt(e):e.action==="spin"?it(e):V(e.next)}function ot(e){if(e.preventDefault(),w.getAttribute("aria-busy")==="true")return;let t=i.step.blocks.find(n=>n?.t==="button"&&n.action==="submit");K(t??{action:"next"})}function Le(){i.closed=!0;for(let t of i.timers.splice(0))clearInterval(t);document.removeEventListener("visibilitychange",ee),F?.removeEventListener?.("change",ye);let e=()=>{try{y.open&&y.close()}catch{}N.remove()};if(!J||ue())return e();y.classList.add("out"),setTimeout(e,ht)}function M(e){i.closed||u||(!i.submitted&&e!=="done"&&X("dismiss"),v.closed(r.slot),v.tab?.(r.slot,!1),Le(),o.onClose?.(e))}return y.addEventListener("cancel",e=>{e.preventDefault(),M("esc")}),y.addEventListener("keydown",e=>{e.key==="Escape"&&!i.modal&&S!=="inline"&&M("esc")}),Q.addEventListener("pointerdown",e=>{if(!i.mobile||i.mode!=="sheet")return;let t=e.clientY,n=0,a=m=>{n=Math.max(0,m.clientY-t),A.style.transform=`translateY(${n}px)`},l=()=>{document.removeEventListener("pointermove",a),document.removeEventListener("pointerup",l),A.style.transform="",n>80&&M("close")};document.addEventListener("pointermove",a),document.addEventListener("pointerup",l)}),q(u?.step&&s.steps.some(e=>e.id===u.step)?u.step:s.steps[0].id),(o.container??document.body).append(N),$e(),{close:M,root:B,host:N,show:q,step:()=>i.step?.id??null,destroy:()=>!i.closed&&Le()}}window[Symbol.for("@thg-agentic/hyper-personalisation-web.onsite.render")]={mountForm:He};})();
@@ -0,0 +1 @@
1
+ (()=>{function A(t,s,e=5){let n=360/s;return e*360+(360-(t+.5)*n)}var M="http://www.w3.org/2000/svg",_=4500,$=16,g="var(--hp-accent,#111)",S="var(--hp-on-accent,#fff)",a="var(--hp-bg,#fff)",m="var(--hp-text,#111)";function i(t,s={}){let e=document.createElementNS(M,t);for(let[n,c]of Object.entries(s))e.setAttribute(n,String(c));return e}function u(t,s,e,n=1){return t.style.fill=s,n<1&&(t.style.fillOpacity=String(n)),e&&(t.style.stroke=e),t}var C=()=>globalThis.matchMedia?.("(prefers-reduced-motion: reduce)")?.matches===!0,y=(t,s=1)=>{let e=(t-90)*Math.PI/180;return`${(s*Math.cos(e)).toFixed(4)} ${(s*Math.sin(e)).toFixed(4)}`};function E(t,s){let e=(Array.isArray(s)?s:[]).map(l=>String(l?.label??l?.key??"")),n=e.length;if(n<2)return null;let c=360/n,d=i("svg",{viewBox:"-1.2 -1.2 2.4 2.4",role:"img","aria-label":`Prize wheel: ${e.join(", ")}`}),o=i("g");o.style.transformBox="fill-box",o.style.transformOrigin="50% 50%";let N=[[1,S],[.14,m],[.72,S]];o.append(u(i("circle",{r:1}),a));let x=[];return e.forEach((l,r)=>{let[p,f]=N[n%2===1&&r===n-1?2:r%2];o.append(u(i("path",{d:`M0 0L${y(r*c)}A1 1 0 ${c>180?1:0} 1 ${y((r+1)*c)}Z`,"stroke-width":.012}),g,a,p));let h=(r+.5)*c-90,b=u(i("text",{transform:`rotate(${h}) translate(0.6 0)${h>90&&h<270?" rotate(180)":""}`,"text-anchor":"middle","dominant-baseline":"central","font-size":n>6?.09:.105,"font-weight":700,"aria-hidden":"true"}),f);b.textContent=l.length>$?`${l.slice(0,$-1)}\u2026`:l,o.append(b);for(let T of[r*c,(r+.5)*c]){let[O,w]=y(T,1.075).split(" ");x.push(u(i("circle",{cx:O,cy:w,r:.024}),a))}}),d.append(u(i("circle",{r:1.13}),m),...x,o,u(i("circle",{r:.17,"stroke-width":.035}),a,m),u(i("circle",{r:.065}),g),u(i("path",{d:"M-0.12 -1.2L0.12 -1.2L0 -0.86Z","stroke-width":.03,"stroke-linejoin":"round"}),g,a)),t.append(d),{spinTo(l){let r=C();return o.style.transition=r?"none":`transform ${_}ms cubic-bezier(.15,.7,.1,1)`,o.style.transform=`rotate(${A(l,e.length,r?0:5)}deg)`,r?Promise.resolve():new Promise(p=>{let f=setTimeout(p,_+200);o.addEventListener("transitionend",()=>{clearTimeout(f),p()},{once:!0})})},remove:()=>d.remove()}}window[Symbol.for("@thg-agentic/hyper-personalisation-web.onsite.wheel")]={mountWheel:E};})();
@@ -0,0 +1 @@
1
+ (()=>{function I(e){let s=typeof document>"u"?null:document.currentScript?.src;return s?new URL(e,s).href:null}var D=new Map;function $(e,s){return window[s]?Promise.resolve(window[s]):e?(D.has(s)||D.set(s,new Promise((n,r)=>{let d=document.createElement("script");d.src=e,d.async=!0,d.onload=()=>window[s]?n(window[s]):r(new Error(`${e} did not register`)),d.onerror=()=>r(new Error(`${e} did not load`)),document.head.append(d)}).finally(()=>D.delete(s))),D.get(s)):Promise.reject(new Error("the CDN script\u2019s own URL is unknown"))}var Te=I("onsite-answers.min.js"),J=()=>$(Te,Symbol.for("@thg-agentic/hyper-personalisation-web.onsite.answers"));var Ie="/v1/capture/challenge",$e=e=>typeof e=="string"&&/^\/v1\/[\w/-]+$/.test(e)?e:Ie;function Z(e,s={}){let n=s.fetch??globalThis.fetch?.bind(globalThis),r=s.servingHost??e.servingHost,d=s.gatewayHost??e.gatewayHost;async function o(c,{method:p="GET",body:i,consent:l=!1,timeoutMs:a}={}){if(!n)return{status:0,body:null};try{let h=await n(c,{method:p,credentials:"omit",signal:a&&AbortSignal.timeout?.(a),headers:{accept:"application/json",authorization:`Bearer ${e.writeKey}`,...i?{"content-type":"application/json"}:{},...l?e.headers():{}},...i?{body:JSON.stringify(i)}:{}}),g=null;try{g=await h.json()}catch{}return{status:h.status,body:g}}catch{return{status:0,body:null}}}return{decide:(c,p)=>o(`${r}/v1/decisions`,{method:"POST",consent:!0,body:{slots:[p?{key:c,pin:{experiment:p[0],arm:p[1],split:p[2]}}:c],identifier_value:e.anonymousId()??void 0,session_id:e.sessionId()??void 0,...e.preview?{preview:e.preview}:{}}}),challenge:()=>o(`${d}${$e(s.challenge)}`),capture:c=>o(`${d}/v1/capture`,{method:"POST",body:c}),answers:c=>o(`${d}/v1/capture/answers`,{method:"POST",body:c}),claim:c=>o(`${r}/v1/offers/claim`,{method:"POST",consent:!0,body:c,timeoutMs:8e3})}}function Q(e,s){let n={},r=()=>{try{let o=JSON.parse(e().getItem(s));o&&typeof o=="object"&&(n=o)}catch{}return n};return{read:r,write:o=>{let c=r();o(c),n=c;try{e().setItem(s,JSON.stringify(c))}catch{}}}}function ee(e,s=()=>!0){let n=Q(()=>sessionStorage,e),r=Q(()=>localStorage,e),d=()=>s()?r:n,o=()=>{let i=r.read();(i.sub!==void 0||i.k!==void 0)&&r.write(l=>{delete l.sub,delete l.k})},c=()=>s()?[n.read(),r.read()]:(o(),[n.read()]),p=(i,l)=>{var a;return i.f??(i.f={}),(a=i.f)[l]??(a[l]={}),i.f[l]};return{seen(i){let l=r.read().f?.[i]??{};return{session:n.read().f?.[i]?.n??0,lifetime:l.n??0,closedAt:l.c??null,submitted:l.s===1}},subscribed:()=>c().some(i=>i.sub===1),shown(i){n.write(l=>{let a=p(l,i);a.n=(a.n??0)+1}),r.write(l=>{let a=p(l,i);a.n=(a.n??0)+1})},closed(i,l=Date.now()){r.write(a=>{p(a,i).c=l})},tab(i,l){n.write(a=>{let h=p(a,i);l?h.t=1:delete h.t})},tabOut:i=>n.read().f?.[i]?.t===1,pin(i,l){if(l===void 0)return n.read().f?.[i]?.p??null;n.write(a=>{p(a,i).p=l})},coveredAt:()=>n.read().o??null,covered(i=Date.now()){n.write(l=>{l.o=i})},code(i,l=Date.now()){if(i===void 0){let[a]=c().flatMap(h=>h.k?[h.k]:[]).sort((h,g)=>g.at-h.at);return a&&l-a.at<14*864e5?a.c:null}return d().write(a=>{a.k={c:i,at:l}}),i},submitted(i){r.write(l=>{p(l,i).s=1}),d().write(l=>{l.sub=1})}}}var Oe=I("onsite-render.min.js"),te=()=>$(Oe,Symbol.for("@thg-agentic/hyper-personalisation-web.onsite.render"));var ie=["popup","sheet","bar","teaser","inline","fullscreen"],Ce=["entry","exit","scroll","time","idle","inline","manual"],z=e=>e!=="inline",re=e=>e==="popup"||e==="sheet"||e==="fullscreen",S=e=>e!==null&&typeof e=="object"&&!Array.isArray(e),F=e=>Array.isArray(e)?e.filter(s=>typeof s=="string"):[],ne=e=>Number.isInteger(e)&&e>=0?e:null;function le(e){if(!S(e)||typeof e.slot!="string"||e.slot==="")return null;let s=S(e.trigger)?e.trigger:{};if(!ie.includes(e.format)||!Ce.includes(s.type))return null;let n=S(e.caps)?e.caps:{};return{...e,trigger:s,priority:Number.isFinite(e.priority)?e.priority:0,pages:S(e.pages)?e.pages:{},devices:F(e.devices),audiences:F(e.audiences),caps:{per_session:ne(n.per_session),lifetime:ne(n.lifetime),after_close_days:Number.isFinite(n.after_close_days)?n.after_close_days:null},window:S(e.window)?e.window:{},questions:Array.isArray(e.questions)?e.questions.filter(S):[],prizes:Array.isArray(e.prizes)?e.prizes.filter(S):[]}}var Pe=/^[a-z][a-z0-9_-]{0,31}$/;function ce(e){if(!S(e)||e.v!==1||!Array.isArray(e.steps))return null;let s=e.steps.filter(n=>S(n)&&Pe.test(n.id)&&Array.isArray(n.blocks));return s.length===0?null:{format:ie.includes(e.format)?e.format:null,theme:S(e.theme)?e.theme:{},steps:s}}function se(e,s){let n=String(e).split("*").map(r=>r.replace(/[.+?^${}()|[\]\\]/g,"\\$&")).join(".*");return new RegExp(`^${n}$`,"i").test(s)}function Me(e,s){let n=F(e?.include);return(!n.length||n.some(r=>se(r,s)))&&!F(e?.exclude).some(r=>se(r,s))}function ae(e){return e.matchMedia?.("(hover: none) and (pointer: coarse)")?.matches===!0||e.innerWidth<768?"mobile":"desktop"}var oe=e=>typeof e=="string"?Date.parse(e):Number.NaN;function X(e,s){let n=[];Me(e.pages,s.path)||n.push("page not included"),e.devices.length&&!e.devices.includes(s.device)&&n.push(`not on ${s.device}`);let r=oe(e.window.starts_at),d=oe(e.window.ends_at);if((s.now<r||s.now>=d)&&n.push("outside its dates"),e.audiences.length&&(s.personalisation?s.audiences&&!e.audiences.some(p=>s.audiences.includes(p))&&n.push("not in its audiences"):n.push("audiences need personalisation consent")),s.preview)return n;let{seen:o}=s,{caps:c}=e;return o.submitted&&n.push("already submitted"),e.exclude_subscribed===!0&&s.subscribed&&n.push("already subscribed"),c.per_session!==null&&o.session>=c.per_session&&n.push("per_session cap"),c.lifetime!==null&&o.lifetime>=c.lifetime&&n.push("lifetime cap"),c.after_close_days!==null&&o.closedAt&&s.now-o.closedAt<c.after_close_days*864e5&&n.push("closed recently"),n}var ue=(e,s)=>s.priority-e.priority;var Ne=["mousemove","pointerdown","keydown","scroll","touchstart","wheel"];function Re(){let e=[];return{on:(r,d,o,c={passive:!0})=>{r.addEventListener(d,o,c),e.push(()=>r.removeEventListener(d,o,c))},later:(r,d)=>{let o=setTimeout(r,d);e.push(()=>clearTimeout(o))},stop:()=>{for(let r of e.splice(0))r()}}}var de=(e,s)=>{let n=s.documentElement.scrollHeight||0;return n>0?(e.scrollY+e.innerHeight)/n:0},ke=e=>{let s=e.activeElement;return!!(s&&(/^(INPUT|TEXTAREA|SELECT)$/.test(s.tagName)||s.isContentEditable))};function Le({on:e,later:s},n,r,d,o){let c=!1,p=!1,i=null,l=0;s(()=>{c=!0},r.delay_ms??5e3),e(o,"mousemove",a=>{a.clientY>d.innerHeight*.1&&(p=!0),i!==null&&(l=a.clientY-i),i=a.clientY}),e(o,"mouseout",a=>{c&&p&&!a.relatedTarget&&a.clientY<=0&&l<0&&!ke(o)&&n("exit")})}function De({on:e,later:s},n,r,d,o){let c=!1,p=0,i=d.scrollY,l=Date.now(),a=null,h=null;s(()=>{c=!0},r.delay_ms??5e3),e(d,"scroll",()=>{let g=d.scrollY,E=Date.now();if(p=Math.max(p,de(d,o)),g<i){(!a||E-a.t>300)&&(a={y:i,t:l});let y=a.y-g;c&&p>=.3&&y>=120&&y/Math.max(1,E-a.t)>=.5&&n("exit_scroll")}else a=null;i=g,l=E}),e(o,"visibilitychange",()=>{o.visibilityState==="hidden"?h=Date.now():h!==null&&Date.now()-h>=1e4&&n("return"),o.visibilityState!=="hidden"&&(h=null)})}function pe(e,s,{device:n,win:r=window,doc:d=document}){let o=Re(),c=(e.seconds??30)*1e3;if(e.type==="entry"&&o.later(()=>s("entry"),e.delay_ms??0),e.type==="time"&&o.later(()=>s("time"),c),e.type==="exit"&&(n==="mobile"?De:Le)(o,s,e,r,d),e.type==="scroll"){let p=e.depth??.5;o.on(r,"scroll",()=>de(r,d)>=p&&s("scroll"))}if(e.type==="idle"){let p=null,i=()=>{clearTimeout(p),p=setTimeout(()=>s("idle"),c)};i();for(let l of Ne)o.on(l==="scroll"?r:d,l,i);return o.on(d,"visibilitychange",i),()=>{clearTimeout(p),o.stop()}}return o.stop}var Fe=I("onsite-wheel.min.js"),fe=()=>$(Fe,Symbol.for("@thg-agentic/hyper-personalisation-web.onsite.wheel"));var he=Symbol.for("@thg-agentic/hyper-personalisation-web.onsite-access"),M=Symbol.for("@thg-agentic/hyper-personalisation-web.onsite"),je=Symbol.for("@thg-agentic/hyper-personalisation-web.onsite.pending"),Ue=Symbol.for("@thg-agentic/hyper-personalisation-web.onsite.listeners"),we=Symbol.for("@thg-agentic/hyper-personalisation-web.onsite.suppressed"),ge={seen:()=>({session:0,lifetime:0,closedAt:null,submitted:!1}),subscribed:()=>!1,shown(){},closed(){},submitted(){},tab(){},tabOut:()=>!1,pin:()=>null,coveredAt:()=>null,covered(){},code:()=>null},We=50,Ye=()=>{try{return new URLSearchParams(location.search).get("hp_debug")==="onsite"}catch{return!1}};function me(e,s={}){if(typeof window>"u"||typeof document>"u")return null;if(window[M])return window[M];let n=typeof e?.[he]=="function"?e[he]():null;if(!n)return console.warn("[hp] onsite: startOnsite needs the client bootstrap or createAnalytics made"),null;let r=s.settings??n.settings??{},d=Z(n,{...s,challenge:r.capture?.challenge}),o=n.preview?ge:ee(n.storageKey,n.personalisation),c=new Map,p=()=>window[we]?.size>0,i=(t,u)=>{for(let f of window[Ue]?.[t]??[])try{f(u)}catch(_){console.warn(`[hp] onsite ${t} listener failed:`,_)}},l=ae(window),a=n.debug||s.debug===!0||Ye(),h=new Map,g=new Map,E=[];for(let t of Array.isArray(r.forms)?r.forms:[]){let u=le(t);u?E.push(u):h.set(String(t?.slot??`form ${h.size+1}`),{slot:String(t?.slot??""),state:"invalid",reasons:["not a form this SDK can show"]})}let y=null,N=[],j=Number.isInteger(r.overlay_gap_minutes)?r.overlay_gap_minutes:0,ye=()=>{let t=o.coveredAt();if(!(j>0)||typeof t!="number")return null;let u=Math.max(0,Math.floor((Date.now()-t)/6e4));return u<j?`a popup showed ${u} min ago; ${j} min between them`:null},O=new Set,R=new Set,w=(t,u,f=[])=>(h.set(t.slot,{slot:t.slot,format:t.format,trigger:t.trigger.type,priority:t.priority,state:u,reasons:f}),a&&console.info(`[hp] onsite ${t.slot}: ${u}${f.length?` (${f.join("; ")})`:""}`),u),be=()=>{try{let t=s.audiences?.();return Array.isArray(t)?t:null}catch{return null}},U=t=>({path:location.pathname,device:l,now:Date.now(),seen:o.seen(t.slot),subscribed:o.subscribed()||s.subscribed?.()===!0,personalisation:n.personalisation(),preview:!!n.preview,audiences:be()}),W=t=>{g.get(t.slot)?.(),g.delete(t.slot)};async function C(t,u,f=!1){if(p())return w(t,"not shown",[`suppressed: ${[...window[we]].join(", ")}`]);let _=X(t,f?{...U(t),seen:ge.seen()}:U(t));if(_.length)return w(t,"not eligible",_);let x=re(t.format)&&!f,k=x&&ye();if(k)return w(t,"not shown",[k]);if(x&&!n.preview&&n.consentAnswered?.()===!1)return R.add(t),w(t,"not shown",["waiting for the consent banner"]);let A=z(t.format);if(A&&y)return w(t,"not shown",[`${y} is showing`]);let v=null;if(!A){try{v=document.querySelector(t.trigger.selector??"")}catch{v=null}if(!v)return w(t,"not shown",["no element matches its selector"])}A&&(y=t.slot),W(t),w(t,"asking for a decision",[u]);let Ae=te().catch(b=>(console.warn("[hp] onsite renderer not loaded:",b?.message??b),null)),T=await d.decide(t.slot,o.pin(t.slot)),m=T.status===200?T.body?.decisions?.find(b=>b?.slot===t.slot):null;m?.experiment&&m.arm&&m.split&&o.pin(t.slot,[m.experiment,m.arm,m.split]);let L=m&&m.holdout!==!0?ce(m.payload):null,G=L?.steps[0].blocks??[],V=m?.offer?.code??(n.preview?"PREVIEW":o.code()),Ee=n.basketValue?.()??null,H=G.some(b=>b?.t==="code")&&!V&&"no code to remind of"||G.some(b=>b?.t==="progress")&&!(Ee>0)&&"the basket is empty";if(H)return A&&(y=null),H==="the basket is empty"&&O.add(t),w(t,"not shown",[H]);if(O.delete(t),!L)return m?.holdout===!0&&n.analytics()&&e.recordExposure(T.body),A&&(y=null),w(t,m?.holdout===!0?"held out":"no decision",[T.status===200?"no creative for this visitor":`decisions answered ${T.status}`]);let q=await Ae;if(!q)return A&&(y=null),w(t,"not shown",["the renderer did not load"]);f||o.shown(t.slot),x&&o.covered();let K=(b,ve={})=>i(b,{slot:t.slot,arm:m.arm??null,format:L.format??t.format,...ve}),xe=q.mountForm({form:t,creative:L,decision:m,access:n,client:e,api:d,counters:o,loadWheel:fe,loadAnswers:J,container:v,coupon:V,basket:()=>n.basketValue?.()??null,emit:K,onClose(b){c.delete(t.slot),y===t.slot&&(y=null),w(t,"closed",[b]),K("closed",{reason:b})}});return c.set(t.slot,xe),n.analytics()&&e.recordExposure(T.body),w(t,"shown",[u]),K("shown"),"shown"}function Y(t,u){if(!z(t.format))return C(t,u);N.push([t,u]),!(N.length>1)&&setTimeout(async()=>{let f=N.sort(([_],[x])=>ue(_,x));N=[];for(let[_,[x,k]]of f.entries()){let A=await C(x,k);if(A==="shown"||A==="held out"){for(let[v]of f.slice(_+1))w(v,"not shown",[`${x.slot} has a higher priority`]);return}}},We)}for(let t of E){if(t.format==="teaser"&&o.tabOut(t.slot)){C(t,"tab kept from an earlier page",!0);continue}let u=X(t,U(t));if(u.length){w(t,"not eligible",u);continue}let f=t.trigger.type;f==="manual"?w(t,"waiting for hp.onsite.open"):f==="inline"||t.format==="inline"?C(t,"inline"):B(t)}function B(t){W(t),g.set(t.slot,pe(t.trigger,u=>{W(t),Y(t,u)},{device:l})),w(t,"armed",[`${t.trigger.type} on ${l}`])}let _e=n.onConsentAnswered?.(()=>{let t=[...R];R.clear();for(let u of t)c.has(u.slot)||(u.trigger.type==="manual"?Y(u,"manual"):B(u))}),Se=n.onBasket?.(()=>{if(!((n.basketValue?.()??0)>0))return;let t=[...O];O.clear();for(let u of t)c.has(u.slot)||Y(u,"the basket changed")}),P=Object.freeze({open(t){let u=E.find(f=>f.slot===t);return u&&!c.has(t)?C(u,"manual").then(f=>f==="shown"):Promise.resolve(c.has(t))},suppress(){for(let[t,u]of c){u.destroy(),c.delete(t),y===t&&(y=null);let f=E.find(_=>_.slot===t);f&&w(f,"closed",["suppressed"])}},debug:()=>[...h.values()].map(t=>({...t,reasons:[...t.reasons]})),stop(){for(let t of g.values())t();g.clear(),Se?.(),_e?.(),O.clear(),R.clear(),window[M]===P&&delete window[M]}});window[M]=P;for(let{slot:t,resolve:u}of window[je]?.splice(0)??[])u(P.open(t));return a&&console.table?.(P.debug()),P}window[Symbol.for("@thg-agentic/hyper-personalisation-web.onsite.module")]={startOnsite:me};})();
@@ -1 +1 @@
1
- (()=>{(()=>{let e=window.hp=window.hp||[];if(!(e.initialized||e.invoked)){e.invoked=!0,e.methods=["track","page","identify","reset","flush","productViewed","productListViewed","recommendationsViewed","personalisationExposed","recordExposure","surfaceViewed","productClicked","productListFiltered","productsSearched","searchSuggestionsViewed","productAdded","productRemoved","cartUpdated","identityLinked","slotEngaged","productVariantSelected","cartViewed","productAddedToWishlist","productRemovedFromWishlist","wishlistProductAddedToCart","productShared","cartShared","couponEntered","couponApplied","couponDenied","couponRemoved","checkoutStarted","promotionViewed","promotionClicked","checkoutStepViewed","checkoutStepCompleted","paymentInfoEntered","checkoutFailed","signedIn","signedUp","signedOut","newsletterSubscribed","newsletterUnsubscribed","backInStockSubscribed","productReviewed","consentUpdated"],e.factory=t=>(...o)=>(e.push([t,...o]),e);for(let t of e.methods)e[t]=e.factory(t);e.servingHeaders=()=>({}),e.inHoldout=()=>!0,e.personalisationGroup=()=>"excluded",e.recommendationContext=()=>({}),e.load=(t,o,r)=>{e._config=t,e._options=o||{};let d=document.createElement("script");d.async=!0,d.src=r;let i=document.getElementsByTagName("script")[0];i.parentNode.insertBefore(d,i)},e.SNIPPET_VERSION="1",e.load({writeKey:"hp_pk_live_REPLACE_ME",apiHost:"https://api.example.com"},{consent:{provider:"onetrust"},identityCookies:{sessionId:"session_id"}},"https://cdn.jsdelivr.net/npm/@thg-agentic/hyper-personalisation-web@3/dist/hp.min.js")}})();})();
1
+ (()=>{(()=>{let e=window.hp=window.hp||[];if(!(e.initialized||e.invoked)){e.invoked=!0,e.methods=["track","page","identify","reset","flush","productViewed","productListViewed","recommendationsViewed","personalisationExposed","recordExposure","surfaceViewed","productClicked","productListFiltered","productsSearched","searchSuggestionsViewed","productAdded","productRemoved","cartUpdated","identityLinked","slotEngaged","productVariantSelected","cartViewed","productAddedToWishlist","productRemovedFromWishlist","wishlistProductAddedToCart","productShared","cartShared","couponEntered","couponApplied","couponDenied","couponRemoved","checkoutStarted","promotionViewed","promotionClicked","checkoutStepViewed","checkoutStepCompleted","paymentInfoEntered","checkoutFailed","signedIn","signedUp","signedOut","newsletterSubscribed","newsletterUnsubscribed","preferencesStated","backInStockSubscribed","productReviewed","consentUpdated"],e.factory=t=>(...o)=>(e.push([t,...o]),e);for(let t of e.methods)e[t]=e.factory(t);e.servingHeaders=()=>({}),e.inHoldout=()=>!0,e.personalisationGroup=()=>"excluded",e.recommendationContext=()=>({}),e.load=(t,o,r)=>{e._config=t,e._options=o||{};let d=document.createElement("script");d.async=!0,d.src=r;let i=document.getElementsByTagName("script")[0];i.parentNode.insertBefore(d,i)},e.SNIPPET_VERSION="1",e.load({writeKey:"hp_pk_live_REPLACE_ME",apiHost:"https://api.example.com"},{consent:{provider:"onetrust"},identityCookies:{sessionId:"session_id"}},"https://cdn.jsdelivr.net/npm/@thg-agentic/hyper-personalisation-web@3/dist/hp.min.js")}})();})();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@thg-agentic/hyper-personalisation-web",
3
- "version": "3.22.2",
3
+ "version": "3.23.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",
@@ -36,6 +36,18 @@
36
36
  "types": "./types/auto.d.ts",
37
37
  "default": "./src/auto.js"
38
38
  },
39
+ "./onsite": {
40
+ "types": "./types/onsite.d.ts",
41
+ "default": "./src/onsite/index.js"
42
+ },
43
+ "./onsite/wheel": {
44
+ "types": "./types/onsite-wheel.d.ts",
45
+ "default": "./src/onsite/wheel.js"
46
+ },
47
+ "./onsite/preview": {
48
+ "types": "./types/onsite-preview.d.ts",
49
+ "default": "./src/onsite/preview.js"
50
+ },
39
51
  "./session": "./src/session.js",
40
52
  "./experiments": "./src/experiments.js",
41
53
  "./conformance": "./src/conformance.js"
@@ -44,7 +56,11 @@
44
56
  "src/",
45
57
  "types/**/*.d.ts",
46
58
  "dist/hp.min.js",
47
- "dist/snippet.min.js"
59
+ "dist/snippet.min.js",
60
+ "dist/onsite.min.js",
61
+ "dist/onsite-render.min.js",
62
+ "dist/onsite-wheel.min.js",
63
+ "dist/onsite-answers.min.js"
48
64
  ],
49
65
  "sideEffects": false,
50
66
  "license": "MIT",
@@ -74,7 +90,7 @@
74
90
  "esbuild": "^0.28.2",
75
91
  "jsdom": "^30.1.1",
76
92
  "typescript": "^7.0.2",
77
- "@thg-agentic/hyper-personalisation-spec": "1.16.0"
93
+ "@thg-agentic/hyper-personalisation-spec": "1.18.0"
78
94
  },
79
95
  "scripts": {
80
96
  "test": "node --test tests/*.test.mjs",
package/src/bootstrap.js CHANGED
@@ -44,6 +44,8 @@ import { sessionDebug } from './debug.js';
44
44
  import { guard } from './guard.js';
45
45
  import { IDENTITY_OPTION } from './identity-option.js';
46
46
  import { createAnalytics, normaliseSha256, PAGE_TYPES } from './index.js';
47
+ import { dropPendingOpens, onsite } from './onsite-facade.js';
48
+ import { loadOnsite } from './onsite-loader.js';
47
49
  import {
48
50
  cachedSettings,
49
51
  cacheSettings,
@@ -134,6 +136,12 @@ export function validateConfig(config, options = {}) {
134
136
  problems.push(
135
137
  'autocapture must be false or { promotions, productLists, recommendations }',
136
138
  );
139
+ if (
140
+ options.onsite !== undefined &&
141
+ typeof options.onsite !== 'boolean' &&
142
+ !isObject(options.onsite)
143
+ )
144
+ problems.push('onsite must be true, false or the onsite options');
137
145
  if (
138
146
  options.beforeSend !== undefined &&
139
147
  typeof options.beforeSend !== 'function'
@@ -312,9 +320,24 @@ function startAutocapture(client, autocapture) {
312
320
  };
313
321
  }
314
322
 
323
+ /**
324
+ * Onsite forms, only when the page opted in and the settings have a live one: the runtime is a
325
+ * separate chunk, fetched here and never part of the core.
326
+ */
327
+ function startOnsiteForms(client, opted, settings) {
328
+ if (!opted || !settings.onsite) return dropPendingOpens();
329
+ loadOnsite()
330
+ .then((module) => module.startOnsite(client, opted === true ? {} : opted))
331
+ .catch((err) => {
332
+ dropPendingOpens();
333
+ console.warn('[hp] onsite not started:', err?.message ?? err);
334
+ });
335
+ }
336
+
315
337
  /** This page is off: what `hp` queued on it is dropped rather than carried. */
316
338
  function off(carry) {
317
339
  carry.close();
340
+ dropPendingOpens();
318
341
  return null;
319
342
  }
320
343
 
@@ -351,7 +374,10 @@ async function start(config, options, carry) {
351
374
  });
352
375
 
353
376
  // Unreachable, or left before the answer: what `hp` queued goes to the next page.
354
- if (unreachable) return null;
377
+ if (unreachable) {
378
+ dropPendingOpens();
379
+ return null;
380
+ }
355
381
  if (!settings.enabled) {
356
382
  if (options.debug)
357
383
  console.info(
@@ -379,6 +405,9 @@ async function start(config, options, carry) {
379
405
 
380
406
  const client = createAnalytics({
381
407
  apiHost: eventsHost(config.apiHost, settings.apiHost),
408
+ // Serving reads (decisions, offers) go where the page pointed the SDK, else the HP API.
409
+ servingHost: resolveApiHost(config.apiHost),
410
+ onsite: settings.onsite ?? null,
382
411
  writeKey,
383
412
  propertyId,
384
413
  // Known before the first page view, so an event the client sends while starting (the consent
@@ -486,7 +515,7 @@ async function start(config, options, carry) {
486
515
  const host = typeof window !== 'undefined' ? window : null;
487
516
  // A page restored from the back/forward cache runs no script again, so it would be shown
488
517
  // with no page view and no list impressions. It is a back_forward view like any other.
489
- host?.addEventListener('pageshow', (event) => {
518
+ host?.addEventListener?.('pageshow', (event) => {
490
519
  if (event.persisted) client.page({ navigation_trigger: 'back_forward' });
491
520
  });
492
521
  if (options.dataLayer && host) {
@@ -505,6 +534,8 @@ async function start(config, options, carry) {
505
534
  }
506
535
 
507
536
  if (identified) client.identify(identified, undefined, IDENTITY_OPTION);
537
+ client.onsite = onsite;
538
+ startOnsiteForms(client, options.onsite, settings);
508
539
  return client;
509
540
  } catch (err) {
510
541
  console.warn('[hp] not started:', err?.message ?? err);
package/src/context.js CHANGED
@@ -370,6 +370,25 @@ export function pageContext(cfg) {
370
370
  };
371
371
  }
372
372
 
373
+ let zone;
374
+
375
+ /**
376
+ * The browser's IANA time zone, read once per page. Temporal answers in a fraction of the time: the
377
+ * first DateTimeFormat loads ICU's locale data, about 90 ms of the page's start on a throttled phone.
378
+ */
379
+ function timeZone() {
380
+ if (zone !== undefined) return zone;
381
+ try {
382
+ zone =
383
+ globalThis.Temporal?.Now?.timeZoneId?.() ||
384
+ Intl.DateTimeFormat().resolvedOptions().timeZone ||
385
+ null;
386
+ } catch {
387
+ zone = null;
388
+ }
389
+ return zone;
390
+ }
391
+
373
392
  /**
374
393
  * @param {object} cfg resolved SDK config
375
394
  * @param {object} [overrides] per-call context overrides
@@ -401,13 +420,7 @@ export function buildContext(cfg, overrides = {}) {
401
420
  // The site's locale (which storefront was served), not navigator.language, so it agrees with
402
421
  // the backend's for the same render.
403
422
  locale: localeTag(perRequest(cfg.getLocale, cfg.locale)),
404
- timezone: (() => {
405
- try {
406
- return Intl.DateTimeFormat().resolvedOptions().timeZone;
407
- } catch {
408
- return null;
409
- }
410
- })(),
423
+ timezone: timeZone(),
411
424
  country: countryCode(cfg.country),
412
425
  ship_to_country: countryCode(
413
426
  perRequest(cfg.getShipToCountry, cfg.shipToCountry),
package/src/hp.js CHANGED
@@ -11,6 +11,7 @@
11
11
  * site that never loads the SDK.
12
12
  */
13
13
 
14
+ import { onsite } from './onsite-facade.js';
14
15
  import { keptVisit } from './recommendation-context.js';
15
16
  import { uuid } from './shape.js';
16
17
 
@@ -129,6 +130,7 @@ export const hp = new Proxy(
129
130
  if (typeof method !== 'string' || method === 'then') return undefined;
130
131
  if (method === 'assignmentDecisionId') return assignmentDecisionId;
131
132
  if (method === 'recommendationContext') return recommendationContext;
133
+ if (method === 'onsite') return onsite;
132
134
  return (...args) => call(method, args);
133
135
  },
134
136
  },
package/src/index.js CHANGED
@@ -45,7 +45,13 @@
45
45
  import { assignmentSession, surfaceExposureToken } from './assignment.js';
46
46
  import { hostConsent, servingHeaders } from './consent.js';
47
47
  import { createConsentGate } from './consent-gate.js';
48
- import { buildContext, getCookie, perRequest, scrubHref } from './context.js';
48
+ import {
49
+ buildContext,
50
+ getCookie,
51
+ localeTag,
52
+ perRequest,
53
+ scrubHref,
54
+ } from './context.js';
49
55
  import { createDecisionMemory, servedDecisions } from './decisions.js';
50
56
  import { createHeldStore, deviceIdFrom } from './device-storage.js';
51
57
  import {
@@ -109,6 +115,10 @@ export { emailSha256, getCookie };
109
115
 
110
116
  /** How a call made before the SDK started is replayed with the messageId and time it was made at. */
111
117
  const REPLAY = Symbol.for('@thg-agentic/hyper-personalisation-web.replay');
118
+ /** How ./onsite reads what it needs from a client it was handed. Not public API. */
119
+ const ONSITE_ACCESS = Symbol.for(
120
+ '@thg-agentic/hyper-personalisation-web.onsite-access',
121
+ );
112
122
 
113
123
  /** SHA-256 of a string as lowercase hex. Synchronous since 3.9 (sha256Hex); kept async for callers. */
114
124
  export async function sha256(value) {
@@ -426,8 +436,34 @@ export function createAnalytics(options) {
426
436
  /** The call being replayed: its first event keeps the messageId and time it was made with. */
427
437
  let replaying = null;
428
438
 
439
+ /**
440
+ * The basket this page last reported, in memory only: what a basket bar on this page shows,
441
+ * whatever the consent, since it is the shopper's own basket on screen and nothing is kept.
442
+ * Noted before the plan, the sample or beforeSend can drop the event.
443
+ */
444
+ let pageBasket = null;
445
+ const basketListeners = new Set();
446
+ /** Told once the consent banner is answered, granted or denied (./onsite). */
447
+ const consentListeners = new Set();
448
+
449
+ function noteBasket(partial) {
450
+ if (partial.type !== 'track' || partial.event !== 'Cart Updated') return;
451
+ const value = partial.properties?.value;
452
+ pageBasket =
453
+ typeof value === 'number' && Number.isFinite(value) && value >= 0
454
+ ? value
455
+ : null;
456
+ for (const listener of basketListeners)
457
+ try {
458
+ listener();
459
+ } catch (err) {
460
+ console.warn('[hp] a basket listener failed', err);
461
+ }
462
+ }
463
+
429
464
  /** Tracking never throws into the host: an event that fails to build or deliver is dropped. */
430
465
  function emit(partial, ctxOverrides, force = false) {
466
+ noteBasket(partial);
431
467
  try {
432
468
  return compose(partial, ctxOverrides, force);
433
469
  } catch (err) {
@@ -650,6 +686,13 @@ export function createAnalytics(options) {
650
686
  } catch (err) {
651
687
  console.warn('[hp] onConsentStatus observer failed', err);
652
688
  }
689
+ if (status === 'granted' || status === 'denied')
690
+ for (const listener of consentListeners)
691
+ try {
692
+ listener();
693
+ } catch (err) {
694
+ console.warn('[hp] a consent listener failed', err);
695
+ }
653
696
  },
654
697
  announce({ action, state, previous, withdrawal }) {
655
698
  // Withdrawn here, not only when the next event reaches recordVisit: a beforeSend that drops
@@ -967,6 +1010,11 @@ export function createAnalytics(options) {
967
1010
  newsletterSubscribed: (p, c) => track('Newsletter Subscribed', p, c),
968
1011
  /** An on-site opt-out. The ESP reports its own as Email Unsubscribed. */
969
1012
  newsletterUnsubscribed: (p, c) => track('Newsletter Unsubscribed', p, c),
1013
+ /**
1014
+ * Answers to an approved preference question, given in the account area, a quiz or an onsite
1015
+ * step after the sign-up. Answers sent with an onsite sign-up are the gateway's to report.
1016
+ */
1017
+ preferencesStated: (p, c) => track('Preferences Stated', p, c),
970
1018
  /** An alert request for one product: back in stock, a price drop or a launch. */
971
1019
  backInStockSubscribed: (p, c) => track('Back In Stock Subscribed', p, c),
972
1020
  productReviewed: (p, c) => track('Product Reviewed', p, c),
@@ -1003,6 +1051,53 @@ export function createAnalytics(options) {
1003
1051
  get anonymousId() {
1004
1052
  return realId(perRequest(cfg.getAnonymousId, null));
1005
1053
  },
1054
+ /** What ./onsite needs from this client: hosts, ids, consent and settings. Not public API. */
1055
+ [ONSITE_ACCESS]() {
1056
+ return {
1057
+ writeKey: cfg.writeKey,
1058
+ storageKey: storageKey(storageName('onsite'), cfg.propertyId),
1059
+ gatewayHost: cfg.apiHost,
1060
+ servingHost: cfg.servingHost ?? cfg.apiHost,
1061
+ settings: cfg.onsite ?? null,
1062
+ debug: cfg.debug === true,
1063
+ preview: previewing,
1064
+ anonymousId: () => realId(perRequest(cfg.getAnonymousId, null)),
1065
+ sessionId: () => realId(perRequest(cfg.getSessionId, null)),
1066
+ analytics: granted,
1067
+ personalisation: personalisationGranted,
1068
+ consent: () => cfg.getConsent(),
1069
+ headers: () => servingHeaders(gate?.state ?? null),
1070
+ pageUrl: () =>
1071
+ typeof location === 'undefined'
1072
+ ? null
1073
+ : scrubHref(location.href, cfg),
1074
+ locale: () => localeTag(perRequest(cfg.getLocale, cfg.locale)),
1075
+ /**
1076
+ * A basket bar's progress: the basket this page reported, else the last one this visit
1077
+ * kept (under personalisation consent), else null.
1078
+ */
1079
+ basketValue: () => {
1080
+ const value = getSessionSignals().basketValue;
1081
+ return pageBasket ?? (Number.isFinite(value) ? value : null);
1082
+ },
1083
+ /** Calls `listener` whenever the page reports its basket; answers how to stop. */
1084
+ onBasket: (listener) => {
1085
+ basketListeners.add(listener);
1086
+ return () => basketListeners.delete(listener);
1087
+ },
1088
+ /**
1089
+ * Whether the consent banner is answered. Without a consent adapter there is no banner to
1090
+ * wait for, so it is.
1091
+ */
1092
+ consentAnswered: () =>
1093
+ !gate || gate.status === 'granted' || gate.status === 'denied',
1094
+ /** Calls `listener` once the banner is answered; answers how to stop. */
1095
+ onConsentAnswered: (listener) => {
1096
+ consentListeners.add(listener);
1097
+ return () => consentListeners.delete(listener);
1098
+ },
1099
+ };
1100
+ },
1006
1101
  /** `hp` and bootstrap replay a call made before the start through this. Not public API. */
1007
1102
  [REPLAY](method, args, made) {
1008
1103
  if (typeof this[method] !== 'function') return;