<!-- 2026-09-23T11:44:35.2699618Z -->
<style>.shoplift-hide { opacity: 0 !important; }</style>
<style id="sl-preview-bar-hide">#preview-bar-iframe, #PBarNextFrameWrapper { display: none !important; }</style>
<script type="text/javascript">(function(rootPath, template, themeRole, themeId, isThemePreview){ /* Generated on 2026-10-23T03:45:02.2830198Z */(function(){"use strict";var se=document.createElement("style");se.textContent=`#shoplift-preview-control{position:fixed;max-width:332px;height:56px;background-color:#141414;z-index:9999;bottom:20px;display:flex;border-radius:8px;box-shadow:13px 22px 7px #0000,9px 14px 7px #00000003,5px 8px 6px #0000000d,2px 4px 4px #00000017,1px 1px 2px #0000001a,0 0 #0000001a;align-items:center;margin:0 auto;left:16px;right:16px;opacity:0;transform:translateY(20px);visibility:hidden;transition:opacity .4s ease-in-out,transform .4s ease-in-out,visibility 0s .4s}#shoplift-preview-control.visible{opacity:1;transform:translateY(0);visibility:visible;transition:opacity .4s ease-in-out,transform .4s ease-in-out,visibility 0s 0s}#shoplift-preview-control *{font-family:Inter,sans-serif;color:#fff;box-sizing:border-box;font-size:16px}#shoplift-preview-variant-title{font-weight:400;line-height:140%;font-size:16px;text-align:start;letter-spacing:-.16px;flex-grow:1;text-wrap:nowrap;overflow:hidden;text-overflow:ellipsis}#shoplift-preview-variant-selector{position:relative;display:block;padding:6px 0;height:100%;min-width:0;flex:1 1 auto}#shoplift-preview-variant-menu-trigger{border:none;cursor:pointer;width:100%;background-color:transparent;padding:0 16px;border-left:1px solid #333;border-right:1px solid #333;height:100%;display:flex;align-items:center;justify-content:start;gap:8px}#shoplift-preview-variant-selector .menu-variant-label{width:24px;height:24px;border-radius:50%;padding:6px;display:flex;justify-content:center;align-items:center;font-size:12px;font-style:normal;font-weight:600;line-height:100%;letter-spacing:-.12px;flex-shrink:0}#shoplift-preview-variant-selector .preview-variant-menu{position:absolute;bottom:110%;transform:translate3d(0,20px,0);visibility:hidden;pointer-events:none;opacity:0;cursor:pointer;background-color:#141414;border:1px solid #141414;border-radius:6px;width:100%;max-height:156px;overflow-y:auto;box-shadow:0 8px 16px #0003;z-index:1;transition:opacity .3s ease-in-out,transform .3s ease-in-out,visibility 0s .3s}#shoplift-preview-variant-selector .preview-variant-menu.preview-variant-menu__visible{visibility:visible;pointer-events:auto;opacity:100;transform:translateZ(0);transition:opacity .3s ease-in-out,transform .3s ease-in-out,visibility 0s 0s}@media screen and (max-width:400px){#shoplift-preview-variant-selector .preview-variant-menu{position:fixed;left:0;right:0;width:auto;bottom:110%}}#shoplift-preview-variant-selector .preview-variant-menu .preview-variant-menu--item{padding:12px 16px;display:flex;overflow:hidden}#shoplift-preview-variant-selector .preview-variant-menu .preview-variant-menu--item .menu-variant-label{margin-right:6px}#shoplift-preview-variant-selector .preview-variant-menu .preview-variant-menu--item span{overflow:hidden;text-overflow:ellipsis;text-wrap:nowrap;white-space:nowrap;color:#f6f6f6;font-size:14px;font-style:normal;font-weight:500}#shoplift-preview-variant-selector .preview-variant-menu .preview-variant-menu--item:hover{background-color:#545454}#shoplift-preview-variant-selector .preview-variant-menu .preview-variant-menu--item:last-of-type{border-bottom-left-radius:6px;border-bottom-right-radius:6px}#shoplift-preview-variant-selector .preview-variant-menu .preview-variant-menu--item:first-of-type{border-top-left-radius:6px;border-top-right-radius:6px}#shoplift-preview-control div:has(#shoplift-exit-preview-button){padding:0 16px}#shoplift-exit-preview-button{padding:6px 8px;font-weight:500;line-height:75%;border-radius:4px;background-color:transparent;border:none;text-decoration:none}#shoplift-exit-preview-button:hover{cursor:pointer;background-color:#333}#shoplift-preview-subscription-warning{position:relative;display:flex;align-items:center;gap:6px;padding:6px 10px;margin:0 4px;border-left:1px solid #333;cursor:help;outline:none}#shoplift-preview-subscription-warning__icon{display:inline-flex;align-items:center;justify-content:center;width:18px;height:18px;border-radius:50%;background-color:#f59e0b;color:#141414!important;font-weight:700;font-size:12px!important;line-height:1;flex-shrink:0}#shoplift-preview-subscription-warning__label{font-size:13px!important;font-weight:500;color:#fbbf24!important;text-wrap:nowrap;white-space:nowrap}#shoplift-preview-subscription-warning__tooltip{position:absolute;bottom:calc(100% + 8px);right:0;max-width:320px;width:max-content;padding:10px 12px;border-radius:6px;background-color:#1f1f1f;color:#fff!important;font-size:12px!important;line-height:1.4!important;box-shadow:0 8px 16px #0000004d;z-index:10000;opacity:0;visibility:hidden;transform:translateY(4px);transition:opacity .2s ease-in-out,transform .2s ease-in-out,visibility 0s .2s;pointer-events:none}#shoplift-preview-subscription-warning__tooltip.shoplift-preview-subscription-warning__tooltip--visible{opacity:1;visibility:visible;transform:translateY(0);transition:opacity .2s ease-in-out,transform .2s ease-in-out,visibility 0s 0s}#shoplift-preview-subscription-warning:focus-visible{box-shadow:inset 0 0 0 2px #f59e0b;border-radius:4px}#shoplift-preview-control:has(#shoplift-preview-subscription-warning){max-width:480px}/*$vite$:1*/`,document.head.appendChild(se);var ge=" daum[ /]| deusu/|(?:^|[^g])news(?!sapphire)|(?<! channel/|google/)google(?!(?:wv|app|/google| pixel))|(?<! cu)bots?(?:\\b|_)|(?<!cam)scan|(?<!lib)http|24x7|;\\s\\w+;$|@[a-z][\\w-]+\\.|\\(\\)|\\.com\\b|\\b\\w+/1\\.0;|\\bbw/|\\bdlc\\b|\\bort/|\\bperl\\b|\\btime/|\\||^[<\\(;]|^[\\w \\.\\-\\(?:\\):%]+(?:/v?\\d+(?:\\.\\d+)?(?:\\.\\d{1,10})*?)?(?:,|$)|^[\\w\\-]+/[\\w]+$|^[^ ]{50,}$|^\\d+\\b|^\\w*search\\b|^\\w+/[\\w\\(\\)]*$|^\\w+/\\d\\.\\d\\s\\([\\w@]+\\)$|^active|^ad muncher|^amaya|^apache/|^avsdevicesdk/|^azure|^biglotron|^blackbox exporter|^bot|^clamav[ /]|^claude-code/|^client/|^cobweb/|^custom|^ddg[_-]android|^discourse|^dispatch/\\d|^downcast/|^duckduckgo|^email|^exodusmovement|^facebook|^getright/|^gozilla/|^hobbit|^hotzonu|^hwcdn/|^igetter/|^jeode/|^jetty/|^jigsaw|^microsoft bits|^movabletype|^mozilla/\\d\\.\\d\\s[\\w\\.-]+$|^mozilla/\\d\\.\\d\\s\\((?:compatible;)?(?:\\s?[\\w\\d-.]+\\/\\d+\\.\\d+)?\\)$|^navermailapp|^netsurf|^offline|^openai/|^owler|^php|^postman|^ps_daily/|^python|^rank|^read|^reed|^remove\\.bg/|^rest|^rss|^snapchat|^sora |^space bison|^stape/|^svn|^swcd |^taringa|^thumbor/|^track|^w3c|^webbandit/|^webcopier|^wget|^whatsapp|^wordpress|^xenu link sleuth|^yahoo|^yandex|^zdm/\\d|^zoom marketplace/|abuse|advisor|agent\\b|analyzer|archive|ask jeeves/teoma|attracta|audit|bluecoat drtr|browsex|burpcollaborator|capture|catch|check\\b|checker|chrome-lighthouse|chromeframe|classifier|cloudflare|collapsify\\b|convertify|cookiehubverify/|crawl|cursor/|cypress/|dareboost|datanyze|dejaclick|detect|discovery|dmbrowser|download|exaleadcloudview|feed|firephp|foregenix|functionize|grab|hardenize\\b|headless|hotjar|httrack|hubspot marketing grader|ibisbrowser|infrawatch|insight|inspect|iplabel|java(?!;)|library|linkcheck|linktiger|mail\\.ru/|manager|manus-user/|marketgoo/|measure|monitor\\b|neustar wpm|node\\b|nutch|offbyone|openvas|optimize|pageburst|pagespeed|parser|phantomjs|pingdom|playwright|powermarks|preview|productfinder|prospectingstudio|proxy|ptst[ /]\\d|radar|readable/|retriever|rexx;|rigor|rss\\b|scrape|securityheaders|selenium|server|silktide|sindup/|sogou|sparkler/|speedcurve|spider|splash|statuscake|supercleaner|synapse|synthetic|testlocally|tools|torrent|transcoder|url|validator|virtuoso|wappalyzer|watchtowr|webglance|webkit2png|whatcms/|xtate/",me=/bot|crawl|http|lighthouse|scan|search|spider/i,z;function ye(){if(z instanceof RegExp)return z;try{z=new RegExp(ge,"i")}catch{z=me}return z}var ve=a=>typeof a=="string"&&a!=="";function we(a){return ve(a)&&ye().test(a)}var be=we;class ee{timestamp;constructor(){this.timestamp=new Date}}class Se extends ee{type;testId;hypothesisId;constructor(e,t,i){super(),this.type=3,this.testId=e,this.hypothesisId=t,this.timestamp=i}}class Ce extends ee{type;path;constructor(e){super(),this.type=4,this.path=e}}class Te extends ee{type;cart;constructor(e){super(),this.type=5,this.cart=e}}class G extends Error{isBot;constructor(){super(),this.isBot=!0}}function Ie(a,e,t){for(const i of e.selectors){const s=a.querySelectorAll(i.cssSelector);for(let r=0;r<s.length;r++)t(e.testId,e.hypothesisId)}ne(a,e,(i,s,r,n,o)=>o(s,r),t)}function U(a,e,t){for(const i of e.selectors)oe(a,e.testId,e.hypothesisId,i,t??(()=>{}));ne(a,e,oe,t??(()=>{}))}function re(a){return a.urlPatterns.reduce((e,t)=>{switch(t.operator){case"contains":return e+`.*${t}.*`;case"endsWith":return e+`.*${t}`;case"startsWith":return e+`${t}.*`}},"")}function ne(a,e,t,i){new MutationObserver(()=>{for(const r of e.selectors)t(a,e.testId,e.hypothesisId,r,i)}).observe(a.documentElement,{childList:!0,subtree:!0})}function oe(a,e,t,i,s){const r=a.querySelectorAll(i.cssSelector);for(let n=0;n<r.length;n++){let o=r.item(n);if(o instanceof HTMLElement&&o.dataset.shoplift!==""){o.dataset.shoplift="";for(const l of i.actions.sort(De))o=Pe(a,i.cssSelector,o,l)}}return r.length>0&&s?(s(e,t),!0):!1}function Pe(a,e,t,i){switch(i.type){case"innerHtml":t.innerHTML=i.value;break;case"attribute":Ae(t,i.scope,i.value);break;case"css":ke(a,e,i.value);break;case"js":Ee(a,t,i);break;case"copy":return xe(t);case"remove":_e(t);break;case"move":Re(t,parseInt(i.value));break}return t}function Ae(a,e,t){a.setAttribute(e,t)}function ke(a,e,t){const i=a.createElement("style");i.innerHTML=`${e} { ${t} }`,a.getElementsByTagName("head")[0]?.appendChild(i)}function Ee(a,e,t){Function("document","element",`"use strict"; ${t.value}`)(a,e)}function xe(a){const e=a.cloneNode(!0);if(!a.parentNode)throw"Can't copy node outside of DOM";return a.parentNode.insertBefore(e,a.nextSibling),e}function _e(a){a.remove()}function Re(a,e){if(e===0)return;const t=Array.prototype.slice.call(a.parentElement.children).indexOf(a),i=Math.min(Math.max(t+e,0),a.parentElement.children.length-1);a.parentElement.children.item(i).insertAdjacentElement(e>0?"afterend":"beforebegin",a)}function De(a,e){return ae(a)-ae(e)}function ae(a){return a.type==="copy"||a.type==="remove"?0:1}const M={Template:0,UrlRedirect:2,Script:3,Price:5},Ve="data:image/svg+xml,%3csvg%20width='12'%20height='12'%20viewBox='0%200%2012%2012'%20fill='none'%20xmlns='http://www.w3.org/2000/svg'%3e%3cpath%20d='M9.96001%207.90004C9.86501%207.90004%209.77001%207.86504%209.69501%207.79004L6.43501%204.53004C6.19501%204.29004%205.80501%204.29004%205.56501%204.53004L2.30501%207.79004C2.16001%207.93504%201.92001%207.93504%201.77501%207.79004C1.63001%207.64504%201.63001%207.40504%201.77501%207.26004L5.03501%204.00004C5.56501%203.47004%206.43001%203.47004%206.96501%204.00004L10.225%207.26004C10.37%207.40504%2010.37%207.64504%2010.225%207.79004C10.15%207.86004%2010.055%207.90004%209.96001%207.90004Z'%20fill='white'/%3e%3c/svg%3e",Oe="data:image/svg+xml,%3csvg%20width='14'%20height='24'%20viewBox='0%200%2014%2024'%20fill='none'%20xmlns='http://www.w3.org/2000/svg'%3e%3cpath%20d='M12.3976%2014.5255C12.2833%2013.8788%2012.0498%2013.3024%2011.6952%2012.7961C11.3416%2012.2898%2010.9209%2011.8353%2010.4353%2011.4317C9.94868%2011.0291%209.43546%2010.6488%208.89565%2010.292C8.48487%2010.049%208.09577%209.78565%207.72637%209.50402C7.35697%209.2224%207.08016%208.89503%206.89694%208.51987C6.71273%208.14471%206.67826%207.69533%206.79055%207.1697C6.86345%206.83216%206.97476%206.54647%207.12351%206.31162C7.27324%206.07778%207.47124%205.89986%207.7175%205.77684C7.96377%205.65483%208.21989%205.59383%208.48389%205.59383C8.88087%205.59383%209.17639%205.7016%209.3734%205.91714C9.56943%206.13268%209.68271%206.42345%209.71424%206.78946C9.74576%207.15547%209.72015%207.55401%209.63839%207.98509C9.55663%208.41617%209.43645%208.84724%209.27687%209.27934L13.5127%208.80149C13.9638%207.52656%2014.1017%206.42447%2013.9264%205.49725C13.751%204.56901%2013.2664%203.85122%2012.4724%203.34491C12.239%203.19648%2011.9779%203.07041%2011.6893%202.96569L12.0026%201.50979L9.86397%200L7.3875%201.50979L7.11169%202.78878C6.65166%202.8874%206.21724%203.01957%205.8114%203.19038C4.85292%203.594%204.06684%204.15115%203.45117%204.86385C2.83452%205.57655%202.42571%206.40108%202.22378%207.33847C2.06616%208.06947%202.04942%208.70796%202.17551%209.25087C2.30061%209.7948%202.52028%2010.2828%202.8355%2010.7139C3.14974%2011.145%203.51816%2011.5344%203.93977%2011.881C4.36039%2012.2288%204.782%2012.5521%205.20164%2012.851C5.68334%2013.1702%206.13844%2013.5169%206.56497%2013.8921C6.99052%2014.2672%207.31954%2014.7125%207.55004%2015.228C7.78055%2015.7445%207.81502%2016.3769%207.65347%2017.1262C7.56482%2017.5389%207.43676%2017.8765%207.27028%2018.1388C7.10381%2018.4011%206.89596%2018.5983%206.64772%2018.7295C6.3985%2018.8606%206.12071%2018.9267%205.8114%2018.9267C5.21641%2018.9267%204.79776%2018.6034%204.62833%2018.1632C4.4589%2017.7229%204.47367%2017.2583%204.60075%2016.5639C4.72782%2015.8705%205.05092%2015.1395%205.37107%2014.3699H1.17665C1.17665%2014.3699%200.207341%2016.1115%200.0310135%2017.6762C-0.0655232%2018.5302%200.0635208%2019.2653%200.41519%2019.8844C0.76686%2020.5036%201.33032%2020.9814%202.10655%2021.319C2.39222%2021.443%202.7104%2021.5447%203.05813%2021.623L2.54589%2024H7.17473L7.7047%2021.5386C8.08493%2021.442%208.43857%2021.3231%208.76562%2021.1787C9.73985%2020.7476%2010.52%2020.1427%2011.1071%2019.3649C11.6932%2018.5871%2012.0873%2017.7291%2012.2892%2016.7917C12.4744%2015.9295%2012.5099%2015.1741%2012.3966%2014.5275L12.3976%2014.5255Z'%20fill='white'/%3e%3c/svg%3e";async function Le(a){let e=a.replace(/-/g,"+").replace(/_/g,"/");for(;e.length%4;)e+="=";const t=atob(e),i=Uint8Array.from(t,n=>n.charCodeAt(0)),s=new Blob([i]).stream().pipeThrough(new DecompressionStream("gzip")),r=await new Response(s).text();return JSON.parse(r)}function F(a,e){return typeof e=="string"&&/\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}.\d+(?:Z|[+-]\d+)/.test(e)?new Date(e):e}function te(a,e){return e}function q(a,e=!1,t=!1,i=","){const s=a/100;if(t){const n=Math.round(s).toLocaleString("en-US");return i!==","?n.replace(/,/g,i):n}else{const r=e?",":".",n=s.toFixed(2).split("."),o=parseInt(n[0],10),l=n[1]??"00",c=o.toLocaleString("en-US");return i!==","?`${c.replace(/,/g,i)}${r}${l}`:e?`${c.replace(/,/g,".")}${r}${l}`:`${c}${r}${l}`}}function H(a,e,t,i){const s=e.replace("{{amount}}",q(a,!1,!1)).replace("{{amount_no_decimals}}",q(a,!1,!0)).replace("{{amount_with_comma_separator}}",q(a,!0,!1)).replace("{{amount_no_decimals_with_comma_separator}}",q(a,!0,!0)).replace("{{amount_with_space_separator}}",q(a,!1,!1," ")).replace("{{amount_no_decimals_with_space_separator}}",q(a,!1,!0," ")).replace("{{amount_with_apostrophe_separator}}",q(a,!1,!1,"'")).replace("{{amount_no_decimals_with_apostrophe_separator}}",q(a,!1,!0,"'")).replace("{{amount_with_period_and_space_separator}}",q(a,!1,!1,". ")).replace("{{amount_no_decimals_with_period_and_space_separator}}",q(a,!1,!0,". "));return i?`${s} ${t}`:s}function le(a){return a.replace(/[^\d.,\s-]/g,"").trim()}function j(a){const e=new Map;for(const[t,i,s]of a.variants)e.set(t,{priceInCents:i,compareAtPriceInCents:s});return e}function $e(a,e,t,i){const{priceInCents:s,compareAtPriceInCents:r}=t,{moneyFormat:n,currency:o,currencyCodeEnabled:l}=i;if(a.getAttribute("data-sl-attribute-p")===e)a.innerHTML=H(s,n,o,l);else if(a.getAttribute("data-sl-attribute-cap")===e)r<=0||r<=s?a.remove():a.innerHTML=H(r,n,o,l);else if(a.getAttribute("data-sl-attribute-discount")===e&&!(r<=0||r<=s)){const d=Math.round((r-s)/r*100),p=le(H(r-s,n,o,!1)),h=a.getAttribute("data-sl-format")||"percent";h==="percent"?a.textContent=`-${d}%`:h==="amount"?a.textContent=`-${p}`:h==="both"&&(a.textContent=`-${d}% (-${p})`)}}function Me(a){const e=[],t={id:"url-pattern",operator:"contains",value:"/"};for(const[i,s,r]of a.variants){e.push({id:`p-${i}`,cssSelector:`[data-sl-attribute-p="${i}"]`,urlPatterns:[t],actions:[{id:`p-action-${i}`,type:"innerHtml",scope:"price",value:H(s,a.moneyFormat,a.currency,a.currencyCodeEnabled)}]});const n=r<=0||r<=s;if(e.push({id:`cap-${i}`,cssSelector:`[data-sl-attribute-cap="${i}"]`,urlPatterns:[t],actions:[{id:`cap-action-${i}`,type:n?"remove":"innerHtml",scope:"compare-at-price",value:n?"":H(r,a.moneyFormat,a.currency,a.currencyCodeEnabled)}]}),!n&&r>s){const o=Math.round((r-s)/r*100),l=le(H(r-s,a.moneyFormat,a.currency,!1));e.push({id:`d-${i}`,cssSelector:`[data-sl-attribute-discount="${i}"]`,urlPatterns:[t],actions:[{id:`d-action-${i}`,type:"js",scope:null,value:`var format = element.getAttribute('data-sl-format') || 'percent'; if (format === 'percent') { element.textContent = '-${o}%'; } else if (format === 'amount') { element.textContent = '-${l}'; } else if (format === 'both') { element.textContent = '-${o}% (-${l})'; }`}]})}}return e}const qe=a=>{let e=5381;for(let t=0;t<a.length;t++)e=(e*33^a.charCodeAt(t))>>>0;return e.toString(36)},He=()=>Math.random().toString(36).slice(2,10)+Date.now().toString(36).slice(-4),Ne=a=>btoa(JSON.stringify(a)).replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/,""),J=a=>a.replace(/#slr-[a-z0-9]+$/,""),Ue=/^[A-Za-z0-9._=~+/-]{1,256}$/,ie=a=>typeof a=="string"&&Ue.test(a)?a:null,Fe=a=>{if(!a)return null;try{const t=JSON.parse(atob(decodeURIComponent(a)))?.$exchange_id;return typeof t=="string"&&t.length>0?t:null}catch{return null}},rt="modulepreload",nt=function(a){return"/"+a},ot={},Be=function(e,t,i){let s=Promise.resolve();function r(n){const o=new Event("vite:preloadError",{cancelable:!0});if(o.payload=n,window.dispatchEvent(o),!o.defaultPrevented)throw n}return s.then(n=>{for(const o of n||[])o.status==="rejected"&&r(o.reason);return e().catch(r)})};function ce(a,e,t){const i=t?a.plans.filter(c=>!c.variantId||c.variantId===t):a.plans,s=[],r=[];for(const c of i)c.direction==="decrease"?(s.push(c.existingShopifyPlanId),r.push(c.createdShopifyPlanId)):(s.push(c.createdShopifyPlanId),r.push(c.existingShopifyPlanId));const n=e?s:r,o=e?r:s;if(t)for(const c of a.plans)for(const d of[c.existingShopifyPlanId,c.createdShopifyPlanId])d&&!n.includes(d)&&!o.includes(d)&&o.push(d);const l={};for(let c=0;c<o.length;c++){const d=o[c],p=n[c];d&&p&&(l[d]=p)}return{showPlanIds:n,hidePlanIds:o,swapMap:l}}function de(a,e,t){const i=e?a.plans.find(r=>r.variantId===e):void 0;if(i)return i.direction;if(t){const r=a.plans.find(n=>n.productId===t);if(r)return r.direction}return a.plans.find(r=>!r.variantId)?.direction??null}function Y(a,e){const t=e?a.plans.filter(r=>!r.productId||r.productId===e):a.plans,i={};for(const r of t)i[r.existingShopifyPlanId]=r.existingDiscountAmount,i[r.createdShopifyPlanId]=r.existingDiscountAmount;const s=Math.max(...Object.values(i),0);return{discountMap:i,maxDiscount:s}}function W(a){const e=document.querySelector('form[action*="/cart/add"] input[name="product-id"]')?.value;if(e)return e;if(a){for(const r of Array.from(document.querySelectorAll("[data-sl-attribute-p]"))){const n=r.getAttribute("data-sl-attribute-p");if(!n)continue;const o=a.variants.find(l=>l[0]===n);if(o?.[3])return o[3]}const s=document.querySelector('form[action*="/cart/add"] input[name="id"]')?.value;if(s){const r=a.variants.find(n=>n[0]===s);if(r?.[3])return r[3]}}const t=window,i=t.ShopifyAnalytics?.meta?.product?.id??t.meta?.product?.id;return i!=null?String(i):null}function D(a,e){return a.widget.selectors[e]??[]}function N(a,e){return a.replace(/[\d.]+%/,`${e}%`)}function $(a,e){const t=document.createTreeWalker(a,NodeFilter.SHOW_TEXT);let i=t.nextNode();for(;i;){if(i.nodeValue!==null){const s=e(i.nodeValue);if(s!==i.nodeValue){i.nodeValue=s;return}}i=t.nextNode()}}function pe(a,e){return a===null?!1:a==="decrease"?!e:e}async function ze(a){if(a.subscriptionSwapDone)return;const e=a.getActiveAssignment();if(!e)return;const t=a.getHypothesis(e.hypothesisId);if(!t?.subscriptionData)return;a.subscriptionSwapDone=!0;const i=t.subscriptionData,s=t.isControl,r=[...new Set(i.plans.map(d=>d.direction))].join(",");a.log(`[SUB-SWAP] ${s?"A":"B"} side, directions=${r}`);const n=i.plans.some(d=>d.variantId);let o=!1,l=!1;function c(){if(!l){l=!0;try{const d=n?document.querySelector("select[name='id'], input[name='id']")?.value:void 0,{showPlanIds:p,hidePlanIds:h,swapMap:u}=ce(i,s,d);a.swapMap=u;const b=D(i,"widgetParent"),E=D(i,"subscriptionPlans"),S=D(i,"subscriptionInput");if(!b.length||!E.length||!S.length)return;const C=document.querySelector(b[0].selector);if(!C?.shadowRoot)return;const _=C.shadowRoot.querySelector(E[0].selector);if(!_?.shadowRoot)return;const T=S[0].selector;let m=null;if(i.widget.widgetType==="buttons"||i.widget.widgetType==="radio"){const y=Array.from(_.shadowRoot.querySelectorAll(T));if(!y.length)return;for(const v of y){const g=v.closest("label");g&&(p.includes(v.value)?g.style.display="":h.includes(v.value)&&(g.style.display="none"))}const w=y.some(v=>p.includes(v.value)&&v.checked),I=y.some(v=>h.includes(v.value)&&v.checked);if((w||I)&&(o=!1),!w&&!o){o=!0;for(const v of y)if(p.includes(v.value)){v.closest("label")?.click(),v.dispatchEvent(new Event("change",{bubbles:!0}));break}}const f=y.find(v=>v.checked);m=f&&p.includes(f.value)?f.value:p[0]??null}else if(i.widget.widgetType==="dropdown"){const y=_.shadowRoot.querySelector("select");if(!y)return;for(const w of Array.from(y.options))h.includes(w.value)&&(w.style.display="none",w.disabled=!0);if(h.includes(y.value)){const w=Array.from(y.options).find(I=>p.includes(I.value));w&&(y.value=w.value,y.dispatchEvent(new Event("change",{bubbles:!0})))}m=p.includes(y.value)?y.value:p[0]??null}if(m){const y=Array.from(document.querySelectorAll('input[name="selling_plan"]'));for(const w of y)w.value!==m&&(w.value=m)}}finally{l=!1}}}if(a.subscriptionHideWrongPlans=c,a.swapMap=ce(i,s).swapMap,c(),n){const d=document.querySelector("select[name='id'], input[name='id']");d&&d.addEventListener("change",c)}}function B(a){const e=D(a,"widgetParent");return e.length?document.querySelector(e[0].selector)?.shadowRoot??null:null}function Z(a,e){const t=D(a,"subscriptionPlans");return t.length?e.querySelector(t[0].selector)?.shadowRoot??null:null}function X(a,e){const t=new URLSearchParams(window.location.search).get("variant");if(t)return t;{const i=document.querySelector('form[action*="/cart/add"] input[name="id"]')?.value;if(i)return i}return a.size>0?[...a.keys()][0]:void 0}function K(a,e){return H(a,e.moneyFormat,e.currency,e.currencyCodeEnabled)}function We({originalFetch:a,swapMap:e,slptValue:t,getSelectedPlanId:i,log:s}){if(window.fetch.__shoplift_intercepted)return s("[SUB-INTERCEPT] already installed — skipping"),()=>{};function r(o){if(i){const l=i();if(l)return e[l]??l}return e[o]??o}const n=function(o,l){if((typeof o=="string"?o:o instanceof URL?o.href:o.url).includes("/cart/add")&&l?.body)try{if(l.body instanceof FormData){const d=l.body.get("selling_plan");d?l.body.set("selling_plan",r(String(d))):(!d||d==="")&&t&&l.body.set("properties[_slpt]",t)}else if(typeof l.body=="string"){const d=JSON.parse(l.body);if(d.items)for(const p of d.items){const h=String(p.selling_plan??"");h?p.selling_plan=r(h):!p.selling_plan&&t&&(p.properties||(p.properties={}),p.properties._slpt=t)}else if(d.id){const p=String(d.selling_plan??"");p?d.selling_plan=r(p):!d.selling_plan&&t&&(d.properties||(d.properties={}),d.properties._slpt=t)}l.body=JSON.stringify(d)}}catch(d){s("[SUB-INTERCEPT] body parse failed; cart-add proceeds with un-swapped plan",d)}return a.call(window,o,l)};return n.__shoplift_intercepted=!0,window.fetch=n,function(){window.fetch===n&&(window.fetch=a)}}function Ke({log:a}){if(window.fetch.__shoplift_intercepted)return a("[SUB-PREVIEW-BLOCK] already installed — skipping"),()=>{};const e=window.fetch,t=function(i,s){const r=typeof i=="string"?i:i instanceof URL?i.href:i.url;return r.includes("/cart/add")?(a("[SUB-PREVIEW-BLOCK] cart-add blocked in preview mode",{url:r}),Promise.resolve(new Response(JSON.stringify({id:0,properties:{},quantity:0,variant_id:0,key:"preview",title:"Preview — cart-add blocked",price:0,original_price:0,line_price:0,original_line_price:0,total_discount:0,discounts:[],preview:!0}),{status:200,headers:{"Content-Type":"application/json"}}))):e.call(window,i,s)};return t.__shoplift_intercepted=!0,window.fetch=t,function(){window.fetch===t&&(window.fetch=e)}}function ue({data:a,runUpdates:e,debounceMs:t=150}){let i=null;function s(){i&&clearTimeout(i),e(),i=setTimeout(e,t)}let r=null;const n=[],o={childList:!0,subtree:!0,characterData:!0,attributes:!0};function l(h){for(const u of n)u.disconnect();n.length=0;for(const u of Array.from(h.querySelectorAll("*")))if(u.shadowRoot){const b=new MutationObserver(s);b.observe(u.shadowRoot,o),n.push(b)}}function c(){const h=B(a);return h?(r&&r.disconnect(),l(h),r=new MutationObserver(u=>{u.some(b=>b.type==="childList"&&b.addedNodes.length>0)&&l(h),s()}),r.observe(h,o),!0):!1}const d=document.body||document.documentElement,p=new MutationObserver(()=>{c()&&s()});return p.observe(d,{childList:!0,subtree:!0}),c()&&s(),e(),function(){i&&(clearTimeout(i),i=null),p.disconnect(),r&&(r.disconnect(),r=null);for(const u of n)u.disconnect();n.length=0}}async function Ge(a){if(a.subscriptionPriceDone)return;const e=a.getActiveAssignment(),t=e?a.getHypothesis(e.hypothesisId):void 0,i=t?.subscriptionData?null:a.findActiveSubscriptionTestControl(),s=t?.subscriptionData?t:i?.hypothesis;if(!s?.subscriptionData)return;const r=t?.subscriptionData?e.testId:i.testId;a.subscriptionPriceDone=!0;const n=s.subscriptionData,o=s.isControl,l=s.priceData,c=n.widget.widgetType;let d=W(l),p=Y(n,d),h=p.discountMap,u=p.maxDiscount;function b(){const g=W(l);g!==d&&(d=g,p=Y(n,d),h=p.discountMap,u=p.maxDiscount,a.log(`[SUB-PRICE] scope refreshed side=${o?"A":"B"}, currentProductId=${d??"n/a"}, maxDiscount=${u}`))}a.log(`[SUB-PRICE] side=${o?"A":"B"}, currentProductId=${d??"n/a"}, maxDiscount=${u}`),a.updatePriceTestHiddenInputs(r,o?"control":"variant",!1);function E(){if(!l)return null;const g=j(l),P=X(g),A=de(n,P,d);if(!pe(A,o))return null;const k=P?g.get(P):void 0;return k?{formattedVariantPrice:K(k.priceInCents,l),formattedDiscounted:K(k.priceInCents*(1-u/100),l)}:null}We({originalFetch:a.fetch,swapMap:a.swapMap??{},slptValue:a.slptValue??void 0,log:a.log,getSelectedPlanId:()=>{const g=B(n);if(!g)return null;const P=Z(n,g);if(!P)return null;const A=D(n,"subscriptionInput"),k=A.length?A[0].selector:'input[name="rc_plan"]';return P.querySelector(`${k}:checked`)?.value??null}});function S(g){const P=D(n,"subscriptionDiscount");for(const A of P)if(A.selector.includes("badge")||A.selector.includes("__badge")){const k=g.querySelector(A.selector);k?.textContent&&!k.textContent.includes(`${u}%`)&&$(k,x=>N(x,u))}}function C(g){const P=E();if(!P)return;const A=D(n,"subscriptionCompareAt");for(const k of A){const x=g.querySelector(k.selector)||g.querySelector(`[part~="${k.selector}"]`);x?.textContent&&!x.textContent.includes(P.formattedVariantPrice)&&$(x,R=>/\d/.test(R)?P.formattedVariantPrice:R)}}function _(g,P){const A=D(n,"subscriptionCompareAt"),k=P===0?"none":"";for(const x of A){const R=g.querySelector(x.selector)||g.querySelector(`[part~="${x.selector}"]`);R&&(k==="none"?R.style.display!=="none"&&(R.style.display="none"):R.style.display==="none"&&(R.style.display=""))}}function T(g){const P=D(n,"subscriptionInput"),A=P.length?P[0].selector:'input[name="rc_plan"]',k=D(n,"subscriptionPlanDiscount"),x=k.length?k[0].selector:".rc-plans-button__discount";for(const R of Array.from(g.querySelectorAll("label"))){const O=R.querySelector(A),V=R.querySelector(x);if(O&&V){const L=h[O.value];if(L!==void 0){if(L===0)V.style.display!=="none"&&(V.style.display="none");else if(V.style.display==="none"&&(V.style.display=""),V.textContent){const Q=V.textContent.match(/[\d.]+%/)?.[0];Q&&Q!==`${L}%`&&$(V,st=>N(st,L))}}}}}function m(g){const P=g.querySelector("select");if(P)for(const A of Array.from(P.options)){const k=h[A.value];if(k!==void 0&&A.textContent){const x=A.textContent.match(/[\d.]+%/)?.[0];x&&x!==`${k}%`&&(A.textContent=N(A.textContent,k))}}}function y(g,P){const k=D(n,"subscriptionDiscount").filter(x=>x.selector.includes("benefit")||x.selector==="rc-benefits");for(const x of k){const R=g.querySelector(x.selector);if(R?.shadowRoot){for(const O of Array.from(R.shadowRoot.querySelectorAll("li")))if(O.textContent?.includes("Save")){const V=O;if(P===0)V.style.display!=="none"&&(V.style.display="none");else{V.style.display==="none"&&(V.style.display="");const L=O.textContent.match(/[\d.]+%/)?.[0];L&&L!==`${P}%`&&$(O,Q=>N(Q,P))}}}}}let w=!1;function I(){if(!w){w=!0;try{if(b(),d!==null&&Object.keys(h).length===0)return;const g=B(n);if(!g)return;S(g),l&&C(g);const P=Z(n,g);let A=u;if(P){const k=D(n,"subscriptionInput"),x=k.length?k[0].selector:'input[name="rc_plan"]',R=P.querySelector(`${x}:checked`);if(R){const O=h[R.value];O!==void 0&&(A=O)}c==="buttons"||c==="radio"?T(P):m(P)}_(g,A),y(g,A)}finally{w=!1}}}function f(){const g=E();if(!g)return;const P=B(n);if(!P)return;const A=D(n,"onetimeToggle"),k=A.length?A[0].selector:'input[value="onetime"]';if(!P.querySelector(k)?.checked)return;const R=D(n,"subscriptionPrice");for(const O of R){const V=P.querySelector(O.selector)||P.querySelector(`[part~="${O.selector}"]`);V?.textContent&&!V.textContent.includes(g.formattedDiscounted)&&$(V,L=>/\d/.test(L)?g.formattedDiscounted:L)}}function v(){a.subscriptionHideWrongPlans&&a.subscriptionHideWrongPlans(),I(),a.subscriptionUpdateOneTime&&a.subscriptionUpdateOneTime(),f()}ue({data:n,runUpdates:v})}async function je(a){if(a.subscriptionOneTimeDone)return;const e=a.getActiveAssignment(),t=e?a.getHypothesis(e.hypothesisId):void 0,i=!!(t?.subscriptionData&&t.priceData),s=i?null:a.findActiveSubscriptionTestControl(),r=i?t:s?.hypothesis;if(!r?.subscriptionData||!r.priceData)return;const n=i?e.testId:s.testId;a.subscriptionOneTimeDone=!0;const o=r.subscriptionData,l=r.priceData,c=j(l),d=r.isControl,p=d?"control":"variant";a.slptValue=`${n}:${p}:f`,a.updatePriceTestHiddenInputs(n,p,!1);function h(){const u=B(o);if(!u)return;const b=X(c);if(!b)return;const E=W(l),S=de(o,b,E);if(!pe(S,d))return;const C=c.get(b);if(!C)return;const _=H(C.priceInCents,l.moneyFormat,l.currency,l.currencyCodeEnabled),T=D(o,"onetimePrice");if(!T.length)return;const m=D(o,"onetimeContainer"),y=m.length?m[0].selector:'[part~="rc-purchase-option__onetime"]',I=u.querySelector(y)??u;for(const f of T){let v=null;try{v=I.querySelector(f.selector)}catch{v=null}v??=I.querySelector(`[part~="${f.selector}"]`),v&&v.textContent&&!v.textContent.includes(_)&&$(v,g=>/\d/.test(g)?_:g)}}a.subscriptionUpdateOneTime=h,h()}async function Je(a,e){const{subscriptionPreviewRender:t}=await Be(async()=>{const{subscriptionPreviewRender:i}=await Promise.resolve().then(()=>it);return{subscriptionPreviewRender:i}},void 0);return t(a.subscriptionData,a.priceData,a.isControl,e)}function Ye(a,e){const t=a.widget.selectors.widgetParent??[],i=a.widget.selectors.subscriptionPlans??[],s=a.widget.selectors.subscriptionInput??[];if(!t.length||!i.length||!s.length){e("[SUB-GLOBAL-HIDE] Missing required selectors — skipping");return}const r=t[0].selector,n=i[0].selector,o=s[0].selector;let l=!1,c=null,d=!1;function p(){if(!d){d=!0;try{h()}finally{d=!1}}}function h(){const C=document.querySelector(r);if(!C?.shadowRoot)return;const _=C.shadowRoot.querySelector(n);if(!_?.shadowRoot)return;_.shadowRoot!==c&&(c=_.shadowRoot,l=!1);let T=0;if(a.widget.widgetType==="buttons"||a.widget.widgetType==="radio"){const m=Array.from(_.shadowRoot.querySelectorAll(o));for(const f of m)if(a.planIds.includes(f.value)){f.disabled||(f.disabled=!0);const v=f.closest("label");v&&v.style.display!=="none"&&(v.style.display="none",T++)}const y=m.filter(f=>!a.planIds.includes(f.value));if(!y.some(f=>f.checked)&&!l&&y.length>0){l=!0;const f=y[0];f.closest("label")?.click(),f.dispatchEvent(new Event("change",{bubbles:!0})),e(`[SUB-GLOBAL-HIDE] Preselected first visible plan input=${f.value}`)}const I=y.find(f=>f.checked)??y[0];if(I){const f=Array.from(document.querySelectorAll('input[name="selling_plan"]'));for(const v of f)v.value!==I.value&&(v.value=I.value,e(`[SUB-GLOBAL-HIDE] Mirrored plan id ${I.value} to form selling_plan input`))}}else if(a.widget.widgetType==="dropdown"){const m=_.shadowRoot.querySelector("select");if(!m)return;for(const I of Array.from(m.options))a.planIds.includes(I.value)&&(I.style.display!=="none"&&(I.style.display="none"),I.disabled||(I.disabled=!0),T++);const y=Array.from(m.options).filter(I=>!a.planIds.includes(I.value)),w=y.some(I=>I.value===m.value);y.length>0&&!w&&!l&&(l=!0,m.value=y[0].value,m.dispatchEvent(new Event("change",{bubbles:!0})),e(`[SUB-GLOBAL-HIDE] Preselected first visible option=${y[0].value}`))}T>0&&e(`[SUB-GLOBAL-HIDE] Hidden ${T} B-side plan buttons`)}const u={childList:!0,subtree:!0,characterData:!0};let b=null;function E(C){b?.disconnect(),b=new MutationObserver(()=>p()),b.observe(C,u)}function S(){const C=document.querySelector(r);if(!C?.shadowRoot)return!1;p(),new MutationObserver(()=>{p();const m=C.shadowRoot.querySelector(n);m?.shadowRoot&&E(m.shadowRoot)}).observe(C.shadowRoot,u);const T=C.shadowRoot.querySelector(n);return T?.shadowRoot&&E(T.shadowRoot),!0}if(!S()){e("[SUB-GLOBAL-HIDE] Widget not in DOM yet — waiting via MutationObserver");const C=new MutationObserver(()=>{S()&&C.disconnect()});C.observe(document.body??document.documentElement,{childList:!0,subtree:!0})}}const he="Limited preview",Ze="Add-to-cart and checkout prices won't reflect this test until it launches — test selling plans are not created in your subscription app until after a test is launched.",Xe=5e3;function Qe(){const a=document.createElement("div");a.id="shoplift-preview-subscription-warning";const e=document.createElement("span");e.id="shoplift-preview-subscription-warning__icon",e.setAttribute("aria-hidden","true"),e.textContent="!";const t=document.createElement("span");t.id="shoplift-preview-subscription-warning__label",t.textContent=he;const i=document.createElement("div");i.id="shoplift-preview-subscription-warning__tooltip",i.setAttribute("role","tooltip"),i.textContent=Ze,a.appendChild(e),a.appendChild(t),a.appendChild(i),a.setAttribute("tabindex","0"),a.setAttribute("aria-describedby",i.id),a.setAttribute("aria-label",he);let s=null;function r(){s!==null&&(clearTimeout(s),s=null)}function n(){i.classList.add("shoplift-preview-subscription-warning__tooltip--visible")}function o(){i.classList.remove("shoplift-preview-subscription-warning__tooltip--visible")}function l(){n(),r(),s=setTimeout(()=>{o(),s=null},Xe)}function c(){r(),n()}function d(){s===null&&o()}a.addEventListener("mouseenter",c),a.addEventListener("mouseleave",d),a.addEventListener("focus",c),a.addEventListener("blur",d);function p(u){try{const b=u.target;if(!(b instanceof Element))return;(b.closest('form[action*="/cart/add"] button[type="submit"], form[action*="/cart/add"] input[type="submit"]')!==null||b.closest('[name="add"], button[name="add"], [data-add-to-cart], button[data-add-to-cart]')!==null)&&l()}catch{}}document.addEventListener("click",p,!0);function h(){r(),document.removeEventListener("click",p,!0),a.removeEventListener("mouseenter",c),a.removeEventListener("mouseleave",d),a.removeEventListener("focus",c),a.removeEventListener("blur",d),a.remove()}return{root:a,tooltip:i,cleanup:h}}let fe=!1;class et{DATA_SL_ATTRIBUTE_P="data-sl-attribute-p";DATA_SL_TEST_ID="data-sl-test-id";VIEWPORT_TRACK_THRESHOLD=.5;temporarySessionKey="Shoplift_Session";essentialSessionKey="Shoplift_Essential";analyticsSessionKey="Shoplift_Analytics";priceSelectorsSessionKey="Shoplift_PriceSelectors_v2";shop;host;eventHost;disableReferrerOverride;legacySessionKey;cssHideClass;testConfigs;inactiveTestConfigs;hiddenSubscriptionPlans;testsFilteredByAudience;sendPageView;shopliftDebug;gaConfig;telemetryEnabled;getCountryTimeout;klaviyoGateTimeout=1e3;geoViaShopify;resolvedRegion=null;klaviyoMembership=null;state;subscriptionPreviewWarningCleanup=null;shopifyAnalyticsId;cookie=document.cookie;isSyncing=!1;isSyncingGA=!1;fetch;localStorageSet;localStorageGet;sessionStorageSet=window.sessionStorage.setItem.bind(window.sessionStorage);sessionStorageGet=window.sessionStorage.getItem.bind(window.sessionStorage);urlParams=new URLSearchParams(window.location.search);device;logHistory;activeViewportObservers=new Map;clientIdRetryCount=0;constructor(e,t,i,s,r,n,o,l,c,d,p,h,u,b=!1){this.shop=e,this.host=t,this.eventHost=i,this.disableReferrerOverride=l,this.logHistory=[],this.legacySessionKey=`SHOPLIFT_SESSION_${this.shop}`,this.cssHideClass=s?"shoplift-hide":"",this.testConfigs=p.map(S=>({...S,startAt:new Date(S.startAt),statusHistory:S.statusHistory.map(C=>({...C,createdAt:new Date(C.createdAt)}))})),this.inactiveTestConfigs=h,this.hiddenSubscriptionPlans=u,this.sendPageView=!!r,this.shopliftDebug=n===!0,this.telemetryEnabled=c===!0,this.geoViaShopify=b===!0,this.gaConfig=o!=={"sendEvents":false,"mode":"gtag"}?o:{sendEvents:!1},this.fetch=window.fetch.bind(window),this.localStorageSet=window.localStorage.setItem.bind(window.localStorage),this.localStorageGet=window.localStorage.getItem.bind(window.localStorage);const E=this.getDeviceType();this.device=E!=="tablet"?E:"mobile",this.state=this.loadState(),this.shopifyAnalyticsId=this.getShopifyAnalyticsId(),this.testsFilteredByAudience=p.filter(S=>S.status=="active"),this.getCountryTimeout=d===1000?1e3:d,window.__slReadCookie=S=>{const C=this.getCookie(S);if(C===null)return null;try{return decodeURIComponent(C)}catch{return C}},this.log("State Loaded",JSON.stringify(this.state))}deriveCategoryFromExistingTests(){if(!this.state.temporary.testCategory&&this.state.essential.visitorTests.length>0){const e=this.state.essential.visitorTests.some(t=>{if(!t.hypothesisId)return!1;const i=this.getHypothesis(t.hypothesisId);return i&&["theme","basicScript","price"].includes(i.type)});this.state.temporary.testCategory=e?"global":"conditional",this.persistTemporaryState(),this.log("Derived test category from existing visitorTests: %s",this.state.temporary.testCategory)}}async init(){try{if(this.log("Shoplift script initializing"),window.Shopify&&window.Shopify.designMode){this.log("Skipping script for design mode");return}if(window.location.href.includes("slScreenshot=true")){this.log("Skipping script for screenshot");return}if(window.location.hostname.endsWith(".edgemesh.com")){this.log("Skipping script for preview");return}if(window.location.href.includes("isShopliftMerchant")){const n=this.urlParams.get("isShopliftMerchant")==="true";this.log("Setting merchant session to %s",n),this.state.temporary.isMerchant=n,this.persistTemporaryState()}if(this.state.temporary.isMerchant){this.log("Setting up preview for merchant"),typeof window.shoplift!="object"&&this.setShopliftStub(),this.state.temporary.previewConfig||this.hidePage(),await this.initPreview(),document.querySelector("#sl-preview-bar-hide")?.remove();return}if(this.state.temporary.previewConfig=void 0,be(navigator.userAgent))return;const e=Date.now(),t=!this.state.temporary.lastSeen||e-this.state.temporary.lastSeen>1800*1e3;(!this.state.temporary.entryPage||t)&&(this.state.temporary.entryPage=J(window.location.href)),this.state.temporary.lastSeen=e,this.persistTemporaryState(),window.__slEntryPage=this.state.temporary.entryPage??"";const i=this.state.essential.visitorTests.filter(n=>n.hypothesisId&&+n.createdAt>Date.now()-6e4);if(i.length===0)this.sendDiagnosticTelemetry("page-landed",null);else for(const n of i)this.sendDiagnosticTelemetry("page-landed",n.testId,{hypothesisId:n.hypothesisId,isControl:n.assignedTo==="control",testType:n.testType??"unknown"});if(navigator.userAgent.includes("Chrome/118")){this.log("Random: %o",[Math.random(),Math.random(),Math.random()]);const n=await this.makeRequest({url:`${this.eventHost}/api/v0/events/ip`,method:"get"}).then(o=>o?.json());this.log(`IP: ${n}`),this.makeRequest({url:`${this.eventHost}/api/v0/logs`,method:"post",data:JSON.stringify(this.debugState(),te)}).catch()}if(this.shopifyAnalyticsId=this.getShopifyAnalyticsId(),this.monitorConsentChange(),this.checkForThemePreview())return;if(!this.disableReferrerOverride&&this.state.temporary.originalReferrer!=null){this.log(`Overriding referrer from '${document.referrer}' to '${this.state.temporary.originalReferrer}'`);const n=this.state.temporary.originalReferrer;delete this.state.temporary.originalReferrer,this.persistTemporaryState(),Object.defineProperty(document,"referrer",{get:()=>n,enumerable:!0,configurable:!0})}if(this.needsKlaviyo(this.testConfigs,this.state.essential.visitorTests,this.state.analytics.visitor??this.buildBaseVisitor())&&this.ensureKlaviyoMembership(),await this.refreshVisitor(this.shopifyAnalyticsId),await this.handleVisitorTest()){this.log("Redirecting for visitor test");return}this.setShoplift(),this.showPage(),this.ensureCartAttributesForExistingPriceTests(!1);const r=this.state.essential.visitorTests.some(n=>(n.hypothesisId?this.getHypothesis(n.hypothesisId):void 0)?.subscriptionData!=null)||Object.values(this.state.temporary.testReservations??{}).some(n=>this.getHypothesis(n.hypothesisId)?.subscriptionData!=null);this.hiddenSubscriptionPlans&&!r&&(this.log(`[SUB-GLOBAL] Visitor not in subscription test — hiding ${this.hiddenSubscriptionPlans.planIds.length} B-side plans`),Ye(this.hiddenSubscriptionPlans,n=>this.log(n))),await this.subscriptionSwap(),await this.subscriptionOneTimePrice(),await this.subscriptionPriceChange(),await this.finalize(),console.log("SHOPLIFT SCRIPT INITIALIZED!")}catch(e){if(e instanceof G)return;throw e}finally{typeof window.shoplift!="object"&&this.setShopliftStub()}}getVariantColor(e){switch(e){case"a":return{text:"#141414",bg:"#E2E2E2"};case"b":return{text:"rgba(255, 255, 255, 1)",bg:"rgba(37, 99, 235, 1)"}}}getDefaultVariantTitle(e){return e.title?e.title:e.type==="price"?e.isControl?"Original prices":"Variant prices":e.isControl?"Original":"Untitled variant "+e.label.toUpperCase()}async initPreview(){const e=this.urlParams.get("previewConfig");if(e){this.state.temporary.previewConfig=void 0,this.log("Setting up the preview"),this.log("Found preview config, writing to temporary state");const t=await Le(e);if(this.state.temporary.previewConfig=t,this.state.temporary.previewConfig.testTypeCategory===M.Price){this.hidePage(!0);const s=this.state.temporary.previewConfig;let r=`${this.host}/api/dom-selectors/${s.storeId}/${s.testId}/${s.isDraft||!1}`;s.shopifyProductId&&(r+=`?productId=${s.shopifyProductId}`);const n=await this.makeJsonRequest({method:"get",url:r}).catch(o=>(this.log("Error getting domSelectors",o),null));if(s.variants.forEach(o=>o.domSelectors=n[o.id]?.domSelectors),s.isDraft){const o=`${this.host}/api/dom-selectors/${s.storeId}/${s.testId}/subscription-preview`,l=await this.makeJsonRequest({method:"get",url:o}).catch(c=>(this.log("No subscription preview data for draft (test may not have a subscription widget)",c),null));l?.subscriptionData&&s.variants.forEach(c=>{c.subscriptionData=l.subscriptionData,c.priceData=l.priceData})}}this.persistTemporaryState();const i=new URL(window.location.toString());i.searchParams.delete("previewConfig"),this.queueRedirect(i)}else if(this.state.temporary.previewConfig){this.showPage();const t=this.state.temporary.previewConfig;if(t.testTypeCategory===M.Template&&this.handleTemplatePreview(t)&&this.initPreviewControls(t),t.testTypeCategory===M.UrlRedirect&&this.handleUrlPreview(t)&&this.initPreviewControls(t),t.testTypeCategory===M.Script&&this.handleScriptPreview(t)&&this.initPreviewControls(t),t.testTypeCategory===M.Price){const i=await this.handlePricePreview(t);t.isDraft?await this.handleSubscriptionPricePreview(t):await this.handleSubscriptionLivePreview(t),i&&this.initPreviewControls(t)}}}initPreviewControls(e){document.addEventListener("DOMContentLoaded",()=>{const t=e.variants.find(b=>b.id===e.currentVariant),i=t?.label||"a",s=e.variants,r=document.createElement("div");r.id="shoplift-preview-control";const n=document.createElement("div"),o=document.createElement("img");o.src=Oe,o.height=24,o.width=14,n.style.padding="0 16px",n.style.lineHeight="100%",n.appendChild(o),r.appendChild(n);const l=document.createElement("div");l.id="shoplift-preview-variant-selector";const c=document.createElement("button");c.id="shoplift-preview-variant-menu-trigger";const d=document.createElement("div");d.className="menu-variant-label",d.style.backgroundColor=this.getVariantColor(i).bg,d.style.color=this.getVariantColor(i).text,d.innerText=i.toUpperCase(),c.appendChild(d);const p=document.createElement("span");if(p.id="shoplift-preview-variant-title",p.innerText=t?this.getDefaultVariantTitle(t):"Untitled variant "+i.toUpperCase(),c.appendChild(p),s.length>1){const b=document.createElement("img");b.src=Ve,b.width=12,b.height=12,b.style.height="12px",b.style.width="12px",c.appendChild(b);const E=document.createElement("div");E.className="preview-variant-menu";for(const S of e.variants.filter(C=>C.id!==e.currentVariant)){const C=document.createElement("div");C.className="preview-variant-menu--item";const _=document.createElement("div");_.className="menu-variant-label",_.style.backgroundColor=this.getVariantColor(S.label).bg,_.style.color=this.getVariantColor(S.label).text,_.style.flexShrink="0",_.innerText=S.label.toUpperCase(),C.appendChild(_);const T=document.createElement("span");T.innerText=this.getDefaultVariantTitle(S),C.appendChild(T),C.addEventListener("click",()=>{this.pickVariant(S.id)}),E.appendChild(C)}l.appendChild(E),c.addEventListener("click",()=>{E.className!=="preview-variant-menu preview-variant-menu__visible"?E.classList.add("preview-variant-menu__visible"):E.classList.remove("preview-variant-menu__visible")}),document.addEventListener("click",S=>{S.target instanceof Element&&!c.contains(S.target)&&E.className==="preview-variant-menu preview-variant-menu__visible"&&E.classList.remove("preview-variant-menu__visible")})}else c.style.pointerEvents="none",d.style.margin="0";if(l.appendChild(c),r.appendChild(l),e.hasSubscription){this.subscriptionPreviewWarningCleanup?.();const b=Qe();r.appendChild(b.root),this.subscriptionPreviewWarningCleanup=b.cleanup}const h=document.createElement("div"),u=document.createElement("button");u.id="shoplift-exit-preview-button",u.innerText="Exit",h.appendChild(u),u.addEventListener("click",()=>{this.exitPreview()}),r.appendChild(h),document.body.appendChild(r),requestAnimationFrame(()=>{r.classList.add("visible")})}),this.ensureCartAttributesForExistingPriceTests(!0)}pickVariant(e){if(this.state.temporary.previewConfig){const t=this.state.temporary.previewConfig,i=new URL(window.location.toString());if(t.testTypeCategory===M.UrlRedirect){const s=t.variants.find(r=>r.id===t.currentVariant)?.redirectUrl;if(i.pathname===s){const r=t.variants.find(n=>n.id===e)?.redirectUrl;r&&(i.pathname=r)}}if(t.testTypeCategory===M.Template){const s=t.variants.find(r=>r.id===t.currentVariant)?.pathName;if(s&&i.pathname===s){const r=t.variants.find(n=>n.id===e)?.pathName;r&&r!==s&&(i.pathname=r)}}t.currentVariant=e,this.persistTemporaryState(),this.queueRedirect(i)}}exitPreview(){const e=new URL(window.location.toString());if(this.state.temporary.previewConfig?.testTypeCategory===M.Template&&e.searchParams.delete("view"),this.state.temporary.previewConfig?.testTypeCategory===M.Script&&e.searchParams.delete("slVariant"),this.state.temporary.previewConfig?.testTypeCategory===M.UrlRedirect){const i=this.state.temporary.previewConfig.variants.filter(r=>!r.isControl&&r.redirectUrl!==null).map(r=>r.redirectUrl),s=this.state.temporary.previewConfig.variants.find(r=>r.label==="a")?.redirectUrl;i.includes(e.pathname)&&s&&(e.pathname=s)}this.state.temporary.isMerchant=!1,e.searchParams.delete("isShopliftMerchant"),this.state.temporary.previewConfig=void 0,this.persistTemporaryState(),this.subscriptionPreviewWarningCleanup?.(),this.subscriptionPreviewWarningCleanup=null,this.hidePage(),this.queueRedirect(e)}handleTemplatePreview(e){const t=e.currentVariant,i=e.variants.find(l=>l.id===t);if(!i)return!1;const s=e.variants.find(l=>l.isControl);if(!s)return!1;this.log("Setting up template preview for type",s.type);const r=new URL(window.location.toString()),n=r.searchParams.get("view"),o=i.type===s.type;return!o&&!i.isControl&&template.suffix===s.affix&&this.typeFromTemplate()===s.type&&i.pathName!==null?(this.log("Hit control template type, redirecting to the variant url"),this.hidePage(),r.pathname=i.pathName,this.queueRedirect(r),!0):(!i.isControl&&this.typeFromTemplate()==i.type&&template.suffix===s.affix&&o&&n!==(i.affix||"__DEFAULT__")&&(this.log("Template type and affix match control, updating the view param"),r.searchParams.delete("view"),this.log("Setting the new viewParam to",i.affix||"__DEFAULT__"),this.hidePage(),r.searchParams.set("view",i.affix||"__DEFAULT__"),this.queueRedirect(r)),n!==null&&n!==(i.affix||"__DEFAULT__")&&(r.searchParams.delete("view"),this.hidePage(),this.queueRedirect(r)),!0)}handleUrlPreview(e){const t=e.currentVariant,i=e.variants.find(n=>n.id===t),s=e.variants.find(n=>n.isControl)?.redirectUrl;if(!i)return!1;this.log("Setting up URL redirect preview");const r=new URL(window.location.toString());return r.pathname===s&&!i.isControl&&i.redirectUrl!==null&&(this.log("Url matches control, redirecting"),this.hidePage(),r.pathname=i.redirectUrl,this.queueRedirect(r)),!0}handleScriptPreview(e){const t=e.currentVariant,i=e.variants.find(n=>n.id===t);if(!i)return!1;this.log("Setting up script preview");const s=new URL(window.location.toString());return s.searchParams.get("slVariant")!==i.id&&(this.log("current id doesn't match the variant, redirecting"),s.searchParams.delete("slVariant"),this.log("Setting the new slVariantParam"),this.hidePage(),s.searchParams.set("slVariant",i.id),this.queueRedirect(s)),!0}async handlePricePreview(e){const t=e.currentVariant,i=e.variants.find(s=>s.id===t);return i?(this.log("Setting up price preview"),i.domSelectors&&i.domSelectors.length>0&&(U(document,{testId:e.testId,hypothesisId:i.id,selectors:i.domSelectors}),this.ensureCartAttributesForExistingPriceTests(!0)),!0):!1}async handleSubscriptionPricePreview(e){const t=e.variants.find(i=>i.id===e.currentVariant);t?.subscriptionData&&(this.log("Setting up subscription price preview"),await Je({id:t.id,isControl:t.isControl,subscriptionData:t.subscriptionData,priceData:t.priceData},(i,...s)=>this.log(i,...s)))}async handleSubscriptionLivePreview(e){this.testConfigs.find(s=>s.id===e.testId)?.hypotheses.find(s=>s.id===e.currentVariant)?.subscriptionData&&(this.log("Setting up subscription live preview"),this.subscriptionSwapDone=!1,this.subscriptionOneTimeDone=!1,this.subscriptionPriceDone=!1,await this.subscriptionSwap(),await this.subscriptionOneTimePrice(),await this.subscriptionPriceChange())}async finalize(){const e=await this.getCartState();e!==null&&this.queueCartUpdate(e),this.pruneStateAndSave(),await this.syncAllEvents()}setShoplift(){this.log("Setting up public API");const t=this.urlParams.get("slVariant")==="true",i=t?null:this.urlParams.get("slVariant");window.shoplift={isHypothesisActive:async s=>{if(this.log("Script checking variant for hypothesis '%s'",s),t)return this.log("Forcing variant for hypothesis '%s'",s),!0;if(i!==null)return this.log("Forcing hypothesis '%s'",i),s===i;const r=this.testConfigs.find(o=>o.hypotheses.some(l=>l.id===s));if(!r)return this.log("No test found for hypothesis '%s'",s),!1;const n=this.state.essential.visitorTests.find(o=>o.testId===r.id);return n?(this.log("Active visitor test found",s),n.hypothesisId===s):(await this.manuallySplitVisitor(r),this.testConfigs.some(o=>o.hypotheses.some(l=>l.id===s&&this.state.essential.visitorTests.some(c=>c.hypothesisId===l.id))))},setAnalyticsConsent:async s=>{await this.onConsentChange(s,!0)},getVisitorData:()=>({visitor:this.state.analytics.visitor,visitorTests:this.state.essential.visitorTests.filter(s=>!s.isInvalid).map(s=>{const{shouldSendToGa:r,savedAt:n,...o}=s;return o})})}}setShopliftStub(){this.log("Setting up stubbed public API");const t=this.urlParams.get("slVariant")==="true",i=t?null:this.urlParams.get("slVariant");window.shoplift={isHypothesisActive:s=>Promise.resolve(t||s===i),setAnalyticsConsent:()=>Promise.resolve(),getVisitorData:()=>({visitor:null,visitorTests:[]})}}async manuallySplitVisitor(e){this.log("Starting manual split for test '%s'",e.id),await this.handleVisitorTest([e])||this.showPage();const i=this.getReservationForTest(e.id);i&&!i.isRealized&&i.entryCriteriaKey&&(this.log("Realizing manual API reservation for test '%s'",e.id),this.realizeReservationForCriteria(i.entryCriteriaKey)),this.saveState(),this.syncAllEvents()}async handleVisitorTest(e){await this.filterTestsByAudience(this.testConfigs,this.state.analytics.visitor??this.buildBaseVisitor(),this.state.essential.visitorTests),this.pruneStaleVisitorTests(),this.deriveCategoryFromExistingTests(),this.clearStaleReservations();let t=e?e.filter(i=>this.testsFilteredByAudience.some(s=>s.id===i.id)):[...this.testsForUrl(this.testsFilteredByAudience),...this.domTestsForUrl(this.testsFilteredByAudience)];try{if(t.length===0)return this.log("No tests found"),!1;this.log("Checking for existing visitor test on page");const i=this.getCurrentVisitorHypothesis(t);if(i){this.log("Found current visitor test");const l=this.considerRedirect(i);return l&&(this.log("Redirecting for current visitor test"),this.redirect(i)),l}const s=this.getReservationForCurrentPage();if(s){this.log("Found matching reservation for current page: %s",s.testId);const l=this.getHypothesis(s.hypothesisId);if(l){l.type!=="price"&&this.realizeReservationForCriteria(s.entryCriteriaKey);const c=this.considerRedirect(l);return c&&this.redirect(l),c}}this.log("No active test relation for test page");const r=this.testsForUrl(this.inactiveTestConfigs.filter(l=>this.testIsPaused(l)&&l.hypotheses.some(c=>this.state.essential.visitorTests.some(d=>d.hypothesisId===c.id)))).map(l=>l.id);if(r.length>0)return this.log("Visitor has paused tests for test page, skipping test assignment: %o",r),!1;if(!this.state.temporary.testCategory){const l=this.testsFilteredByAudience.filter(d=>this.isGlobalEntryCriteria(this.getEntryCriteriaKey(d))),c=this.testsFilteredByAudience.filter(d=>!this.isGlobalEntryCriteria(this.getEntryCriteriaKey(d)));if(this.log("Category dice roll - global tests: %o, conditional tests: %o",l.map(d=>({id:d.id,title:d.title,criteria:this.getEntryCriteriaKey(d)})),c.map(d=>({id:d.id,title:d.title,criteria:this.getEntryCriteriaKey(d)}))),l.length>0&&c.length>0){const d=l.length,p=c.length,h=d+p,u=Math.random()*h;this.state.temporary.testCategory=u<d?"global":"conditional",this.log("Category dice roll: rolled %.2f of %d (global weight: %d, conditional weight: %d), selected '%s'",u,h,d,p,this.state.temporary.testCategory)}else l.length>0?(this.state.temporary.testCategory="global",this.log("Only global tests available, setting category to global")):(this.state.temporary.testCategory="conditional",this.log("Only conditional tests available, setting category to conditional"));this.persistTemporaryState()}const n=this.state.temporary.testCategory;if(this.log("Visitor test category: %s",n),n==="global"){const l=this.testsFilteredByAudience.filter(c=>!this.isGlobalEntryCriteria(this.getEntryCriteriaKey(c)));for(const c of l)this.markTestAsBlocked(c,"category:global");t=t.filter(c=>this.isGlobalEntryCriteria(this.getEntryCriteriaKey(c)))}else{const l=this.testsFilteredByAudience.filter(c=>this.isGlobalEntryCriteria(this.getEntryCriteriaKey(c)));for(const c of l)this.markTestAsBlocked(c,"category:conditional");t=t.filter(c=>!this.isGlobalEntryCriteria(this.getEntryCriteriaKey(c)))}if(t.length===0)return this.log("No tests remaining after category filter"),!1;this.createReservations(t);const o=this.getReservationForCurrentPage();if(o&&!o.isRealized){const l=this.getHypothesis(o.hypothesisId);if(l){l.type!=="price"&&this.realizeReservationForCriteria(o.entryCriteriaKey);const c=this.considerRedirect(l);return c&&(this.log("Redirecting for new test"),this.redirect(l)),c}}return!1}finally{this.includeInDomTests(),this.saveState()}}includeInDomTests(){this.applyControlForAudienceFilteredPriceTests();const e=this.getDomTestsForCurrentUrl(),t=this.getVisitorDomHypothesis(e);for(const i of e){this.log("Evaluating dom test '%s'",i.id);const s=i.hypotheses.some(u=>u.type==="price");if(this.state.essential.visitorTests.find(u=>u.testId===i.id&&u.isInvalid&&!u.hypothesisId)){if(this.log("Visitor is blocked from test '%s', applying control prices if price test",i.id),s){const u=i.hypotheses.find(b=>b.isControl);u?.priceData&&(this.applyPriceTestWithMapLookup(i.id,u,[u],()=>{this.log("Control prices applied for blocked visitor, no metrics tracked")}),this.updatePriceTestHiddenInputs(i.id,"control",!1))}continue}const n=this.getReservationForTest(i.id);let o=null,l=!1;const c=t.find(u=>i.hypotheses.some(b=>u.id===b.id));if(n)o=this.getHypothesis(n.hypothesisId)??null,this.log("Using reserved hypothesis '%s' for test '%s'",n.hypothesisId,i.id);else if(c)o=c,this.log("Using existing hypothesis assignment for test '%s'",i.id);else if(s){const u=this.visitorActiveTestTypeWithReservations();u?(l=!0,this.log("Visitor already in test type '%s', treating as non-test for price test '%s'",u,i.id)):o=this.pickHypothesis(i)}else o=this.pickHypothesis(i);if(l&&s){const u=i.hypotheses.find(b=>b.isControl);u?.priceData&&(this.log("Applying control prices for non-test visitor on price test '%s' (Map-based)",i.id),this.applyPriceTestWithMapLookup(i.id,u,[u],()=>{this.log("Control prices applied for non-test visitor, no metrics tracked")}),this.updatePriceTestHiddenInputs(i.id,"control",!1));continue}if(!o){this.log("Failed to pick hypothesis for test");continue}this.sendDiagnosticTelemetry("assignment",i.id,{hypothesisId:o.id,isControl:o.isControl,testType:o.type});const d=i.bayesianRevision??4,p=o.type==="price",h=d>=5;if(p&&h){if(this.log(`Price test with Map-based lookup (v${d}): ${i.id}`),!o.priceData){this.log("No price data for hypothesis '%s', skipping",o.id);continue}const u=o.isControl?"control":"variant";this.log(`Setting up Map-based price test for ${u} (test: ${i.id})`),this.applyPriceTestWithMapLookup(i.id,o,i.hypotheses,b=>{const E=this.getReservationForTest(b);E&&!E.isRealized&&E.entryCriteriaKey?this.realizeReservationForCriteria(E.entryCriteriaKey):this.queueAddVisitorToTest(b,o),this.saveState(),this.queuePageView(window.location.pathname),this.syncAllEvents()});continue}if(p&&!h){this.log(`Price test without viewport tracking (v${d}): ${i.id}`);const u=this.getDomSelectorsForHypothesis(o);if(u.length===0)continue;U(document,{testId:i.id,hypothesisId:o.id,selectors:u},b=>{this.queueAddVisitorToTest(b,o),this.saveState(),this.queuePageView(window.location.pathname),this.syncAllEvents()});continue}if(!o.domSelectors||o.domSelectors.length===0){this.log("No selectors found, skipping hypothesis");continue}U(document,{testId:i.id,hypothesisId:o.id,selectors:o.domSelectors},u=>{this.queueAddVisitorToTest(u,o),this.saveState(),this.queuePageView(window.location.pathname),this.syncAllEvents()})}}considerRedirect(e){if(this.log("Considering redirect for hypothesis '%s'",e.id),e.isControl)return this.log("Skipping redirect for control"),!1;if(e.type==="basicScript"||e.type==="manualScript")return this.log("Skipping redirect for script test"),!1;const t=this.state.essential.visitorTests.find(n=>n.hypothesisId===e.id),i=new URL(window.location.toString()),r=new URLSearchParams(window.location.search).get("view");if(e.type==="theme"){if(!(e.themeId===themeId)){if(this.log("Theme id '%s' is not hypothesis theme ID '%s'",e.themeId,themeId),this.isAppProxyPath())return this.log("On App Proxy path, skipping theme redirect to avoid infinite loop"),!1;if(t&&t.themeId!==e.themeId&&(t.themeId===themeId||!this.isThemePreview()))this.log("On old theme, redirecting and updating local visitor"),t.themeId=e.themeId;else if(this.isThemePreview())return this.log("On non-test theme, skipping redirect"),!1;return this.log("Hiding page to redirect for theme test"),this.hidePage(),!0}return!1}else if(e.type!=="dom"&&e.type!=="price"&&e.affix!==template.suffix&&e.affix!==r||e.redirectPath&&!i.pathname.endsWith(e.redirectPath))return this.log("Hiding page to redirect for template test"),this.hidePage(),!0;return this.log("Not redirecting"),!1}redirect(e){if(this.log("Redirecting to hypothesis '%s'",e.id),e.isControl)return;const t=new URL(window.location.toString());if(t.searchParams.delete("view"),e.redirectPath){const o=RegExp("^(/w{2}-w{2})/").exec(t.pathname);if(o&&o.length>1){const l=o[1];t.pathname=`${l}${e.redirectPath}`}else t.pathname=e.redirectPath}else e.type==="theme"?(t.searchParams.set("_ab","0"),t.searchParams.set("_fd","0"),t.searchParams.set("_sc","1"),t.searchParams.set("preview_theme_id",e.themeId.toString())):e.type!=="urlRedirect"&&t.searchParams.set("view",e.affix);const i=this.state.essential.visitorTests.find(o=>o.hypothesisId===e.id)?.testId,s=t.pathname+t.search,r=window.location.pathname+window.location.search,n=J(t.hash);if(i&&s!==r&&!n){const o=He(),l=Ne({v:2,t:i,n:o,fh:qe(window.location.pathname+window.location.search)});t.hash=`slr-${o}`;const c=new Date(Date.now()+3e4).toUTCString();document.cookie=`shoplift_redirect=${l};domain=.${window.location.hostname};path=/;SameSite=Strict;expires=${c}`}s===r&&this.showPage(),this.queueRedirect(t)}async refreshVisitor(e){if(e===null||!this.state.essential.isFirstLoad||!this.testConfigs.some(i=>i.visitorOption!=="all"))return;this.log("Refreshing visitor"),this.hidePage();const t=await this.getVisitor(e);t&&t.id&&this.updateLocalVisitor(t)}buildBaseVisitor(){return{shopifyAnalyticsId:this.shopifyAnalyticsId,device:this.device,country:null,...this.state.essential.initialState}}getInitialState(){const e=this.getUTMValue("utm_source")??"",t=this.getUTMValue("utm_medium")??"",i=this.getUTMValue("utm_campaign")??"",s=this.getUTMValue("utm_content")??"",r=window.document.referrer,n=this.device;return{createdAt:new Date,utmSource:e,utmMedium:t,utmCampaign:i,utmContent:s,referrer:r,device:n}}checkForThemePreview(){return this.log("Checking for theme preview"),window.location.hostname.endsWith(".shopifypreview.com")?(this.log("on shopify preview domain"),this.clearThemeBar(!0,!1,this.state),document.querySelector("#sl-preview-bar-hide")?.remove(),!1):this.isThemePreview()?this.state.essential.visitorTests.some(e=>e.isThemeTest&&e.hypothesisId!=null&&this.getHypothesis(e.hypothesisId)&&e.themeId===themeId)?(this.log("On active theme test, removing theme bar"),this.clearThemeBar(!1,!0,this.state),!1):this.state.essential.visitorTests.some(e=>e.isThemeTest&&e.hypothesisId!=null&&!this.getHypothesis(e.hypothesisId)&&e.themeId===themeId)?(this.log("Visitor is on an inactive theme test, redirecting to main theme"),this.redirectToMainTheme(),!0):this.state.essential.isFirstLoad?(this.log("No visitor found on theme preview, redirecting to main theme"),this.redirectToMainTheme(),!0):this.inactiveTestConfigs.some(e=>e.hypotheses.some(t=>t.themeId===themeId))?(this.log("Current theme is an inactive theme test, redirecting to main theme"),this.redirectToMainTheme(),!0):this.testConfigs.some(e=>e.hypotheses.some(t=>t.themeId===themeId))?(this.log("Falling back to clearing theme bar"),this.clearThemeBar(!1,!0,this.state),!1):(this.log("No tests on current theme, skipping script"),this.clearThemeBar(!0,!1,this.state),document.querySelector("#sl-preview-bar-hide")?.remove(),!0):(this.log("Not on theme preview"),this.clearThemeBar(!0,!1,this.state),!1)}redirectToMainTheme(){this.hidePage();const e=new URL(window.location.toString());e.searchParams.set("preview_theme_id",""),this.queueRedirect(e)}testsForUrl(e){const t=new URL(window.location.href),i=this.typeFromTemplate();return e.filter(s=>s.hypotheses.some(r=>r.type!=="dom"&&r.type!=="price"&&(r.isControl&&r.type===i&&r.affix===template.suffix||r.type==="theme"||r.isControl&&r.type==="urlRedirect"&&r.redirectPath&&t.pathname.endsWith(r.redirectPath)||r.type==="basicScript"))&&(s.ignoreTestViewParameterEnforcement||!t.searchParams.has("view")||s.hypotheses.map(r=>r.affix).includes(t.searchParams.get("view")??"")))}domTestsForUrl(e){const t=new URL(window.location.href);return e.filter(i=>i.hypotheses.some(s=>s.type!=="dom"&&s.type!=="price"?!1:s.type==="price"&&s.priceData&&s.priceData.variants.length>0?!0:s.domSelectors&&s.domSelectors.some(r=>new RegExp(re(r)).test(J(t.toString())))))}needsKlaviyo(e,t,i){return e.some(s=>s.requiresKlaviyo&&!t.some(r=>r.testId===s.id)&&this.matchesTestSettings(s,i,this.visitorCreatedDuringTestActive(s.statusHistory)))}getKlaviyoIdentity(){const e=ie(Fe(this.getCookie("__kla_id",document.cookie)));return{kx:ie(this.urlParams.get("_kx"))??(e?null:ie(new URL(this.state.temporary.entryPage??"",window.location.href).searchParams.get("_kx"))),exchangeId:e}}ensureKlaviyoMembership(){return this.klaviyoMembership??=this.resolveKlaviyoMembership().catch(e=>(this.log("Error resolving Klaviyo membership",e),{groups:[],known:!1})),this.klaviyoMembership}async resolveKlaviyoMembership(){const{kx:e,exchangeId:t}=this.getKlaviyoIdentity();if(!(e??t))return{groups:[],known:!1};this.log("Hiding page to resolve Klaviyo membership"),this.hidePage();const s=new URLSearchParams;e&&s.append("kx",e),t&&s.append("exchangeId",t);let r={groups:[],known:!1};try{const n=await this.makeJsonRequest({method:"get",url:`${this.host}/api/v1/storefront/klaviyo-groups/${encodeURIComponent(this.shop)}?${s}`,signal:AbortSignal.timeout(this.klaviyoGateTimeout)});r={groups:n?.groups??[],known:n?.known===!0}}catch(n){if(n instanceof G)return n;this.log("Error getting Klaviyo groups",n)}return r}async filterTestsByAudience(e,t,i){const s=[],r=e.some(l=>(l.requiresRegion||this.geoViaShopify&&l.requiresCountry)&&!i.some(c=>c.testId===l.id));this.resolvedRegion===null&&r&&(this.log("Hiding page to wait for Shopify region resolution"),this.hidePage(),await this.waitForResolvedRegion()),window.__slRegion=this.resolvedRegion??"";let n=t.country;this.geoViaShopify?n=this.resolvedRegion?this.resolvedRegion.slice(0,2):null:!n&&e.some(l=>l.requiresCountry&&!i.some(c=>c.testId===l.id))&&(this.log("Hiding page to check geoip"),this.hidePage(),n=await this.makeJsonRequest({method:"get",url:`${this.eventHost}/api/v0/visitors/get-country`,signal:AbortSignal.timeout(this.getCountryTimeout)}).catch(l=>(this.log("Error getting country",l),null)));let o={groups:[],known:!1};if(this.needsKlaviyo(e,i,t)){const l=await this.ensureKlaviyoMembership();if(l instanceof G)throw l;o=l}window.__slKlaviyoGroups=o.groups,window.__slKlaviyoKnown=o.known;for(const l of e){if(this.log("Checking audience for test '%s'",l.id),this.state.essential.visitorTests.some(p=>p.testId===l.id&&p.hypothesisId==null)){console.log(`Skipping blocked test '${l.id}'`);continue}const c=this.visitorCreatedDuringTestActive(l.statusHistory);(i.some(p=>p.testId===l.id&&(l.device==="all"||l.device===t.device&&l.device===this.device))||this.isTargetAudience(l,t,c,n))&&(this.log("Visitor is in audience for test '%s'",l.id),s.push(l))}this.testsFilteredByAudience=s}async waitForResolvedRegion(e=1500,t=50){const i=Date.now();for(;this.resolvedRegion===null&&Date.now()-i<e;)await new Promise(s=>window.setTimeout(s,t))}isTargetAudience(e,t,i,s){const r=this.getChannel(t);return this.matchesTestSettings(e,t,i)&&(e.targetAudiences.length===0||e.targetAudiences.reduce((n,o)=>n||o.reduce((l,c)=>l&&c(t,i,r,s),!0),!1))}matchesTestSettings(e,t,i){return(e.device==="all"||e.device===t.device&&e.device===this.device)&&(e.visitorOption==="all"||e.visitorOption==="new"&&i||e.visitorOption==="returning"&&!i)}visitorCreatedDuringTestActive(e){let t="";for(const i of e){if(this.state.analytics.visitor!==null&&this.state.analytics.visitor.createdAt<i.createdAt||this.state.essential.initialState.createdAt<i.createdAt)break;t=i.status}return t==="active"}getDomTestsForCurrentUrl(){return this.domTestsForUrl(this.testsFilteredByAudience)}getCurrentVisitorHypothesis(e){return e.flatMap(t=>t.hypotheses).find(t=>t.type!=="dom"&&t.type!=="price"&&this.state.essential.visitorTests.some(i=>i.hypothesisId===t.id))}getVisitorDomHypothesis(e){return e.flatMap(t=>t.hypotheses).filter(t=>(t.type==="dom"||t.type==="price")&&this.state.essential.visitorTests.some(i=>i.hypothesisId===t.id))}getHypothesis(e){return this.testConfigs.filter(t=>t.hypotheses.some(i=>i.id===e)).map(t=>t.hypotheses.find(i=>i.id===e))[0]}getActiveAssignment(){if(this.state.temporary.isMerchant&&this.state.temporary.previewConfig){const t=this.state.temporary.previewConfig;return t.currentVariant&&t.testId?{testId:t.testId,hypothesisId:t.currentVariant}:null}const e=this.state.essential.visitorTests.find(t=>t.hypothesisId);return e?.hypothesisId?{testId:e.testId,hypothesisId:e.hypothesisId}:null}findActiveSubscriptionTestControl(){for(const e of this.testConfigs){const t=e.hypotheses.find(i=>i.isControl);if(t?.subscriptionData)return{testId:e.id,hypothesis:t}}return null}getDomSelectorsForHypothesis(e){if(!e)return[];if(e.domSelectors&&e.domSelectors.length>0)return e.domSelectors;if(e.priceData){const t=`${this.priceSelectorsSessionKey}_${e.id}`;try{const s=sessionStorage.getItem(t);if(s){const r=JSON.parse(s);return e.domSelectors=r,this.log("Loaded %d price selectors from cache for hypothesis '%s'",r.length,e.id),r}}catch{}const i=Me(e.priceData);e.domSelectors=i;try{sessionStorage.setItem(t,JSON.stringify(i)),this.log("Generated and cached %d price selectors for hypothesis '%s'",i.length,e.id)}catch{this.log("Generated %d price selectors for hypothesis '%s' (cache unavailable)",i.length,e.id)}return i}return[]}hasThemeTest(e){return e.some(t=>t.hypotheses.some(i=>i.type==="theme"))}hasTestThatIsNotThemeTest(e){return e.some(t=>t.hypotheses.some(i=>i.type!=="theme"&&i.type!=="dom"&&i.type!=="price"))}hasThemeAndOtherTestTypes(e){return this.hasThemeTest(e)&&this.hasTestThatIsNotThemeTest(e)}testIsPaused(e){return e.status==="paused"||e.status==="incompatible"||e.status==="suspended"}visitorActiveTestType(){const e=this.state.essential.visitorTests.filter(t=>this.testConfigs.some(i=>i.hypotheses.some(s=>s.id==t.hypothesisId)));return e.length===0?null:e.some(t=>t.isThemeTest)?"theme":"templateOrUrlRedirect"}getReservationType(e){return e==="price"||this.isTemplateTestType(e)?"deferred":"immediate"}isTemplateTestType(e){return["product","collection","landing","index","cart","search","blog","article","collectionList"].includes(e)}getEntryCriteriaKey(e){const t=e.hypotheses.find(i=>i.isControl);if(!t)return`unknown:${e.id}`;switch(t.type){case"theme":return"global:theme";case"basicScript":return"global:autoApi";case"price":return"global:price";case"manualScript":return`conditional:manualApi:${e.id}`;case"urlRedirect":return`conditional:url:${t.redirectPath||"unknown"}`;default:return`conditional:template:${t.type}`}}isGlobalEntryCriteria(e){return e.startsWith("global:")}groupTestsByEntryCriteria(e){const t=new Map;for(const i of e){const s=this.getEntryCriteriaKey(i),r=t.get(s)||[];r.push(i),t.set(s,r)}return t}doesCurrentPageMatchEntryCriteria(e){if(this.isGlobalEntryCriteria(e))return!0;if(e==="conditional:manualApi")return!1;if(e.startsWith("conditional:url:")){const t=e.replace("conditional:url:","");return window.location.pathname.endsWith(t)}if(e.startsWith("conditional:template:")){const t=e.replace("conditional:template:","");return this.typeFromTemplate()===t}return!1}hasActiveReservation(){const e=this.getActiveReservations();return Object.values(e).some(t=>!t.isRealized)}getActiveReservation(){const e=this.getActiveReservations();return Object.values(e).find(t=>!t.isRealized)??null}clearStaleReservations(){const e=this.state.temporary.testReservations;if(!e)return;let t=!1;for(const[i,s]of Object.entries(e)){const r=this.testConfigs.find(o=>o.id===s.testId);if(!r){this.log("Test '%s' no longer in config, clearing reservation for criteria '%s'",s.testId,i),delete e[i],t=!0;continue}if(r.status!=="active"){this.log("Test '%s' status is '%s', clearing reservation for criteria '%s'",s.testId,r.status,i),delete e[i],t=!0;continue}this.testsFilteredByAudience.some(o=>o.id===s.testId)||(this.log("Visitor no longer passes audience for test '%s', clearing reservation for criteria '%s'",s.testId,i),delete e[i],t=!0)}t&&this.persistTemporaryState()}createReservations(e){if(this.state.temporary.testReservations||(this.state.temporary.testReservations={}),this.state.temporary.rolledEntryCriteria||(this.state.temporary.rolledEntryCriteria=[]),this.state.temporary.testCategory==="global"){this.createSingleReservation(e,"global");return}const i=e.filter(o=>this.doesCurrentPageMatchEntryCriteria(this.getEntryCriteriaKey(o))),s=e.filter(o=>!this.doesCurrentPageMatchEntryCriteria(this.getEntryCriteriaKey(o)));this.log("Conditional tests split - matching current page: %d, not matching: %d",i.length,s.length),i.length>0&&this.log("Tests matching current page (same pool): %o",i.map(o=>({id:o.id,title:o.title,criteria:this.getEntryCriteriaKey(o)})));const r=`conditional:current-page:${this.typeFromTemplate()}`;if(i.length>0&&!this.state.temporary.rolledEntryCriteria.includes(r)){this.createSingleReservation(i,r);for(const o of i){const l=this.getEntryCriteriaKey(o);this.state.temporary.rolledEntryCriteria.includes(l)||this.state.temporary.rolledEntryCriteria.push(l)}}const n=this.groupTestsByEntryCriteria(s);for(const[o,l]of n){if(this.state.temporary.rolledEntryCriteria.includes(o)){this.log("Already rolled for criteria '%s', skipping",o);continue}if(l.some(S=>this.state.essential.visitorTests.some(C=>C.testId===S.id))){this.log("Visitor already has VT for criteria '%s', skipping",o),this.state.temporary.rolledEntryCriteria.push(o);continue}const d=[...l].sort((S,C)=>S.id.localeCompare(C.id));this.log("Test dice roll for criteria '%s' - available tests: %o",o,d.map(S=>({id:S.id,title:S.title})));const p=Math.floor(Math.random()*d.length),h=d[p];this.log("Test dice roll: picked index %d of %d, selected test '%s' (%s)",p+1,l.length,h.id,h.title);const u=this.pickHypothesis(h);if(!u){this.log("No hypothesis picked for test '%s'",h.id);continue}this.sendDiagnosticTelemetry("assignment",h.id,{hypothesisId:u.id,isControl:u.isControl,testType:u.type});const b=this.getReservationType(u.type),E={testId:h.id,hypothesisId:u.id,testType:u.type,reservationType:b,isThemeTest:u.type==="theme",themeId:u.themeId,createdAt:new Date,isRealized:!1,entryCriteriaKey:o};this.state.temporary.testReservations[o]=E,this.state.temporary.rolledEntryCriteria.push(o),this.log("Created %s reservation for test '%s' (criteria: %s)",b,h.id,o);for(const S of l)S.id!==h.id&&this.markTestAsBlocked(S,o)}this.persistTemporaryState()}createSingleReservation(e,t){if(this.state.temporary.rolledEntryCriteria.includes(t)){this.log("Already rolled for pool '%s', skipping",t);return}if(e.some(p=>this.state.essential.visitorTests.some(h=>h.testId===p.id&&!h.isInvalid))){this.log("Visitor already has VT for pool '%s', skipping",t),this.state.temporary.rolledEntryCriteria.push(t);return}if(e.length===0){this.log("No tests in pool '%s'",t);return}const s=[...e].sort((p,h)=>p.id.localeCompare(h.id));this.log("Test dice roll for pool '%s' - available tests: %o",t,s.map(p=>({id:p.id,title:p.title,criteria:this.getEntryCriteriaKey(p)})));const r=Math.floor(Math.random()*s.length),n=s[r];this.log("Test dice roll: picked index %d of %d, selected test '%s' (%s)",r,e.length,n.id,n.title);const o=this.pickHypothesis(n);if(!o){this.log("No hypothesis picked for test '%s'",n.id);return}this.sendDiagnosticTelemetry("assignment",n.id,{hypothesisId:o.id,isControl:o.isControl,testType:o.type});const l=this.getReservationType(o.type),c=this.getEntryCriteriaKey(n),d={testId:n.id,hypothesisId:o.id,testType:o.type,reservationType:l,isThemeTest:o.type==="theme",themeId:o.themeId,createdAt:new Date,isRealized:!1,entryCriteriaKey:c};this.state.temporary.testReservations[c]=d,this.state.temporary.rolledEntryCriteria.push(t),this.log("Created %s reservation for test '%s' from pool '%s' (criteria: %s)",l,n.id,t,c);for(const p of e)p.id!==n.id&&this.markTestAsBlocked(p,`pool:${t}`);this.persistTemporaryState()}markTestAsBlocked(e,t){this.state.essential.visitorTests.some(i=>i.testId===e.id)||(this.log("Blocking visitor from test '%s' (reason: %s)",e.id,t),this.state.essential.visitorTests.push({createdAt:new Date,testId:e.id,hypothesisId:null,isThemeTest:e.hypotheses.some(i=>i.type==="theme"),shouldSendToGa:!1,isSaved:!0,isInvalid:!0,themeId:void 0}))}realizeReservationForCriteria(e){const t=this.state.temporary.testReservations?.[e];if(!t)return this.log("No reservation found for criteria '%s'",e),!1;if(t.isRealized)return this.log("Reservation already realized for criteria '%s'",e),!1;if(this.state.essential.visitorTests.some(s=>s.testId===t.testId&&!s.isInvalid))return this.log("Visitor already assigned to test '%s'",t.testId),!1;const i=this.getHypothesis(t.hypothesisId);return i?(t.isRealized=!0,this.persistTemporaryState(),this.queueAddVisitorToTest(t.testId,i),this.saveState(),this.log("Realized reservation for test '%s' (criteria: %s)",t.testId,e),!0):(this.log("Hypothesis '%s' not found",t.hypothesisId),!1)}getActiveReservations(){return this.state.temporary.testReservations??{}}getReservationForCurrentPage(){const e=this.getActiveReservations();for(const[t,i]of Object.entries(e)){if(i.isRealized)continue;const s=this.testConfigs.find(r=>r.id===i.testId);if(!(!s||s.status!=="active")&&this.doesCurrentPageMatchEntryCriteria(t))return i}return null}getReservationForTest(e){const t=this.getActiveReservations();return Object.values(t).find(i=>i.testId===e)??null}getReservationTestType(){const e=this.getActiveReservations(),t=Object.values(e);if(t.length===0)return null;for(const i of t)if(i.isThemeTest)return"theme";for(const i of t)if(i.testType==="price")return"price";return t.some(i=>!i.isRealized)?"templateOrUrlRedirect":null}hasPriceTests(e){return e.some(t=>t.hypotheses.some(i=>i.type==="price"))}_priceTestProductIds=null;getPriceTestProductIds(){if(this._priceTestProductIds)return this._priceTestProductIds;const e=new Set;for(const t of this.testConfigs)for(const i of t.hypotheses)if(i.type==="price"){for(const s of i.domSelectors||[]){const r=s.cssSelector.match(/data-sl-attribute-(?:p|cap)="(\d+)"/);r?.[1]&&e.add(r[1])}if(i.priceData?.variants)for(const[s]of i.priceData.variants)e.add(s)}return this._priceTestProductIds=e,this.log("Built price test product ID cache with %d products",e.size),e}isProductInAnyPriceTest(e){return this.getPriceTestProductIds().has(e)}visitorActiveTestTypeWithReservations(){const e=this.getActiveReservations();for(const r of Object.values(e)){if(r.isThemeTest)return"theme";if(r.testType==="price")return"price"}if(Object.values(e).some(r=>!r.isRealized)){if(this.state.temporary.testCategory==="global")for(const n of Object.values(e)){if(n.testType==="theme")return"theme";if(n.testType==="price")return"price";if(n.testType==="basicScript")return"theme"}return"templateOrUrlRedirect"}const i=this.state.essential.visitorTests.filter(r=>!r.isInvalid&&this.testConfigs.some(n=>n.hypotheses.some(o=>o.id===r.hypothesisId)));return i.length===0?null:i.some(r=>this.getHypothesis(r.hypothesisId)?.type==="price")?"price":i.some(r=>r.isThemeTest)?"theme":"templateOrUrlRedirect"}applyControlForAudienceFilteredPriceTests(){const e=this.testConfigs.filter(s=>s.status==="active"&&s.hypotheses.some(r=>r.type==="price"));if(e.length===0)return;const t=this.testsFilteredByAudience.filter(s=>s.hypotheses.some(r=>r.type==="price")),i=e.filter(s=>!t.some(r=>r.id===s.id));if(i.length!==0){this.log("Found %d price tests filtered by audience, applying control selectors",i.length);for(const s of i){const r=s.hypotheses.find(c=>c.isControl),n=this.getDomSelectorsForHypothesis(r);if(n.length===0){this.log("No control selectors for audience-filtered price test '%s'",s.id);continue}const o=new URL(window.location.href);n.some(c=>{try{return new RegExp(re(c)).test(J(o.toString()))}catch{return!1}})&&(this.log("Applying control selectors for audience-filtered price test '%s'",s.id),U(document,{testId:s.id,hypothesisId:r.id,selectors:n},()=>{}),this.updatePriceTestHiddenInputs(s.id,"control",!1))}}}pickHypothesis(e){let t=Math.random();const i=e.hypotheses.reduce((r,n)=>r+n.visitorCount,0);return e.hypotheses.sort((r,n)=>r.isControl?n.isControl?0:-1:n.isControl?1:0).reduce((r,n)=>{if(r!==null)return r;const l=e.hypotheses.reduce((c,d)=>c&&d.visitorCount>20,!0)?n.visitorCount/i-n.trafficPercentage:0;return t<=n.trafficPercentage-l?n:(t-=n.trafficPercentage-l,null)},null)}typeFromTemplate(){switch(template.type){case"list-collections":return"collectionList";case"page":return"landing";case"article":case"blog":case"cart":case"collection":case"index":case"product":case"search":return template.type;default:return null}}queueRedirect(e){this.saveState(),this.disableReferrerOverride||(this.log(`Saving temporary referrer override '${document.referrer}'`),this.state.temporary.originalReferrer=document.referrer,this.persistTemporaryState()),window.setTimeout(()=>window.location.assign(e),0),window.setTimeout(()=>{this.syncAllEvents()},2e3)}scheduleRetrySync(){this.clientIdRetryCount>=5||(this.clientIdRetryCount++,window.setTimeout(()=>{this.syncAllEvents()},500))}async syncAllEvents(){const e=async()=>{if(this.isSyncing){window.setTimeout(()=>{(async()=>await e())()},500);return}try{if(this.isSyncing=!0,this.syncGAEvents(),this.shopifyAnalyticsId||(this.shopifyAnalyticsId=this.getShopifyAnalyticsId()),!this.shopifyAnalyticsId){this.scheduleRetrySync();return}await this.syncEvents()}finally{this.isSyncing=!1}};await e()}async syncEvents(){if(!this.state.essential.consentApproved||!this.shopifyAnalyticsId||this.state.analytics.queue.length===0)return;const e=this.state.analytics.queue.length,t=this.state.analytics.queue.splice(0,e);this.log("Syncing %s events",e);try{const i={shopifyAnalyticsId:this.shopifyAnalyticsId,device:this.state.analytics.visitor?.device??this.device,country:this.state.analytics.visitor?.country??null,...this.state.essential.initialState},s={shop:this.shop,visitorDetails:{...i,visitorId:this.savedVisitorIdFor(i.shopifyAnalyticsId)},events:this.state.essential.visitorTests.filter(n=>!n.isInvalid&&!n.isSaved&&n.hypothesisId!=null).map(n=>new Se(n.testId,n.hypothesisId,n.createdAt)).concat(t)};await this.sendEvents(s);for(const n of this.state.essential.visitorTests.filter(o=>!o.isInvalid&&!o.isSaved&&o.hypothesisId!=null))this.sendDiagnosticTelemetry("event-delivered",n.testId,{hypothesisId:n.hypothesisId,isControl:n.assignedTo==="control",testType:n.testType??"unknown"});const r=await this.getVisitor(this.shopifyAnalyticsId);r!==null&&this.updateLocalVisitor(r);for(const n of this.state.essential.visitorTests.filter(o=>!o.isInvalid&&!o.isSaved))n.isSaved=!0,n.savedAt=Date.now()}catch{this.state.analytics.queue.splice(0,0,...t)}finally{this.saveState()}}syncGAEvents(){if(!this.gaConfig.sendEvents){if(fe)return;fe=!0,this.log("UseGtag is false — skipping GA Events");return}if(this.isSyncingGA){this.log("Already syncing GA - skipping GA events");return}const e=this.state.essential.visitorTests.filter(t=>t.shouldSendToGa);e.length!==0&&(this.isSyncingGA=!0,this.log("Syncing %s GA Events",e.length),Promise.allSettled(e.map(t=>this.sendGAEvent(t))).then(()=>this.log("All gtag events sent")).finally(()=>this.isSyncingGA=!1))}sendGAEvent(e){return new Promise(t=>{this.log("Sending GA Event for test %s, hypothesis %s",e.testId,e.hypothesisId);const i=()=>{this.log("GA acknowledged event for hypothesis %s",e.hypothesisId),e.shouldSendToGa=!1,this.persistEssentialState(),t()},s={exp_variant_string:`SL-${e.testId}-${e.hypothesisId}`};this.shopliftDebug&&Object.assign(s,{debug_mode:!0});function r(n,o,l){window.dataLayer=window.dataLayer||[],window.dataLayer.push(arguments)}this.gaConfig.mode==="gtag"?r("event","experience_impression",{...s,event_callback:i}):(window.dataLayer=window.dataLayer||[],window.dataLayer.push({event:"experience_impression",...s,eventCallback:i}))})}updateLocalVisitor(e){let t;({visitorTests:t,...this.state.analytics.visitor}=e),this.log("updateLocalVisitor - server returned %d tests: %o",t.length,t.map(s=>({testId:s.testId,hypothesisId:s.hypothesisId,isInvalid:s.isInvalid}))),this.log("updateLocalVisitor - local has %d tests: %o",this.state.essential.visitorTests.length,this.state.essential.visitorTests.map(s=>({testId:s.testId,hypothesisId:s.hypothesisId,isSaved:s.isSaved,isInvalid:s.isInvalid})));const i=300*1e3;for(const s of this.state.essential.visitorTests.filter(r=>r.isSaved&&(!r.savedAt||Date.now()-r.savedAt>i)&&!t.some(n=>n.testId===r.testId)))this.log("updateLocalVisitor - marking LOCAL test as INVALID (isSaved && not in server): testId=%s, hypothesisId=%s",s.testId,s.hypothesisId),s.isInvalid=!0;for(const s of t){const r=this.state.essential.visitorTests.findIndex(o=>o.testId===s.testId);if(!(r!==-1))this.log("updateLocalVisitor - ADDING server test (not found locally): testId=%s, hypothesisId=%s",s.testId,s.hypothesisId),this.state.essential.visitorTests.push(s);else{const o=this.state.essential.visitorTests.at(r);this.log("updateLocalVisitor - REPLACING local test with server test: testId=%s, local hypothesisId=%s -> server hypothesisId=%s, local isInvalid=%s -> false",s.testId,o?.hypothesisId,s.hypothesisId,o?.isInvalid),s.isInvalid=!1,s.shouldSendToGa=o?.shouldSendToGa??!1,s.testType=o?.testType,s.assignedTo=o?.assignedTo,s.testTitle=o?.testTitle,this.state.essential.visitorTests.splice(r,1,s)}}this.log("updateLocalVisitor - FINAL local tests: %o",this.state.essential.visitorTests.map(s=>({testId:s.testId,hypothesisId:s.hypothesisId,isSaved:s.isSaved,isInvalid:s.isInvalid}))),this.state.analytics.visitor.storedAt=new Date}savedVisitorIdFor(e){const t=this.state.analytics.visitor;return t?.id&&t.shopifyAnalyticsId===this.shopifyAnalyticsId&&e===this.shopifyAnalyticsId?t.id:null}async getVisitor(e){try{return await this.makeJsonRequest({method:"get",url:`${this.eventHost}/api/v0/visitors/by-key/${this.shop}/${e}`})}catch{return null}}async sendEvents(e){await this.makeRequest({method:"post",url:`${this.eventHost}/api/v0/events`,data:JSON.stringify(e)})}sendDiagnosticTelemetry(e,t,i){if(!this.telemetryEnabled||!navigator.sendBeacon)return;const s=this.state.essential.consentApproved,r=JSON.stringify({shop:this.shop,testId:t,checkpoint:e,device:this.device,...s?{visitorId:this.shopifyAnalyticsId??"unknown"}:{},clientTimestamp:Date.now(),consentApproved:s,hasConsentInteraction:this.state.essential.hasConsentInteraction,...i});navigator.sendBeacon(`${this.eventHost}/api/v0/telemetry`,new Blob([r],{type:"text/plain"}))}getUTMValue(e){return new URLSearchParams(window.location.search).get(e)||null}hidePage(e){this.log("Hiding page"),this.cssHideClass&&!window.document.documentElement.classList.contains(this.cssHideClass)&&(window.document.documentElement.classList.add(this.cssHideClass),e||setTimeout(this.removeAsyncHide(this.cssHideClass),2e3))}showPage(){this.cssHideClass&&this.removeAsyncHide(this.cssHideClass)()}getDeviceType(){function e(){let i=!1;return(function(s){(/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino/i.test(s)||/1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test(s.substr(0,4)))&&(i=!0)})(navigator.userAgent||navigator.vendor),i}function t(){let i=!1;return(function(s){(/android|ipad|playbook|silk/i.test(s)||/1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test(s.substr(0,4)))&&(i=!0)})(navigator.userAgent||navigator.vendor),i}return e()?"mobile":t()?"tablet":"desktop"}removeAsyncHide(e){return()=>{e&&window.document.documentElement.classList.remove(e)}}async getCartState(){try{let e=await this.makeJsonRequest({method:"get",url:`${window.location.origin}/cart.js`});return e===null||(e.note===null&&(e=await this.makeJsonRequest({method:"post",url:`${window.location.origin}/cart/update.js`,data:JSON.stringify({note:""})})),e==null)?null:{token:e.token,total_price:e.total_price,total_discount:e.total_discount,currency:e.currency,items_subtotal_price:e.items_subtotal_price,items:e.items.map(t=>({quantity:t.quantity,variant_id:t.variant_id,key:t.key,price:t.price,final_line_price:t.final_line_price,sku:t.sku,product_id:t.product_id}))}}catch(e){return this.log("Error sending cart info",e),null}}ensureCartAttributesForExistingPriceTests(e){try{if(this.log("Checking visitor assignments for active price tests"),e&&this.state.temporary.previewConfig){const t=this.state.temporary.previewConfig;this.log("Using preview config for merchant:",t.testId);let i="variant";if(t.variants&&t.variants.length>0){const s=t.variants.find(r=>r.id===t.currentVariant);s&&s.isControl&&(i="control")}this.log("Merchant preview - updating hidden inputs:",t.testId,i),this.updatePriceTestHiddenInputs(t.testId,i,!0);return}for(const t of this.state.essential.visitorTests){const i=this.testConfigs.find(n=>n.id===t.testId);if(!i){this.log("Test config not found:",t.testId);continue}const s=i.hypotheses.find(n=>n.id===t.hypothesisId);if(!s||s.type!=="price")continue;const r=s.isControl?"control":"variant";this.log("Updating hidden inputs for price test:",t.testId,r),this.updatePriceTestHiddenInputs(t.testId,r,e)}}catch(t){this.log("Error ensuring cart attributes for existing price tests:",t)}}subscriptionSwapDone=!1;subscriptionHideWrongPlans=null;subscriptionPriceDone=!1;subscriptionUpdateOneTime=null;subscriptionOneTimeDone=!1;swapMap=null;slptValue=null;async subscriptionSwap(){await ze(this)}async subscriptionPriceChange(){await Ge(this)}async subscriptionOneTimePrice(){await je(this)}updatePriceTestHiddenInputs(e,t,i){try{this.cleanupPriceTestObservers();const s=`${e}:${t}:${i?"t":"f"}`,r=T=>{const m=T.getAttribute("data-sl-pid");if(!m)return!0;if(i&&this.state.temporary.previewConfig){const w=this.state.temporary.previewConfig,I=t==="control"?"a":"b",f=w.variants.find(v=>v.label===I);if(!f)return!1;for(const v of f.domSelectors||[]){const g=v.cssSelector.match(/data-sl-attribute-(?:p|cap)="(\d+)"/);if(g){const P=g[1];if(this.log(`Extracted ID from selector: ${P}, comparing to: ${m}`),P===m)return this.log("Product ID match found in preview config:",m,"variant:",f.label),!0}else this.log(`Could not extract ID from selector: ${v.cssSelector}`)}return this.log("No product ID match in preview config for:",m,"variant:",I),!1}const y=this.testConfigs.find(w=>w.id===e);if(!y)return this.log("Test config not found for testId:",e),!1;for(const w of y.hypotheses||[]){for(const I of w.domSelectors||[]){const f=I.cssSelector.match(/data-sl-attribute-(?:p|cap)="(\d+)"/);if(f&&f[1]===m)return this.log("Product ID match found in domSelectors:",m,"for test:",e),!0}if(w.priceData?.variants){for(const I of w.priceData.variants)if(I[0]===m)return this.log("Product ID match found in priceData:",m,"for test:",e),!0}}return this.log("No product ID match for:",m,"in test:",e),!1},n=new Set;let o=!1,l=null;const c=(T,m)=>{if(document.querySelectorAll("[data-sl-attribute-p]").forEach(w=>{if(w instanceof Element&&w.nodeType===Node.ELEMENT_NODE&&w.isConnected&&document.contains(w))try{T.observe(w,{childList:!0,subtree:!0,characterData:!0,characterDataOldValue:!0,attributes:!1})}catch(I){this.log(`Failed to observe element (${m}):`,I)}}),document.body&&document.body.isConnected)try{T.observe(document.body,{childList:!0,subtree:!0,characterData:!0,characterDataOldValue:!0,attributes:!1})}catch(w){this.log(`Failed to observe document.body (${m}):`,w)}},d=(T,m,y,w)=>{const I=T.filter(f=>{const v=f.cssSelector.match(/data-sl-attribute-(?:p|cap)="(\d+)"/);return v&&v[1]===w});this.log(`Applying ${y} DOM selectors, total: ${T.length}, filtered: ${I.length}`),I.length>0&&U(document,{testId:e,hypothesisId:m,selectors:I})},p=(T,m)=>{this.log(`Applying DOM selector changes for product ID: ${T}`),m.disconnect(),o=!0;try{if(i&&this.state.temporary.previewConfig){const y=t==="control"?"a":"b",w=this.state.temporary.previewConfig.variants.find(I=>I.label===y);if(!w?.domSelectors){this.log(`No DOM selectors found for preview variant: ${y}`);return}d(w.domSelectors,w.id,"preview config",T)}else{const y=this.testConfigs.find(I=>I.id===e);if(!y){this.log(`No test config found for testId: ${e}`);return}const w=y.hypotheses.find(I=>t==="control"?I.isControl:!I.isControl);if(!w?.domSelectors){this.log(`No DOM selectors found for assignment: ${t}`);return}d(w.domSelectors,w.id,"live config",T)}}finally{l!==null&&clearTimeout(l),l=window.setTimeout(()=>{o=!1,l=null,c(m,"reconnection"),this.log("Re-established innerHTML observer after DOM changes")},50)}},h=new MutationObserver(T=>{if(!o)for(const m of T){if(m.type!=="childList"&&m.type!=="characterData")continue;let y=m.target;m.type==="characterData"&&(y=m.target.parentElement||m.target.parentNode);let w=y,I=w.getAttribute("data-sl-attribute-p");for(;!I&&w.parentElement;)w=w.parentElement,I=w.getAttribute("data-sl-attribute-p");if(!I)continue;const f=w.innerHTML||w.textContent||"";let v="";m.type==="characterData"&&m.oldValue!==null&&(v=m.oldValue),this.log(`innerHTML changed on element with data-sl-attribute-p="${I}"`),v&&this.log(`Previous content: "${v}"`),this.log(`Current content: "${f}"`),p(I,h)}});c(h,"initial setup"),n.add(h);const u=new MutationObserver(T=>{T.forEach(m=>{m.addedNodes.forEach(y=>{if(y.nodeType===Node.ELEMENT_NODE){const w=y;E(w);const I=w.matches('input[name="properties[_slpt]"]')?[w]:w.querySelectorAll('input[name="properties[_slpt]"]');I.length>0&&this.log(`MutationObserver found ${I.length} new hidden input(s)`),I.forEach(f=>{const v=f.getAttribute("data-sl-pid");if(this.log(`MutationObserver checking new input with data-sl-pid="${v}"`),r(f))f.value!==s&&(f.value=s,this.log("Updated newly added hidden input:",s)),S(f);else{const g=f.getAttribute("data-sl-pid");g&&this.isProductInAnyPriceTest(g)?this.log("Preserving hidden input for product ID '%s' - belongs to a different price test",g):(f.remove(),this.log("Removed newly added non-matching hidden input for product ID:",g))}})}})})});n.add(u);const b=new MutationObserver(T=>{T.forEach(m=>{if(m.type==="attributes"&&m.attributeName==="data-sl-pid"){const y=m.target;if(this.log("AttributeObserver detected data-sl-pid attribute change on:",y.tagName),y.matches('input[name="properties[_slpt]"]')){const w=y,I=m.oldValue,f=w.getAttribute("data-sl-pid");this.log(`data-sl-pid changed from "${I}" to "${f}" - triggering payment placement updates`),r(w)?(w.value!==s&&(w.value=s,this.log("Updated hidden input after data-sl-pid change:",s)),f&&p(f,h),this.log("Re-running payment placement updates after variant change"),E(document.body)):f&&this.isProductInAnyPriceTest(f)?this.log("Preserving hidden input for product ID '%s' - belongs to a different price test",f):(w.remove(),this.log("Removed non-matching hidden input after data-sl-pid change:",f))}}})});n.add(b);const E=T=>{T.tagName==="SHOPIFY-PAYMENT-TERMS"&&(this.log("MutationObserver found new shopify-payment-terms element"),this.updateShopifyPaymentTerms(e,t));const m=T.querySelectorAll("shopify-payment-terms");m.length>0&&(this.log(`MutationObserver found ${m.length} shopify-payment-terms in added node`),this.updateShopifyPaymentTerms(e,t)),T.tagName==="AFTERPAY-PLACEMENT"&&(this.log("MutationObserver found new afterpay-placement element"),this.updateAfterpayPlacements(e,t,"afterpay"));const y=T.querySelectorAll("afterpay-placement");y.length>0&&(this.log(`MutationObserver found ${y.length} afterpay-placement in added node`),this.updateAfterpayPlacements(e,t,"afterpay")),T.tagName==="SQUARE-PLACEMENT"&&(this.log("MutationObserver found new square-placement element"),this.updateAfterpayPlacements(e,t,"square"));const w=T.querySelectorAll("square-placement");w.length>0&&(this.log(`MutationObserver found ${w.length} square-placement in added node`),this.updateAfterpayPlacements(e,t,"square")),T.tagName==="KLARNA-PLACEMENT"&&(this.log("MutationObserver found new klarna-placement element"),this.updateKlarnaPlacements(e,t));const I=T.querySelectorAll("klarna-placement");I.length>0&&(this.log(`MutationObserver found ${I.length} klarna-placement in added node`),this.updateKlarnaPlacements(e,t))},S=T=>{b.observe(T,{attributes:!0,attributeFilter:["data-sl-pid"],attributeOldValue:!0,subtree:!1});const m=T.getAttribute("data-sl-pid");this.log(`Started AttributeObserver on specific input with data-sl-pid="${m}"`)},C=()=>{const T=document.querySelectorAll('input[name="properties[_slpt]"]');this.log(`Found ${T.length} existing hidden inputs to check`),T.forEach(m=>{const y=m.getAttribute("data-sl-pid");this.log(`Checking existing input with data-sl-pid="${y}"`),r(m)?(m.value=s,this.log("Updated existing hidden input:",s),y&&(this.log("Applying initial DOM selector changes for existing product"),p(y,h)),S(m)):y&&this.isProductInAnyPriceTest(y)?this.log("Preserving hidden input for product ID '%s' - belongs to a different price test",y):(m.remove(),this.log("Removed non-matching hidden input for product ID:",y))})},_=()=>{document.body?(u.observe(document.body,{childList:!0,subtree:!0}),this.log("Started MutationObserver on document.body"),C(),E(document.body)):document.readyState==="loading"?document.addEventListener("DOMContentLoaded",()=>{document.body&&(u.observe(document.body,{childList:!0,subtree:!0}),this.log("Started MutationObserver after DOMContentLoaded"),C(),E(document.body))}):(this.log("Set timeout on observer"),setTimeout(_,10))};_(),window.__shopliftPriceTestObservers=n,window.__shopliftPriceTestValue=s,this.log("Set up DOM observer for price test hidden inputs")}catch(s){this.log("Error updating price test hidden inputs:",s)}}updateKlarnaPlacements(e,t){this.updatePlacementElements(e,t,"klarna-placement",(i,s)=>{i.setAttribute("data-purchase-amount",s.toString())})}cleanupPriceTestObservers(){const e=window.__shopliftPriceTestObservers;e&&(e.forEach(t=>{t.disconnect()}),e.clear(),this.log("Cleaned up existing price test observers")),delete window.__shopliftPriceTestObservers,delete window.__shopliftPriceTestValue}updateAfterpayPlacements(e,t,i="afterpay"){const s=i==="square"?"square-placement":"afterpay-placement";if(document.querySelectorAll(s).length===0){this.log(`No ${s} elements found on page - early return`);return}this.updatePlacementElements(e,t,s,(n,o)=>{if(i==="afterpay"){const l=(o/100).toFixed(2);n.setAttribute("data-amount",l)}else n.setAttribute("data-amount",o.toString())}),this.log("updateAfterpayPlacements completed")}updatePlacementElements(e,t,i,s){const r=document.querySelectorAll(i);if(r.length===0){this.log(`No ${i} elements found - early return`);return}let n;if(this.state.temporary.isMerchant&&this.state.temporary.previewConfig){const l=t==="control"?"a":"b",c=this.state.temporary.previewConfig.variants.find(d=>d.label===l);if(!c?.domSelectors){this.log(`No variant found for label ${l} in preview config for ${i}`);return}n=c.domSelectors,this.log(`Using preview config for ${i} in merchant mode, variant: ${l}`)}else{const l=this.testConfigs.find(d=>d.id===e);if(!l){this.log(`No testConfig found for id: ${e} - early return`);return}const c=l.hypotheses.find(d=>t==="control"?d.isControl:!d.isControl);if(!c?.domSelectors){this.log(`No hypothesis or domSelectors found for assignment: ${t} - early return`);return}n=c.domSelectors}const o=new RegExp(`${this.DATA_SL_ATTRIBUTE_P}=["'](\\d+)["']`);r.forEach(l=>{let c=null;const d=l.parentElement;if(d&&(c=d.querySelector('input[name="properties[_slpt]"]')),c||(c=l.querySelector('input[name="properties[_slpt]"]')),!c){this.log(`No hidden input found for ${i} element`);return}const p=c.getAttribute("data-sl-pid");if(!p){this.log("Hidden input has no data-sl-pid attribute - skipping");return}const h=n.find(S=>{const C=S.cssSelector.match(o);return C&&C[1]===p});if(!h){this.log(`No matching selector found for productId: ${p} - skipping element`);return}const u=h.actions.find(S=>S.scope==="price");if(!u?.value){this.log("No price action or value found - skipping element");return}const b=parseFloat(u.value.replace(/[^0-9.]/g,""));if(Number.isNaN(b)){this.log(`Invalid price "${u.value}" for product ${p} - skipping`);return}const E=Math.round(b*100);s(l,E)}),this.log(`updatePlacementElements completed for ${i}`)}updateShopifyPaymentTerms(e,t){const i=document.querySelectorAll("shopify-payment-terms");if(i.length===0)return;this.log("Store using shopify payments");let s;if(this.state.temporary.isMerchant&&this.state.temporary.previewConfig){const n=t==="control"?"a":"b",o=this.state.temporary.previewConfig.variants.find(l=>l.label===n);if(!o||!o.domSelectors){this.log(`No variant found for label ${n} in preview config`);return}s=o.domSelectors,this.log(`Using preview config for shopify-payment-terms in merchant mode, variant: ${n}`)}else{const n=this.testConfigs.find(l=>l.id===e);if(!n)return;const o=n.hypotheses.find(l=>t==="control"?l.isControl===!0:l.isControl===!1);if(!o||!o.domSelectors)return;s=o.domSelectors}const r=new RegExp(`${this.DATA_SL_ATTRIBUTE_P}=["'](\\d+)["']`);i.forEach(n=>{const o=n.getAttribute("variant-id");if(!o)return;const l=s.find(c=>{const d=c.cssSelector.match(r);return d&&d[1]===o});if(l){const c=l.actions.find(d=>d.scope==="price");if(c&&c.value){const d=n.getAttribute("shopify-meta");if(d)try{const p=JSON.parse(d);if(p.variants&&Array.isArray(p.variants)){const h=p.variants.find(u=>u.id?.toString()===o);if(h){h.full_price=c.value;const u=parseFloat(c.value.replace(/[^0-9.]/g,""));if(h.number_of_payment_terms&&h.number_of_payment_terms>1){const b=u/h.number_of_payment_terms;h.price_per_term=`$${b.toFixed(2)}`}n.setAttribute("shopify-meta",JSON.stringify(p))}}}catch(p){this.log("Error parsing/updating shoplift-meta:",p)}}}})}async makeJsonRequest(e){const t=await this.makeRequest(e);return t===null?null:JSON.parse(await t.text(),F)}async makeRequest(e){const{url:t,method:i,headers:s,data:r,signal:n}=e,o=new Headers;if(s)for(const c in s)o.append(c,s[c]);(!s||!s.Accept)&&o.append("Accept","application/json"),r!==void 0&&(!s||!s["Content-Type"])&&o.append("Content-Type","application/json"),(this.eventHost.includes("ngrok.io")||this.eventHost.includes("ngrok-free.app"))&&o.append("ngrok-skip-browser-warning","1234");const l=await this.fetch(t,{method:i,headers:o,body:r,signal:n});if(!l.ok){if(l.status===204)return null;if(l.status===422){const c=await l.json();if(typeof c<"u"&&c.isBot)throw new G}throw new Error(`Error sending shoplift request ${l.status}`)}return l}queueAddVisitorToTest(e,t){if(this.state.essential.visitorTests.some(s=>s.testId===e))return;const i=this.testConfigs.find(s=>s.id===e);if(this.state.essential.visitorTests.push({createdAt:new Date,testId:e,hypothesisId:t.id,isThemeTest:t.type==="theme",themeId:t.themeId,isSaved:!1,isInvalid:!1,shouldSendToGa:!0,testType:t.type,assignedTo:t.isControl?"control":"variant",testTitle:i?.title}),t.type==="price"){const s=t.isControl?"control":"variant";this.log("Price test assignment detected, updating cart attributes:",e,s),this.updatePriceTestHiddenInputs(e,s,!1)}}queueCartUpdate(e){this.queueEvent(new Te(e))}queuePageView(e){this.queueEvent(new Ce(e))}queueEvent(e){!this.state.essential.consentApproved&&this.state.essential.hasConsentInteraction||this.state.analytics.queue.length>10||this.state.analytics.queue.push(e)}legacyGetLocalStorageVisitor(){const e=this.localStorageGet(this.legacySessionKey);if(e)try{return JSON.parse(e,F)}catch{}return null}pruneStaleVisitorTests(){this.state.essential.visitorTests=this.state.essential.visitorTests.filter(e=>this.testConfigs.some(t=>t.id==e.testId)||this.inactiveTestConfigs.filter(t=>this.testIsPaused(t)).some(t=>t.id===e.testId))}pruneStateAndSave(){this.pruneStaleVisitorTests(),this.saveState()}saveState(){this.persistEssentialState(),this.persistAnalyticsState()}loadState(){const e=this.loadAnalyticsState(),t={analytics:e,essential:this.loadEssentialState(e),temporary:this.loadTemporaryState()},i=this.legacyGetLocalStorageVisitor(),s=this.legacyGetCookieVisitor(),r=[i,s].filter(n=>n!==null).sort((n,o)=>+o.storedAt-+n.storedAt)[0];return t.analytics.visitor===null&&r&&({visitorTests:t.essential.visitorTests,...t.analytics.visitor}=r,t.essential.isFirstLoad=!1,t.essential.initialState={createdAt:r.createdAt,referrer:r.referrer,utmCampaign:r.utmCampaign,utmContent:r.utmContent,utmMedium:r.utmMedium,utmSource:r.utmSource,device:r.device},this.deleteCookie("SHOPLIFT"),this.deleteLocalStorage(this.legacySessionKey)),!t.essential.consentApproved&&t.essential.hasConsentInteraction&&this.deleteLocalStorage(this.analyticsSessionKey),t}loadEssentialState(e){const t=this.loadLocalStorage(this.essentialSessionKey),i=this.loadCookie(this.essentialSessionKey),s=this.getInitialState();e.visitor?.device&&(s.device=e.visitor.device);const r={timestamp:new Date,consentApproved:!1,hasConsentInteraction:!1,debugMode:!1,initialState:s,visitorTests:[],isFirstLoad:!0},n=[t,i].filter(o=>o!==null).sort((o,l)=>+l.timestamp-+o.timestamp)[0]??r;return n.initialState||(e.visitor!==null?n.initialState=e.visitor:(n.initialState=s,n.initialState.createdAt=n.timestamp)),n}loadAnalyticsState(){const e=this.loadLocalStorage(this.analyticsSessionKey),t=this.loadCookie(this.analyticsSessionKey),i={timestamp:new Date,visitor:null,queue:[]},s=[e,t].filter(r=>r!==null).sort((r,n)=>+n.timestamp-+r.timestamp)[0]??i;return s.queue.length===0&&e&&e.queue.length>1&&(s.queue=e.queue),s}loadTemporaryState(){const e=this.sessionStorageGet(this.temporarySessionKey),t=e?JSON.parse(e,F):null,i=this.loadCookie(this.temporarySessionKey);return t??i??{isMerchant:!1,timestamp:new Date}}persistEssentialState(){this.log("Persisting essential state"),this.state.essential.isFirstLoad=!1,this.state.essential.timestamp=new Date,this.persistLocalStorageState(this.essentialSessionKey,this.state.essential),this.persistCookieState(this.essentialSessionKey,this.state.essential)}persistAnalyticsState(){this.log("Persisting analytics state"),this.state.essential.consentApproved&&(this.state.analytics.timestamp=new Date,this.persistLocalStorageState(this.analyticsSessionKey,this.state.analytics),this.persistCookieState(this.analyticsSessionKey,{...this.state.analytics,queue:[]}))}persistTemporaryState(){this.log("Setting temporary session state"),this.state.temporary.timestamp=new Date,this.sessionStorageSet(this.temporarySessionKey,JSON.stringify(this.state.temporary)),this.persistCookieState(this.temporarySessionKey,this.state.temporary,!0)}loadLocalStorage(e){const t=this.localStorageGet(e);if(t===null)return null;try{return JSON.parse(t,F)}catch{return null}}loadCookie(e){const t=this.getCookie(e);if(t===null)return null;try{return JSON.parse(t,F)}catch{return null}}persistLocalStorageState(e,t){this.localStorageSet(e,JSON.stringify(t))}persistCookieState(e,t,i=!1){const s=JSON.stringify(t),r=i?"":`expires=${new Date(new Date().getTime()+864e5*365).toUTCString()};`;document.cookie=`${e}=${s};domain=.${window.location.hostname};path=/;SameSite=Strict;${r}`}deleteCookie(e){const t=new Date(0).toUTCString();document.cookie=`${e}=;domain=.${window.location.hostname};path=/;expires=${t};`}deleteLocalStorage(e){window.localStorage.removeItem(e)}getChannel(e){return[{"name":"cross-network","test":(v) => new RegExp(".*cross-network.*", "i").test(v.utmCampaign)},{"name":"direct","test":(v) => v.utmSource === "" && v.utmMedium === ""},{"name":"paid-shopping","test":(v) => (new RegExp("^(?:Google|IGShopping|aax-us-east\.amazon-adsystem\.com|aax\.amazon-adsystem\.com|alibaba|alibaba\.com|amazon|amazon\.co\.uk|amazon\.com|apps\.shopify\.com|checkout\.shopify\.com|checkout\.stripe\.com|cr\.shopping\.naver\.com|cr2\.shopping\.naver\.com|ebay|ebay\.co\.uk|ebay\.com|ebay\.com\.au|ebay\.de|etsy|etsy\.com|m\.alibaba\.com|m\.shopping\.naver\.com|mercadolibre|mercadolibre\.com|mercadolibre\.com\.ar|mercadolibre\.com\.mx|message\.alibaba\.com|msearch\.shopping\.naver\.com|nl\.shopping\.net|no\.shopping\.net|offer\.alibaba\.com|one\.walmart\.com|order\.shopping\.yahoo\.co\.jp|partners\.shopify\.com|s3\.amazonaws\.com|se\.shopping\.net|shop\.app|shopify|shopify\.com|shopping\.naver\.com|shopping\.yahoo\.co\.jp|shopping\.yahoo\.com|shopzilla|shopzilla\.com|simplycodes\.com|store\.shopping\.yahoo\.co\.jp|stripe|stripe\.com|uk\.shopping\.net|walmart|walmart\.com)$", "i").test(v.utmSource) || new RegExp("^(.*(([^a-df-z]|^)shop|shopping).*)$", "i").test(v.utmCampaign)) && new RegExp("^(.*cp.*|ppc|retargeting|paid.*)$", "i").test(v.utmMedium)},{"name":"paid-search","test":(v) => new RegExp("^(?:360\.cn|alice|aol|ar\.search\.yahoo\.com|ask|at\.search\.yahoo\.com|au\.search\.yahoo\.com|auone|avg|babylon|baidu|biglobe|biglobe\.co\.jp|biglobe\.ne\.jp|bing|br\.search\.yahoo\.com|ca\.search\.yahoo\.com|centrum\.cz|ch\.search\.yahoo\.com|cl\.search\.yahoo\.com|cn\.bing\.com|cnn|co\.search\.yahoo\.com|comcast|conduit|daum|daum\.net|de\.search\.yahoo\.com|dk\.search\.yahoo\.com|dogpile|dogpile\.com|duckduckgo|ecosia\.org|email\.seznam\.cz|eniro|es\.search\.yahoo\.com|espanol\.search\.yahoo\.com|exalead\.com|excite\.com|fi\.search\.yahoo\.com|firmy\.cz|fr\.search\.yahoo\.com|globo|go\.mail\.ru|google|google-play|hk\.search\.yahoo\.com|id\.search\.yahoo\.com|in\.search\.yahoo\.com|incredimail|it\.search\.yahoo\.com|kvasir|lens\.google\.com|lite\.qwant\.com|lycos|m\.baidu\.com|m\.naver\.com|m\.search\.naver\.com|m\.sogou\.com|mail\.rambler\.ru|mail\.yandex\.ru|malaysia\.search\.yahoo\.com|msn|msn\.com|mx\.search\.yahoo\.com|najdi|naver|naver\.com|news\.google\.com|nl\.search\.yahoo\.com|no\.search\.yahoo\.com|ntp\.msn\.com|nz\.search\.yahoo\.com|onet|onet\.pl|pe\.search\.yahoo\.com|ph\.search\.yahoo\.com|pl\.search\.yahoo\.com|play\.google\.com|qwant|qwant\.com|rakuten|rakuten\.co\.jp|rambler|rambler\.ru|se\.search\.yahoo\.com|search-results|search\.aol\.co\.uk|search\.aol\.com|search\.google\.com|search\.smt\.docomo\.ne\.jp|search\.ukr\.net|secureurl\.ukr\.net|seznam|seznam\.cz|sg\.search\.yahoo\.com|so\.com|sogou|sogou\.com|sp-web\.search\.auone\.jp|startsiden|startsiden\.no|suche\.aol\.de|terra|th\.search\.yahoo\.com|tr\.search\.yahoo\.com|tut\.by|tw\.search\.yahoo\.com|uk\.search\.yahoo\.com|ukr|us\.search\.yahoo\.com|virgilio|vn\.search\.yahoo\.com|wap\.sogou\.com|webmaster\.yandex\.ru|websearch\.rakuten\.co\.jp|yahoo|yahoo\.co\.jp|yahoo\.com|yandex|yandex\.by|yandex\.com|yandex\.com\.tr|yandex\.fr|yandex\.kz|yandex\.ru|yandex\.ua|yandex\.uz|zen\.yandex\.ru)$", "i").test(v.utmSource) && new RegExp("^(.*cp.*|ppc|retargeting|paid.*)$", "i").test(v.utmMedium)},{"name":"paid-social","test":(v) => new RegExp("^(?:43things|43things\.com|51\.com|5ch\.net|Hatena|ImageShack|academia\.edu|activerain|activerain\.com|activeworlds|activeworlds\.com|addthis|addthis\.com|airg\.ca|allnurses\.com|allrecipes\.com|alumniclass|alumniclass\.com|ameba\.jp|ameblo\.jp|americantowns|americantowns\.com|amp\.reddit\.com|ancestry\.com|anobii|anobii\.com|answerbag|answerbag\.com|answers\.yahoo\.com|aolanswers|aolanswers\.com|apps\.facebook\.com|ar\.pinterest\.com|artstation\.com|askubuntu|askubuntu\.com|asmallworld\.com|athlinks|athlinks\.com|away\.vk\.com|awe\.sm|b\.hatena\.ne\.jp|baby-gaga|baby-gaga\.com|babyblog\.ru|badoo|badoo\.com|bebo|bebo\.com|beforeitsnews|beforeitsnews\.com|bharatstudent|bharatstudent\.com|biip\.no|biswap\.org|bit\.ly|blackcareernetwork\.com|blackplanet|blackplanet\.com|blip\.fm|blog\.com|blog\.feedspot\.com|blog\.goo\.ne\.jp|blog\.naver\.com|blog\.yahoo\.co\.jp|blogg\.no|bloggang\.com|blogger|blogger\.com|blogher|blogher\.com|bloglines|bloglines\.com|blogs\.com|blogsome|blogsome\.com|blogspot|blogspot\.com|blogster|blogster\.com|blurtit|blurtit\.com|bookmarks\.yahoo\.co\.jp|bookmarks\.yahoo\.com|br\.pinterest\.com|brightkite|brightkite\.com|brizzly|brizzly\.com|business\.facebook\.com|buzzfeed|buzzfeed\.com|buzznet|buzznet\.com|cafe\.naver\.com|cafemom|cafemom\.com|camospace|camospace\.com|canalblog\.com|care\.com|care2|care2\.com|caringbridge\.org|catster|catster\.com|cbnt\.io|cellufun|cellufun\.com|centerblog\.net|chat\.zalo\.me|chegg\.com|chicagonow|chicagonow\.com|chiebukuro\.yahoo\.co\.jp|classmates|classmates\.com|classquest|classquest\.com|co\.pinterest\.com|cocolog-nifty|cocolog-nifty\.com|copainsdavant\.linternaute\.com|couchsurfing\.org|cozycot|cozycot\.com|cross\.tv|crunchyroll|crunchyroll\.com|cyworld|cyworld\.com|cz\.pinterest\.com|d\.hatena\.ne\.jp|dailystrength\.org|deluxe\.com|deviantart|deviantart\.com|dianping|dianping\.com|digg|digg\.com|diigo|diigo\.com|discover\.hubpages\.com|disqus|disqus\.com|dogster|dogster\.com|dol2day|dol2day\.com|doostang|doostang\.com|dopplr|dopplr\.com|douban|douban\.com|draft\.blogger\.com|draugiem\.lv|drugs-forum|drugs-forum\.com|dzone|dzone\.com|edublogs\.org|elftown|elftown\.com|epicurious\.com|everforo\.com|exblog\.jp|extole|extole\.com|facebook|facebook\.com|faceparty|faceparty\.com|fandom\.com|fanpop|fanpop\.com|fark|fark\.com|fb|fb\.me|fc2|fc2\.com|feedspot|feministing|feministing\.com|filmaffinity|filmaffinity\.com|flickr|flickr\.com|flipboard|flipboard\.com|folkdirect|folkdirect\.com|foodservice|foodservice\.com|forums\.androidcentral\.com|forums\.crackberry\.com|forums\.imore\.com|forums\.nexopia\.com|forums\.webosnation\.com|forums\.wpcentral\.com|fotki|fotki\.com|fotolog|fotolog\.com|foursquare|foursquare\.com|free\.facebook\.com|friendfeed|friendfeed\.com|fruehstueckstreff\.org|fubar|fubar\.com|gaiaonline|gaiaonline\.com|gamerdna|gamerdna\.com|gather\.com|geni\.com|getpocket\.com|glassboard|glassboard\.com|glassdoor|glassdoor\.com|godtube|godtube\.com|goldenline\.pl|goldstar|goldstar\.com|goo\.gl|gooblog|goodreads|goodreads\.com|google\+|googlegroups\.com|googleplus|govloop|govloop\.com|gowalla|gowalla\.com|gree\.jp|groups\.google\.com|gulli\.com|gutefrage\.net|habbo|habbo\.com|hi5|hi5\.com|hootsuite|hootsuite\.com|houzz|houzz\.com|hoverspot|hoverspot\.com|hr\.com|hu\.pinterest\.com|hubculture|hubculture\.com|hubpages\.com|hyves\.net|hyves\.nl|ibibo|ibibo\.com|id\.pinterest\.com|identi\.ca|ig|imageshack\.com|imageshack\.us|imvu|imvu\.com|in\.pinterest\.com|insanejournal|insanejournal\.com|instagram|instagram\.com|instapaper|instapaper\.com|internations\.org|interpals\.net|intherooms|intherooms\.com|irc-galleria\.net|is\.gd|italki|italki\.com|jammerdirect|jammerdirect\.com|jappy\.com|jappy\.de|kaboodle\.com|kakao|kakao\.com|kakaocorp\.com|kaneva|kaneva\.com|kin\.naver\.com|l\.facebook\.com|l\.instagram\.com|l\.messenger\.com|last\.fm|librarything|librarything\.com|lifestream\.aol\.com|line|line\.me|linkedin|linkedin\.com|listal|listal\.com|listography|listography\.com|livedoor\.com|livedoorblog|livejournal|livejournal\.com|lm\.facebook\.com|lnkd\.in|m\.blog\.naver\.com|m\.cafe\.naver\.com|m\.facebook\.com|m\.kin\.naver\.com|m\.vk\.com|m\.yelp\.com|mbga\.jp|medium\.com|meetin\.org|meetup|meetup\.com|meinvz\.net|meneame\.net|menuism\.com|messages\.google\.com|messages\.yahoo\.co\.jp|messenger|messenger\.com|mix\.com|mixi\.jp|mobile\.facebook\.com|mocospace|mocospace\.com|mouthshut|mouthshut\.com|movabletype|movabletype\.com|mubi|mubi\.com|my\.opera\.com|myanimelist\.net|myheritage|myheritage\.com|mylife|mylife\.com|mymodernmet|mymodernmet\.com|myspace|myspace\.com|netvibes|netvibes\.com|news\.ycombinator\.com|newsshowcase|nexopia|ngopost\.org|niconico|nicovideo\.jp|nightlifelink|nightlifelink\.com|ning|ning\.com|nl\.pinterest\.com|odnoklassniki\.ru|odnoklassniki\.ua|okwave\.jp|old\.reddit\.com|oneworldgroup\.org|onstartups|onstartups\.com|opendiary|opendiary\.com|oshiete\.goo\.ne\.jp|out\.reddit\.com|over-blog\.com|overblog\.com|paper\.li|partyflock\.nl|photobucket|photobucket\.com|pinboard|pinboard\.in|pingsta|pingsta\.com|pinterest|pinterest\.at|pinterest\.ca|pinterest\.ch|pinterest\.cl|pinterest\.co\.kr|pinterest\.co\.uk|pinterest\.com|pinterest\.com\.au|pinterest\.com\.mx|pinterest\.de|pinterest\.es|pinterest\.fr|pinterest\.it|pinterest\.jp|pinterest\.nz|pinterest\.ph|pinterest\.pt|pinterest\.ru|pinterest\.se|pixiv\.net|pl\.pinterest\.com|playahead\.se|plurk|plurk\.com|plus\.google\.com|plus\.url\.google\.com|pocket\.co|posterous|posterous\.com|pro\.homeadvisor\.com|pulse\.yahoo\.com|qapacity|qapacity\.com|quechup|quechup\.com|quora|quora\.com|qzone\.qq\.com|ravelry|ravelry\.com|reddit|reddit\.com|redux|redux\.com|renren|renren\.com|researchgate\.net|reunion|reunion\.com|reverbnation|reverbnation\.com|rtl\.de|ryze|ryze\.com|salespider|salespider\.com|scoop\.it|screenrant|screenrant\.com|scribd|scribd\.com|scvngr|scvngr\.com|secondlife|secondlife\.com|serverfault|serverfault\.com|shareit|sharethis|sharethis\.com|shvoong\.com|sites\.google\.com|skype|skyrock|skyrock\.com|slashdot\.org|slideshare\.net|smartnews\.com|snapchat|snapchat\.com|social|sociallife\.com\.br|socialvibe|socialvibe\.com|spaces\.live\.com|spoke|spoke\.com|spruz|spruz\.com|ssense\.com|stackapps|stackapps\.com|stackexchange|stackexchange\.com|stackoverflow|stackoverflow\.com|stardoll\.com|stickam|stickam\.com|studivz\.net|suomi24\.fi|superuser|superuser\.com|sweeva|sweeva\.com|t\.co|t\.me|tagged|tagged\.com|taggedmail|taggedmail\.com|talkbiznow|talkbiznow\.com|taringa\.net|techmeme|techmeme\.com|tencent|tencent\.com|tiktok|tiktok\.com|tinyurl|tinyurl\.com|toolbox|toolbox\.com|touch\.facebook\.com|tr\.pinterest\.com|travellerspoint|travellerspoint\.com|tripadvisor|tripadvisor\.com|trombi|trombi\.com|trustpilot|tudou|tudou\.com|tuenti|tuenti\.com|tumblr|tumblr\.com|tweetdeck|tweetdeck\.com|twitter|twitter\.com|twoo\.com|typepad|typepad\.com|unblog\.fr|urbanspoon\.com|ushareit\.com|ushi\.cn|vampirefreaks|vampirefreaks\.com|vampirerave|vampirerave\.com|vg\.no|video\.ibm\.com|vk\.com|vkontakte\.ru|wakoopa|wakoopa\.com|wattpad|wattpad\.com|web\.facebook\.com|web\.skype\.com|webshots|webshots\.com|wechat|wechat\.com|weebly|weebly\.com|weibo|weibo\.com|wer-weiss-was\.de|weread|weread\.com|whatsapp|whatsapp\.com|wiki\.answers\.com|wikihow\.com|wikitravel\.org|woot\.com|wordpress|wordpress\.com|wordpress\.org|xanga|xanga\.com|xing|xing\.com|yahoo-mbga\.jp|yammer|yammer\.com|yelp|yelp\.co\.uk|yelp\.com|youroom\.in|za\.pinterest\.com|zalo|zoo\.gr|zooppa|zooppa\.com)$", "i").test(v.utmSource) && new RegExp("^(.*cp.*|ppc|retargeting|paid.*)$", "i").test(v.utmMedium)},{"name":"paid-video","test":(v) => new RegExp("^(?:blog\.twitch\.tv|crackle|crackle\.com|curiositystream|curiositystream\.com|d\.tube|dailymotion|dailymotion\.com|dashboard\.twitch\.tv|disneyplus|disneyplus\.com|fast\.wistia\.net|help\.hulu\.com|help\.netflix\.com|hulu|hulu\.com|id\.twitch\.tv|iq\.com|iqiyi|iqiyi\.com|jobs\.netflix\.com|justin\.tv|m\.twitch\.tv|m\.youtube\.com|music\.youtube\.com|netflix|netflix\.com|player\.twitch\.tv|player\.vimeo\.com|ted|ted\.com|twitch|twitch\.tv|utreon|utreon\.com|veoh|veoh\.com|viadeo\.journaldunet\.com|vimeo|vimeo\.com|wistia|wistia\.com|youku|youku\.com|youtube|youtube\.com)$", "i").test(v.utmSource) && new RegExp("^(.*cp.*|ppc|retargeting|paid.*)$", "i").test(v.utmMedium)},{"name":"display","test":(v) => new RegExp("^(?:display|banner|expandable|interstitial|cpm)$", "i").test(v.utmMedium)},{"name":"paid-other","test":(v) => new RegExp("^(.*cp.*|ppc|retargeting|paid.*)$", "i").test(v.utmMedium)},{"name":"organic-shopping","test":(v) => new RegExp("^(?:360\.cn|alice|aol|ar\.search\.yahoo\.com|ask|at\.search\.yahoo\.com|au\.search\.yahoo\.com|auone|avg|babylon|baidu|biglobe|biglobe\.co\.jp|biglobe\.ne\.jp|bing|br\.search\.yahoo\.com|ca\.search\.yahoo\.com|centrum\.cz|ch\.search\.yahoo\.com|cl\.search\.yahoo\.com|cn\.bing\.com|cnn|co\.search\.yahoo\.com|comcast|conduit|daum|daum\.net|de\.search\.yahoo\.com|dk\.search\.yahoo\.com|dogpile|dogpile\.com|duckduckgo|ecosia\.org|email\.seznam\.cz|eniro|es\.search\.yahoo\.com|espanol\.search\.yahoo\.com|exalead\.com|excite\.com|fi\.search\.yahoo\.com|firmy\.cz|fr\.search\.yahoo\.com|globo|go\.mail\.ru|google|google-play|hk\.search\.yahoo\.com|id\.search\.yahoo\.com|in\.search\.yahoo\.com|incredimail|it\.search\.yahoo\.com|kvasir|lens\.google\.com|lite\.qwant\.com|lycos|m\.baidu\.com|m\.naver\.com|m\.search\.naver\.com|m\.sogou\.com|mail\.rambler\.ru|mail\.yandex\.ru|malaysia\.search\.yahoo\.com|msn|msn\.com|mx\.search\.yahoo\.com|najdi|naver|naver\.com|news\.google\.com|nl\.search\.yahoo\.com|no\.search\.yahoo\.com|ntp\.msn\.com|nz\.search\.yahoo\.com|onet|onet\.pl|pe\.search\.yahoo\.com|ph\.search\.yahoo\.com|pl\.search\.yahoo\.com|play\.google\.com|qwant|qwant\.com|rakuten|rakuten\.co\.jp|rambler|rambler\.ru|se\.search\.yahoo\.com|search-results|search\.aol\.co\.uk|search\.aol\.com|search\.google\.com|search\.smt\.docomo\.ne\.jp|search\.ukr\.net|secureurl\.ukr\.net|seznam|seznam\.cz|sg\.search\.yahoo\.com|so\.com|sogou|sogou\.com|sp-web\.search\.auone\.jp|startsiden|startsiden\.no|suche\.aol\.de|terra|th\.search\.yahoo\.com|tr\.search\.yahoo\.com|tut\.by|tw\.search\.yahoo\.com|uk\.search\.yahoo\.com|ukr|us\.search\.yahoo\.com|virgilio|vn\.search\.yahoo\.com|wap\.sogou\.com|webmaster\.yandex\.ru|websearch\.rakuten\.co\.jp|yahoo|yahoo\.co\.jp|yahoo\.com|yandex|yandex\.by|yandex\.com|yandex\.com\.tr|yandex\.fr|yandex\.kz|yandex\.ru|yandex\.ua|yandex\.uz|zen\.yandex\.ru)$", "i").test(v.utmSource) || new RegExp("^(.*(([^a-df-z]|^)shop|shopping).*)$", "i").test(v.utmCampaign)},{"name":"organic-social","test":(v) => new RegExp("^(?:43things|43things\.com|51\.com|5ch\.net|Hatena|ImageShack|academia\.edu|activerain|activerain\.com|activeworlds|activeworlds\.com|addthis|addthis\.com|airg\.ca|allnurses\.com|allrecipes\.com|alumniclass|alumniclass\.com|ameba\.jp|ameblo\.jp|americantowns|americantowns\.com|amp\.reddit\.com|ancestry\.com|anobii|anobii\.com|answerbag|answerbag\.com|answers\.yahoo\.com|aolanswers|aolanswers\.com|apps\.facebook\.com|ar\.pinterest\.com|artstation\.com|askubuntu|askubuntu\.com|asmallworld\.com|athlinks|athlinks\.com|away\.vk\.com|awe\.sm|b\.hatena\.ne\.jp|baby-gaga|baby-gaga\.com|babyblog\.ru|badoo|badoo\.com|bebo|bebo\.com|beforeitsnews|beforeitsnews\.com|bharatstudent|bharatstudent\.com|biip\.no|biswap\.org|bit\.ly|blackcareernetwork\.com|blackplanet|blackplanet\.com|blip\.fm|blog\.com|blog\.feedspot\.com|blog\.goo\.ne\.jp|blog\.naver\.com|blog\.yahoo\.co\.jp|blogg\.no|bloggang\.com|blogger|blogger\.com|blogher|blogher\.com|bloglines|bloglines\.com|blogs\.com|blogsome|blogsome\.com|blogspot|blogspot\.com|blogster|blogster\.com|blurtit|blurtit\.com|bookmarks\.yahoo\.co\.jp|bookmarks\.yahoo\.com|br\.pinterest\.com|brightkite|brightkite\.com|brizzly|brizzly\.com|business\.facebook\.com|buzzfeed|buzzfeed\.com|buzznet|buzznet\.com|cafe\.naver\.com|cafemom|cafemom\.com|camospace|camospace\.com|canalblog\.com|care\.com|care2|care2\.com|caringbridge\.org|catster|catster\.com|cbnt\.io|cellufun|cellufun\.com|centerblog\.net|chat\.zalo\.me|chegg\.com|chicagonow|chicagonow\.com|chiebukuro\.yahoo\.co\.jp|classmates|classmates\.com|classquest|classquest\.com|co\.pinterest\.com|cocolog-nifty|cocolog-nifty\.com|copainsdavant\.linternaute\.com|couchsurfing\.org|cozycot|cozycot\.com|cross\.tv|crunchyroll|crunchyroll\.com|cyworld|cyworld\.com|cz\.pinterest\.com|d\.hatena\.ne\.jp|dailystrength\.org|deluxe\.com|deviantart|deviantart\.com|dianping|dianping\.com|digg|digg\.com|diigo|diigo\.com|discover\.hubpages\.com|disqus|disqus\.com|dogster|dogster\.com|dol2day|dol2day\.com|doostang|doostang\.com|dopplr|dopplr\.com|douban|douban\.com|draft\.blogger\.com|draugiem\.lv|drugs-forum|drugs-forum\.com|dzone|dzone\.com|edublogs\.org|elftown|elftown\.com|epicurious\.com|everforo\.com|exblog\.jp|extole|extole\.com|facebook|facebook\.com|faceparty|faceparty\.com|fandom\.com|fanpop|fanpop\.com|fark|fark\.com|fb|fb\.me|fc2|fc2\.com|feedspot|feministing|feministing\.com|filmaffinity|filmaffinity\.com|flickr|flickr\.com|flipboard|flipboard\.com|folkdirect|folkdirect\.com|foodservice|foodservice\.com|forums\.androidcentral\.com|forums\.crackberry\.com|forums\.imore\.com|forums\.nexopia\.com|forums\.webosnation\.com|forums\.wpcentral\.com|fotki|fotki\.com|fotolog|fotolog\.com|foursquare|foursquare\.com|free\.facebook\.com|friendfeed|friendfeed\.com|fruehstueckstreff\.org|fubar|fubar\.com|gaiaonline|gaiaonline\.com|gamerdna|gamerdna\.com|gather\.com|geni\.com|getpocket\.com|glassboard|glassboard\.com|glassdoor|glassdoor\.com|godtube|godtube\.com|goldenline\.pl|goldstar|goldstar\.com|goo\.gl|gooblog|goodreads|goodreads\.com|google\+|googlegroups\.com|googleplus|govloop|govloop\.com|gowalla|gowalla\.com|gree\.jp|groups\.google\.com|gulli\.com|gutefrage\.net|habbo|habbo\.com|hi5|hi5\.com|hootsuite|hootsuite\.com|houzz|houzz\.com|hoverspot|hoverspot\.com|hr\.com|hu\.pinterest\.com|hubculture|hubculture\.com|hubpages\.com|hyves\.net|hyves\.nl|ibibo|ibibo\.com|id\.pinterest\.com|identi\.ca|ig|imageshack\.com|imageshack\.us|imvu|imvu\.com|in\.pinterest\.com|insanejournal|insanejournal\.com|instagram|instagram\.com|instapaper|instapaper\.com|internations\.org|interpals\.net|intherooms|intherooms\.com|irc-galleria\.net|is\.gd|italki|italki\.com|jammerdirect|jammerdirect\.com|jappy\.com|jappy\.de|kaboodle\.com|kakao|kakao\.com|kakaocorp\.com|kaneva|kaneva\.com|kin\.naver\.com|l\.facebook\.com|l\.instagram\.com|l\.messenger\.com|last\.fm|librarything|librarything\.com|lifestream\.aol\.com|line|line\.me|linkedin|linkedin\.com|listal|listal\.com|listography|listography\.com|livedoor\.com|livedoorblog|livejournal|livejournal\.com|lm\.facebook\.com|lnkd\.in|m\.blog\.naver\.com|m\.cafe\.naver\.com|m\.facebook\.com|m\.kin\.naver\.com|m\.vk\.com|m\.yelp\.com|mbga\.jp|medium\.com|meetin\.org|meetup|meetup\.com|meinvz\.net|meneame\.net|menuism\.com|messages\.google\.com|messages\.yahoo\.co\.jp|messenger|messenger\.com|mix\.com|mixi\.jp|mobile\.facebook\.com|mocospace|mocospace\.com|mouthshut|mouthshut\.com|movabletype|movabletype\.com|mubi|mubi\.com|my\.opera\.com|myanimelist\.net|myheritage|myheritage\.com|mylife|mylife\.com|mymodernmet|mymodernmet\.com|myspace|myspace\.com|netvibes|netvibes\.com|news\.ycombinator\.com|newsshowcase|nexopia|ngopost\.org|niconico|nicovideo\.jp|nightlifelink|nightlifelink\.com|ning|ning\.com|nl\.pinterest\.com|odnoklassniki\.ru|odnoklassniki\.ua|okwave\.jp|old\.reddit\.com|oneworldgroup\.org|onstartups|onstartups\.com|opendiary|opendiary\.com|oshiete\.goo\.ne\.jp|out\.reddit\.com|over-blog\.com|overblog\.com|paper\.li|partyflock\.nl|photobucket|photobucket\.com|pinboard|pinboard\.in|pingsta|pingsta\.com|pinterest|pinterest\.at|pinterest\.ca|pinterest\.ch|pinterest\.cl|pinterest\.co\.kr|pinterest\.co\.uk|pinterest\.com|pinterest\.com\.au|pinterest\.com\.mx|pinterest\.de|pinterest\.es|pinterest\.fr|pinterest\.it|pinterest\.jp|pinterest\.nz|pinterest\.ph|pinterest\.pt|pinterest\.ru|pinterest\.se|pixiv\.net|pl\.pinterest\.com|playahead\.se|plurk|plurk\.com|plus\.google\.com|plus\.url\.google\.com|pocket\.co|posterous|posterous\.com|pro\.homeadvisor\.com|pulse\.yahoo\.com|qapacity|qapacity\.com|quechup|quechup\.com|quora|quora\.com|qzone\.qq\.com|ravelry|ravelry\.com|reddit|reddit\.com|redux|redux\.com|renren|renren\.com|researchgate\.net|reunion|reunion\.com|reverbnation|reverbnation\.com|rtl\.de|ryze|ryze\.com|salespider|salespider\.com|scoop\.it|screenrant|screenrant\.com|scribd|scribd\.com|scvngr|scvngr\.com|secondlife|secondlife\.com|serverfault|serverfault\.com|shareit|sharethis|sharethis\.com|shvoong\.com|sites\.google\.com|skype|skyrock|skyrock\.com|slashdot\.org|slideshare\.net|smartnews\.com|snapchat|snapchat\.com|social|sociallife\.com\.br|socialvibe|socialvibe\.com|spaces\.live\.com|spoke|spoke\.com|spruz|spruz\.com|ssense\.com|stackapps|stackapps\.com|stackexchange|stackexchange\.com|stackoverflow|stackoverflow\.com|stardoll\.com|stickam|stickam\.com|studivz\.net|suomi24\.fi|superuser|superuser\.com|sweeva|sweeva\.com|t\.co|t\.me|tagged|tagged\.com|taggedmail|taggedmail\.com|talkbiznow|talkbiznow\.com|taringa\.net|techmeme|techmeme\.com|tencent|tencent\.com|tiktok|tiktok\.com|tinyurl|tinyurl\.com|toolbox|toolbox\.com|touch\.facebook\.com|tr\.pinterest\.com|travellerspoint|travellerspoint\.com|tripadvisor|tripadvisor\.com|trombi|trombi\.com|trustpilot|tudou|tudou\.com|tuenti|tuenti\.com|tumblr|tumblr\.com|tweetdeck|tweetdeck\.com|twitter|twitter\.com|twoo\.com|typepad|typepad\.com|unblog\.fr|urbanspoon\.com|ushareit\.com|ushi\.cn|vampirefreaks|vampirefreaks\.com|vampirerave|vampirerave\.com|vg\.no|video\.ibm\.com|vk\.com|vkontakte\.ru|wakoopa|wakoopa\.com|wattpad|wattpad\.com|web\.facebook\.com|web\.skype\.com|webshots|webshots\.com|wechat|wechat\.com|weebly|weebly\.com|weibo|weibo\.com|wer-weiss-was\.de|weread|weread\.com|whatsapp|whatsapp\.com|wiki\.answers\.com|wikihow\.com|wikitravel\.org|woot\.com|wordpress|wordpress\.com|wordpress\.org|xanga|xanga\.com|xing|xing\.com|yahoo-mbga\.jp|yammer|yammer\.com|yelp|yelp\.co\.uk|yelp\.com|youroom\.in|za\.pinterest\.com|zalo|zoo\.gr|zooppa|zooppa\.com)$", "i").test(v.utmSource) || new RegExp("^(?:social|social-network|social-media|sm|social network|social media)$", "i").test(v.utmMedium)},{"name":"organic-video","test":(v) => new RegExp("^(?:blog\.twitch\.tv|crackle|crackle\.com|curiositystream|curiositystream\.com|d\.tube|dailymotion|dailymotion\.com|dashboard\.twitch\.tv|disneyplus|disneyplus\.com|fast\.wistia\.net|help\.hulu\.com|help\.netflix\.com|hulu|hulu\.com|id\.twitch\.tv|iq\.com|iqiyi|iqiyi\.com|jobs\.netflix\.com|justin\.tv|m\.twitch\.tv|m\.youtube\.com|music\.youtube\.com|netflix|netflix\.com|player\.twitch\.tv|player\.vimeo\.com|ted|ted\.com|twitch|twitch\.tv|utreon|utreon\.com|veoh|veoh\.com|viadeo\.journaldunet\.com|vimeo|vimeo\.com|wistia|wistia\.com|youku|youku\.com|youtube|youtube\.com)$", "i").test(v.utmSource) || new RegExp("^(.*video.*)$", "i").test(v.utmMedium)},{"name":"organic-search","test":(v) => new RegExp("^(?:360\.cn|alice|aol|ar\.search\.yahoo\.com|ask|at\.search\.yahoo\.com|au\.search\.yahoo\.com|auone|avg|babylon|baidu|biglobe|biglobe\.co\.jp|biglobe\.ne\.jp|bing|br\.search\.yahoo\.com|ca\.search\.yahoo\.com|centrum\.cz|ch\.search\.yahoo\.com|cl\.search\.yahoo\.com|cn\.bing\.com|cnn|co\.search\.yahoo\.com|comcast|conduit|daum|daum\.net|de\.search\.yahoo\.com|dk\.search\.yahoo\.com|dogpile|dogpile\.com|duckduckgo|ecosia\.org|email\.seznam\.cz|eniro|es\.search\.yahoo\.com|espanol\.search\.yahoo\.com|exalead\.com|excite\.com|fi\.search\.yahoo\.com|firmy\.cz|fr\.search\.yahoo\.com|globo|go\.mail\.ru|google|google-play|hk\.search\.yahoo\.com|id\.search\.yahoo\.com|in\.search\.yahoo\.com|incredimail|it\.search\.yahoo\.com|kvasir|lens\.google\.com|lite\.qwant\.com|lycos|m\.baidu\.com|m\.naver\.com|m\.search\.naver\.com|m\.sogou\.com|mail\.rambler\.ru|mail\.yandex\.ru|malaysia\.search\.yahoo\.com|msn|msn\.com|mx\.search\.yahoo\.com|najdi|naver|naver\.com|news\.google\.com|nl\.search\.yahoo\.com|no\.search\.yahoo\.com|ntp\.msn\.com|nz\.search\.yahoo\.com|onet|onet\.pl|pe\.search\.yahoo\.com|ph\.search\.yahoo\.com|pl\.search\.yahoo\.com|play\.google\.com|qwant|qwant\.com|rakuten|rakuten\.co\.jp|rambler|rambler\.ru|se\.search\.yahoo\.com|search-results|search\.aol\.co\.uk|search\.aol\.com|search\.google\.com|search\.smt\.docomo\.ne\.jp|search\.ukr\.net|secureurl\.ukr\.net|seznam|seznam\.cz|sg\.search\.yahoo\.com|so\.com|sogou|sogou\.com|sp-web\.search\.auone\.jp|startsiden|startsiden\.no|suche\.aol\.de|terra|th\.search\.yahoo\.com|tr\.search\.yahoo\.com|tut\.by|tw\.search\.yahoo\.com|uk\.search\.yahoo\.com|ukr|us\.search\.yahoo\.com|virgilio|vn\.search\.yahoo\.com|wap\.sogou\.com|webmaster\.yandex\.ru|websearch\.rakuten\.co\.jp|yahoo|yahoo\.co\.jp|yahoo\.com|yandex|yandex\.by|yandex\.com|yandex\.com\.tr|yandex\.fr|yandex\.kz|yandex\.ru|yandex\.ua|yandex\.uz|zen\.yandex\.ru)$", "i").test(v.utmSource) || v.utmMedium.toLowerCase() === "organic"},{"name":"referral","test":(v) => new RegExp("^(?:referral|app|link)$", "i").test(v.utmMedium)},{"name":"email","test":(v) => new RegExp("^(?:email|e-mail|e_mail|e mail)$", "i").test(v.utmMedium) || new RegExp("^(?:email|e-mail|e_mail|e mail)$", "i").test(v.utmSource)},{"name":"affiliate","test":(v) => v.utmMedium.toLowerCase() === "affiliate"},{"name":"audio","test":(v) => v.utmMedium.toLowerCase() === "audio"},{"name":"sms","test":(v) => v.utmSource.toLowerCase() === "sms" || v.utmMedium.toLowerCase() === "sms"},{"name":"mobile-push-notification","test":(v) => v.utmSource.toLowerCase() === "firebase" || new RegExp("(?:.*mobile.*|.*notification.*|push$)", "i").test(v.utmMedium)}].find(i=>i.test(e))?.name??"other"}getShopifyAnalyticsId(){const e=this.getCookie("_shopify_y");if(e)return e;try{const t=this.localStorageGet("Shoplift_ClientId");if(t)return t}catch{}return null}legacyGetCookieVisitor(){const e=this.getCookie("SHOPLIFT");return e===null?null:JSON.parse(e,F)}getCookie(e,t=this.cookie){const i=t.split("; ").filter(s=>s.split("=").at(0)===e).at(0);return i===void 0?null:i.split("=").slice(1).join("=")}monitorConsentChange(){document.addEventListener("visitorConsentCollected",e=>{(async()=>await this.onConsentChange(e.detail.analyticsAllowed,!0))()}),document.readyState==="loading"?document.addEventListener("DOMContentLoaded",()=>this.loadShopifyConsentApiWithRetry()):this.loadShopifyConsentApiWithRetry()}loadShopifyConsentApiWithRetry(){let e=0;const t=()=>{this.loadShopifyConsentApi()||e++<10&&window.setTimeout(t,100)};t()}loadShopifyConsentApi(){if(window.Shopify){this.log("Loading Shopify features");const e=async()=>{if(!window.Shopify){this.log("Shopify object missing... suddenly?");return}if(window.Shopify.customerPrivacy===void 0){this.log("Shopify CustomerPrivacy api still missing, trying again in 1000ms"),t=window.setTimeout(()=>{(async()=>await e())()},1e3);return}if(this.geoViaShopify){const s=window.Shopify.customerPrivacy.getRegion?.();this.resolvedRegion=typeof s=="string"?s.replace(/-/g,""):""}const i=window.Shopify.customerPrivacy.getTrackingConsent();await this.onConsentChange(window.Shopify.customerPrivacy.analyticsProcessingAllowed(),i==="yes")};let t=window.setTimeout(()=>{(async()=>await e())()},5e3);return window.Shopify.loadFeatures([{name:"consent-tracking-api",version:"0.1"}],i=>{(async()=>{if(window.clearTimeout(t),i){this.log("Error loading consent tracking",i);return}await e()})()}),!0}return!1}async onConsentChange(e,t){try{if(this.log("Consent change detected",e,t),this.state.essential.consentApproved=e,this.state.essential.hasConsentInteraction=t,!this.state.essential.consentApproved){this.state.essential.hasConsentInteraction&&(this.state.analytics.queue.length=0),this.saveState();return}this.cookie=document.cookie,this.shopifyAnalyticsId=this.getShopifyAnalyticsId(),this.saveState(),await this.syncAllEvents()}catch(i){this.log("Error syncing on consent change",i)}}isThemePreview(){return isThemePreview||themeRole!=="main"}isAppProxyPath(){const e=["/apps/","/tools/","/a/"],t=window.location.pathname;return e.some(i=>t.startsWith(i))}clearThemeBar(e,t,i){const s=structuredClone(i);this.log("Looking for theme bar"),this.waitForElement(null,"body").then(r=>this.waitForElement(r,"#preview-bar-iframe, #PBarNextFrameWrapper").then(n=>(this.log("Found theme bar"),t&&(this.log("Removing theme bar"),n.remove()),e?this.makeRequest({url:`${this.eventHost}/api/v0/logs`,method:"post",data:JSON.stringify({...this.debugState(),stateAtEvaluation:s},te)}):Promise.resolve(null)))).catch(r=>console.error(r))}waitForElement(e,t){return new Promise(i=>{const s=document.querySelector(t);if(s){i(s);return}const r=new MutationObserver(n=>{const o=document.querySelector(t);if(o){r.disconnect(),i(o);return}});r.observe(e??document.documentElement,{childList:!0})})}setDebug(e){this.state.essential.debugMode=e,this.saveState()}log(e,...t){let i=0;const s=e.replace(/%[sdoOfF]/g,r=>{if(i>=t.length)return r;const n=t[i++];return r==="%o"||r==="%O"?JSON.stringify(n):String(n)});this.logHistory.push(`[${new Date().toISOString()}][SL] ${s}`),!(!this.state.essential.debugMode&&!this.shopliftDebug)&&console.debug(`[SL] ${e}`,...t)}debugState(){return{state:this.state,storage:{essential:this.loadLocalStorage(this.essentialSessionKey),analytics:this.loadLocalStorage(this.analyticsSessionKey)},params:{shop:this.shop,host:this.host,eventHost:this.eventHost,cssHideClass:this.cssHideClass,testConfigs:this.testConfigs,inactiveTestConfigs:this.inactiveTestConfigs,sendPageView:this.sendPageView,isShopifyMerchantCookie:this.getCookie("is_shopify_merchant"),themeId,url:window.location.href,isThemePreview,themeRole,gaConfig:this.gaConfig},logHistory:this.logHistory}}createViewportObserver(e,t={}){const{threshold:i=this.VIEWPORT_TRACK_THRESHOLD,triggerOnce:s=!0}=t,r=new Set;return new IntersectionObserver(n=>{n.forEach(o=>{if(o.isIntersecting&&!r.has(o.target)){const l=o.target,c=l.getAttribute(this.DATA_SL_TEST_ID);c&&(e(c,l),s&&r.add(l))}})},{threshold:i})}applyChangesWithViewport(e,t,i,s){const r=t.selectorsForViewportTracking??t.selectors,n=o=>{if(this.state.essential.visitorTests.some(h=>h.testId===o)||this.activeViewportObservers.has(o))return;const l=[];if(r.forEach(h=>{e.querySelectorAll(h.cssSelector).forEach(b=>l.push(b))}),l.length===0)return;let c=!1;const d=()=>{c||(c=!0,i(o),p.disconnect(),this.activeViewportObservers.delete(o))},p=this.createViewportObserver(()=>{d()},{triggerOnce:!0,...s});this.activeViewportObservers.set(o,p),this.log(`Created viewport observer for test ${o}, observing ${l.length} elements`),l.forEach(h=>{h.setAttribute(this.DATA_SL_TEST_ID,String(o)),p.observe(h)}),setTimeout(()=>{c||l.forEach(h=>{const u=h.getBoundingClientRect(),b=s?.threshold??this.VIEWPORT_TRACK_THRESHOLD,E=Math.min(u.bottom,window.innerHeight)-Math.max(u.top,0),S=Math.min(u.right,window.innerWidth)-Math.max(u.left,0);u.top<window.innerHeight&&u.bottom>0&&u.left<window.innerWidth&&u.right>0&&E>0&&S>0&&E>=u.height*b&&(this.log(`Price element already visible in viewport for test ${o}:`,h),d())})},100)};t.selectors.length>0&&U(e,t,()=>{}),Ie(e,{testId:t.testId,hypothesisId:t.hypothesisId,selectors:r},o=>{n(o)})}applyPriceTestWithMapLookup(e,t,i,s){if(!t.priceData){this.log("No price data for hypothesis '%s'",t.id);return}this.log("Hypothesis '%s' isControl=%s, priceData has %d variants",t.id,t.isControl,t.priceData.variants.length);const r=t.priceData.variants.slice(0,3);for(const[S,C,_]of r)this.log(" Sample priceData: variant=%s, price=%d, compareAt=%d",S,C,_);const n=j(t.priceData),o=new Set;for(const S of i)if(S.priceData)for(const[C]of S.priceData.variants)o.add(C);this.log("Price test Map lookup: %d products in hypothesis, %d total products to track",n.size,o.size);const l=t.priceData,c=new WeakSet;let d=!1;const p="[data-sl-attribute-p], [data-sl-attribute-cap], [data-sl-attribute-discount]",h=S=>{if(c.has(S))return;const C=S.getAttribute("data-sl-attribute-p"),_=S.getAttribute("data-sl-attribute-cap"),T=S.getAttribute("data-sl-attribute-discount"),m=C||_||T;if(!m||!o.has(m))return;c.add(S);const y=n.get(m);y&&(this.log("Applying price for product %s: %d cents (compare at: %d cents)",m,y.priceInCents,y.compareAtPriceInCents),$e(S,m,y,l),this.log("Applied price to element for product %s",m)),!d&&!this.state.essential.visitorTests.some(w=>w.testId===e)&&(S.setAttribute(this.DATA_SL_TEST_ID,String(e)),this.setupElementViewportTracking(S,e,()=>{d||(d=!0,s(e))}))},u=()=>{const S=document.querySelectorAll(p);this.log("Scanning for price elements, found: %d",S.length),S.forEach(h)},b=new MutationObserver(S=>{for(const C of S)C.type==="childList"&&C.addedNodes.forEach(_=>{if(_.nodeType===Node.ELEMENT_NODE){const T=_;(T.hasAttribute("data-sl-attribute-p")||T.hasAttribute("data-sl-attribute-cap")||T.hasAttribute("data-sl-attribute-discount"))&&h(T),T.querySelectorAll(p).forEach(h)}}),C.type==="attributes"&&C.target instanceof Element&&h(C.target)}),E=document.body||document.documentElement;b.observe(E,{childList:!0,subtree:!0,attributes:!0,attributeFilter:["data-sl-attribute-p","data-sl-attribute-cap","data-sl-attribute-discount"]}),this.log("MutationObserver started for price elements"),u(),document.readyState==="loading"&&document.addEventListener("DOMContentLoaded",()=>{this.log("DOMContentLoaded - rescanning for price elements"),u()}),setTimeout(()=>{this.log("Delayed rescan for price elements"),u()},100),setTimeout(()=>{this.log("Final rescan for price elements"),u()},500)}setupElementViewportTracking(e,t,i){const s=this.VIEWPORT_TRACK_THRESHOLD,r=e.getBoundingClientRect(),n=Math.min(r.bottom,window.innerHeight)-Math.max(r.top,0),o=Math.min(r.right,window.innerWidth)-Math.max(r.left,0);if(r.top<window.innerHeight&&r.bottom>0&&r.left<window.innerWidth&&r.right>0&&n>0&&o>0&&n>=r.height*s){this.log("Price element already visible for test %s",t),i();return}const c=new IntersectionObserver(d=>{for(const p of d)if(p.isIntersecting&&p.intersectionRatio>=s){this.log("Price element entered viewport for test %s",t),c.disconnect(),i();break}},{threshold:s});c.observe(e)}debug(){const e=this.debugState();console.log(JSON.stringify(e,te,2))}}(async function(){window.shopliftInstance||(window.shopliftInstance=new et("contractor-training-center.myshopify.com","https://app.shoplift.ai","https://events.shoplift.ai",false,false,false,{"sendEvents":false,"mode":"gtag"},false,false,1000,[],[],null,true),await window.shopliftInstance.init())})();async function tt(a,e,t,i){const s=Ke({log:i});if(t)return i("[SUB-PREVIEW] A side — no overlay applied; widget renders naturally"),s;const r=a.widget.widgetType,n=e?j(e):null;let o=W(e),l=Y(a,o),c=l.discountMap,d=l.maxDiscount;function p(){const f=W(e);f!==o&&(o=f,l=Y(a,o),c=l.discountMap,d=l.maxDiscount,i(`[SUB-PREVIEW] scope refreshed currentProductId=${o??"n/a"}, maxDiscount=${d}`))}i(`[SUB-PREVIEW] side=B, currentProductId=${o??"n/a"}, maxDiscount=${d}`);function h(f){if(!e||!n)return null;const v=X(n),g=v?n.get(v):void 0;return g?{formattedVariantPrice:K(g.priceInCents,e),formattedDiscounted:K(g.priceInCents*(1-f/100),e)}:null}function u(f){const v=Z(a,f);if(!v)return d;const g=D(a,"subscriptionInput"),P=g.length?g[0].selector:'input[name="rc_plan"]',A=v.querySelector(`${P}:checked`);if(A){const k=c[A.value];if(k!==void 0)return k}return d}function b(f){const v=D(a,"subscriptionDiscount");for(const g of v)if(g.selector.includes("badge")||g.selector.includes("__badge")){const P=f.querySelector(g.selector);P?.textContent&&!P.textContent.includes(`${d}%`)&&$(P,A=>N(A,d))}}function E(f,v){const g=h(v);if(!g)return;const P=D(a,"subscriptionCompareAt");for(const A of P){const k=f.querySelector(A.selector)||f.querySelector(`[part~="${A.selector}"]`);k?.textContent&&!k.textContent.includes(g.formattedVariantPrice)&&$(k,x=>/\d/.test(x)?g.formattedVariantPrice:x)}}function S(f,v){const g=h(v);if(!g)return;const P=D(a,"subscriptionPrice");for(const A of P){const k=f.querySelector(A.selector)||f.querySelector(`[part~="${A.selector}"]`);k?.textContent&&!k.textContent.includes(g.formattedDiscounted)&&$(k,x=>/\d/.test(x)?g.formattedDiscounted:x)}}function C(f){const v=D(a,"subscriptionInput"),g=v.length?v[0].selector:'input[name="rc_plan"]',P=D(a,"subscriptionPlanDiscount"),A=P.length?P[0].selector:".rc-plans-button__discount";for(const k of Array.from(f.querySelectorAll("label"))){const x=k.querySelector(g),R=k.querySelector(A);if(x&&R?.textContent){const O=c[x.value];if(O!==void 0){const V=R.textContent.match(/[\d.]+%/)?.[0];V&&V!==`${O}%`&&$(R,L=>N(L,O))}}}}function _(f){const v=f.querySelector("select");if(v)for(const g of Array.from(v.options)){const P=c[g.value];if(P!==void 0&&g.textContent){const A=g.textContent.match(/[\d.]+%/)?.[0];A&&A!==`${P}%`&&(g.textContent=N(g.textContent,P))}}}function T(f){const v=D(a,"onetimePrice");if(!v.length||!e||!n)return;const g=X(n),P=g?n.get(g):void 0;if(!P)return;const A=K(P.priceInCents,e),k=D(a,"onetimeContainer"),x=k.length?k[0].selector:'[part~="rc-purchase-option__onetime"]',R=f.querySelector(x);if(R)for(const O of v){const V=R.querySelector(`[part~="${O.selector}"]`);V?.textContent&&!V.textContent.includes(A)&&$(V,L=>/\d/.test(L)?A:L)}}function m(f,v){const P=D(a,"subscriptionDiscount").filter(A=>A.selector.includes("benefit")||A.selector==="rc-benefits");for(const A of P){const k=f.querySelector(A.selector);if(k?.shadowRoot){for(const x of Array.from(k.shadowRoot.querySelectorAll("li")))if(x.textContent?.includes("Save")){const R=x.textContent.match(/[\d.]+%/)?.[0];R&&R!==`${v}%`&&$(x,O=>N(O,v))}}}}let y=!1;function w(){if(!y){y=!0;try{p();const f=B(a);if(!f)return;const v=u(f);b(f),E(f,v),S(f,v),T(f);const g=Z(a,f);g&&(r==="buttons"||r==="radio"?C(g):_(g)),m(f,v)}finally{y=!1}}}const I=ue({data:a,runUpdates:w});return function(){I(),s()}}const it=Object.freeze(Object.defineProperty({__proto__:null,subscriptionPreviewRender:tt},Symbol.toStringTag,{value:"Module"}))})(); })("/", { suffix: "sticky-nav", type: "article" }, "main", 185538478157, false)</script>
5 Mistakes That Cause Contractors to Fail the Virginia Licensing Exam
Posted by
Lauren Buckley
Share
Preparing for the Virginia contractor licensing exam requires more than construction experience. Contractors also need to understand what the exam tests, know how to navigate their reference materials, and manage their time effectively.
Experienced contractors can struggle when they approach the exam based solely on what they know from the field. Understanding the most common exam-prep mistakes can help you build a better study strategy before test day.
At a Glance: Common Virginia Contractor Exam Mistakes
Relying too heavily on field experience
Trying to memorize reference books instead of learning how to use them
Practicing questions without practicing the exam process
Spending too much time on difficult questions
Taking the exam before practice results show you're ready
Understanding Virginia Contractor Exam Requirements
Virginia's exam requirements depend on the license class you're pursuing. According to the Virginia Department of Professional and Occupational Regulation (DPOR), for the business examination, a Class B Designated Employee must pass the Virginia and General portions, while a Class A Designated Employee must pass the Virginia, General, and Advanced portions.
Virginia also requires new Class A, B, and C contractor businesses to complete an approved eight-hour pre-license education course. That course is a separate licensing requirement from the Class A and Class B business examinations.
With that in mind, here are five mistakes contractors should avoid when preparing.
Mistake #1: Relying Too Much on Construction Experience
Years of construction experience can make you a better contractor, but they don't automatically prepare you for the Virginia licensing exam.
The business exam includes subjects that may not be part of your everyday responsibilities in the field. Depending on the exam portion, candidates may encounter questions involving Virginia regulations, business organization, financial management, employment requirements, project management, contracts, and other business topics.
Instead of asking, “Do I know how to run a construction project?” ask, “Do I understand the subjects this exam is actually testing?”
Start with the exam content and build your study plan around it. Your field experience will help, but it shouldn't be your only preparation.
“One of the biggest mistakes experienced contractors can make is assuming their years in the field will carry them through the exam. They may know construction extremely well, but the exam also tests the business and regulatory side of being a contractor in Virginia.”
— Chris Clausing, Director of Curriculum, Contractor Training Center
Mistake #2: Trying to Memorize the Books Instead of Learning How to Use Them
Trying to memorize every regulation, definition, formula, and business concept isn't an efficient way to prepare.
Contractors should understand the major concepts, but they should also become comfortable navigating the reference materials applicable to their exam. That means knowing how the books are organized, where major topics are located, and how to find information efficiently.
When working through practice questions, don't focus only on whether you got the answer right. Pay attention to how you found the answer.
Which reference contained it?
Which section did you use?
How long did it take you to locate?
Practicing that process helps turn your books into tools instead of something you're trying to learn how to navigate under exam pressure.
Mistake #3: Practicing Questions Without Practicing the Exam Process
Answering practice questions is useful, but simply checking whether your answers are right or wrong isn't enough. Practice should also teach you how to take the exam.
Use the reference materials you'll need to know, work through questions under time constraints, and practice deciding when you know an answer versus when you need to research it.
For Virginia-specific questions, become comfortable locating the regulations and requirements that apply to contractors in the Commonwealth. The Virginia Board for Contractors is the primary state resource for current contractor licensing information.
A simple process to practice is:
Read the Question → Identify the Subject → Find the Information → Answer → Move On
By exam day, that process should feel familiar.
Mistake #4: Letting One Difficult Question Eat Up Your Time
Time management matters on a licensing exam. One of the easiest ways to get into trouble is to find a difficult question, become determined to solve it immediately, and spend too much time searching through your materials.
Even if you eventually find the answer, you may have sacrificed time that could have been used to answer several other questions.
A better approach is to recognize when a question is taking too long and keep the rest of the exam moving. Your practice sessions should help you develop that judgment.
“Candidates sometimes think they need to solve every difficult question the moment they see it. Good exam strategy is knowing when to keep looking and when to move on so one question doesn't consume time you need elsewhere.”
— Chris Clausing, Director of Curriculum, Contractor Training Center
Practice exams are particularly useful here because they reveal more than your knowledge. They show whether you can apply that knowledge efficiently under a deadline.
Mistake #5: Scheduling the Exam Before Your Practice Results Say You're Ready
Finishing a course or reading through your materials doesn't necessarily mean you're ready for the exam. Your practice performance should help make that determination.
Before test day, you should be comfortable with the subjects covered by your required exam portions, able to navigate your reference materials efficiently, and capable of completing realistic practice questions within the available time.
More importantly, look for patterns in what you're getting wrong. If Virginia regulations consistently cause problems, spend more time there. If business calculations are slowing you down, practice those. If you know the concepts but can't find information quickly, focus on navigating your references.
The closer you get to exam day, the more targeted your studying should become.
“Before taking the exam, you want more than familiarity with the material. You want evidence from your practice that you can find the information, answer the questions, and manage your time consistently.”
— Chris Clausing, Director of Curriculum, Contractor Training Center
How to Prepare for the Virginia Contractor Licensing Exam
Effective exam preparation should focus on both knowledge and execution.
First, confirm the requirements for the Virginia contractor license you're pursuing through the Virginia Board for Contractors and determine which exam portions apply to you. Then study the subjects those portions cover while becoming familiar with the appropriate reference materials.
As the exam approaches, shift more of your preparation toward realistic practice. Work under time constraints, identify your weakest subjects, and practice finding information rather than simply rereading it.
By test day, you don't want to be figuring out your strategy. You want to be executing a process you've already practiced.
Prepare for the Virginia Contractor Exam With Contractor Training Center
Contractor Training Center helps contractors prepare for Virginia's contractor licensing requirements with exam preparation focused on what candidates need to know for test day.
Exam prep can help you understand the material being tested, become more comfortable with the relevant reference materials, identify weak areas through practice questions, and develop a strategy for managing your time.
Whether you're pursuing a Virginia Class A or Class B contractor license, preparing specifically for your required exam portions can help you approach test day knowing what to expect and how to work through it.
Prepare for Your Virginia Contractor Exam
Explore Contractor Training Center's Virginia contractor exam preparation courses and study resources to help you prepare for the Class A or Class B licensing examinations.
What is the biggest mistake contractors make when preparing for the Virginia licensing exam?
One common mistake is relying too heavily on construction experience instead of preparing for the specific subjects covered by the exam. Experienced contractors still need to study business and regulatory topics and become comfortable navigating the materials relevant to their required exam portions.
What exams are required for a Virginia Class A contractor license?
For the business examination, the Designated Employee for a Virginia Class A contractor license must pass the Virginia, General, and Advanced portions. Applicants should review the Virginia Board for Contractors requirements for current licensing information and any additional requirements associated with their classification or specialty.
What exams are required for a Virginia Class B contractor license?
For the business examination, the Designated Employee for a Virginia Class B contractor license must pass the Virginia and General portions. Other licensing requirements can apply depending on the classification or specialty being pursued.
Is Virginia's eight-hour pre-license course the same as exam prep?
No. Virginia's eight-hour pre-license education course is a separate licensing requirement from the Class A and Class B business examinations. Exam preparation is designed to help candidates study and practice for the examination itself.
How should I study for the Virginia contractor exam?
Start by confirming which exam portions you need and studying the subjects those portions cover. Become familiar with your applicable reference materials, complete realistic practice questions, and practice under time constraints. Use your practice results to identify the topics or exam skills that need additional work.
How do I know when I'm ready to take the Virginia contractor exam?
Your practice performance is a better indicator than the number of hours you've studied. You should be able to work through realistic questions within the appropriate time constraints, navigate your reference materials efficiently, and consistently identify and correct weaknesses before scheduling the exam.
Build your knowledge and sharpen your skills—get contractor tips, tools, and updates straight to your inbox. Sign up today!
By providing my personal information, including phone number, I consent to receive email messages, auto-dialed calls, texts, and prerecorded messages from Contractor Training Center with information and offers, including current and possible future services, customer service and billing and agree to the Terms of Service & Privacy Policy. If, at any time, you wish to opt out of electronic or text communications, reply STOP to cancel, HELP for help. Msg & data rates may apply. To opt out of email, follow the unsubscribe process on the email communication. I understand that my consent is not required to purchase, and that cancellation of purchase does not automatically revoke this consent.
Choosing a selection results in a full page refresh.