{"version":3,"file":"chunk.common_INJqqS6p.esm.js","sources":["../../node_modules/@shopify/bugsnag-light-core/dist/index.mjs","../../src/__deprecated__/constants/loginDefault.ts","../../src/__deprecated__/common/utils/isCompactLayout.ts","../../src/config.ts","../../src/__deprecated__/common/constants.ts","../../src/__deprecated__/common/bugsnag/constants.ts","../../src/__deprecated__/common/bugsnag/utils.ts","../../src/__deprecated__/common/bugsnag/index.ts","../../src/__deprecated__/common/init/index.ts","../../node_modules/tslib/tslib.es6.js","../../src/__deprecated__/common/utils/constraintWidthInViewport.ts","../../node_modules/@shopify/monorail/lib/esm/_virtual/_rollupPluginBabelHelpers.mjs","../../node_modules/@shopify/monorail/lib/esm/config/endpoints.mjs","../../node_modules/@shopify/monorail/lib/esm/middleware/producer-middleware.mjs","../../node_modules/@shopify/monorail/lib/esm/events/events.mjs","../../node_modules/@shopify/monorail/lib/esm/helpers/uuid.mjs","../../node_modules/@shopify/monorail/lib/esm/helpers/convert-case.mjs","../../node_modules/@shopify/monorail/lib/esm/producers/producer-errors.mjs","../../node_modules/@shopify/monorail/lib/esm/producers/http-producer.mjs","../../node_modules/@shopify/monorail/lib/esm/producers/log-producer.mjs","../../node_modules/@shopify/monorail/lib/esm/producers/monorail-edge-producer.mjs","../../src/__deprecated__/dynamicImports/opentelemetry/metrics.ts","../../src/__deprecated__/dynamicImports/opentelemetry/options.ts","../../src/__deprecated__/dynamicImports/opentelemetry/singleton.ts","../../src/__deprecated__/dynamicImports/opentelemetry/opentelemetry.ts","../../src/__deprecated__/dynamicImports/opentelemetry/record.ts","../../src/__deprecated__/common/utils/cookies.ts","../../src/__deprecated__/common/utils/cookieExchange.ts","../../src/__deprecated__/common/utils/storage.ts","../../node_modules/uuid/dist/esm-browser/stringify.js","../../node_modules/uuid/dist/esm-browser/rng.js","../../node_modules/uuid/dist/esm-browser/native.js","../../node_modules/uuid/dist/esm-browser/v4.js","../../src/__deprecated__/common/utils/utils.ts","../../src/__deprecated__/common/utils/email.ts","../../src/__deprecated__/common/utils/dom.ts","../../node_modules/@floating-ui/utils/dist/floating-ui.utils.mjs","../../node_modules/@floating-ui/core/dist/floating-ui.core.mjs","../../node_modules/@floating-ui/utils/dist/floating-ui.utils.dom.mjs","../../node_modules/@floating-ui/dom/dist/floating-ui.dom.mjs","../../src/__deprecated__/common/shop-sheet-modal/constants-compact.ts","../../src/__deprecated__/common/utils/position.behavior.ts","../../src/__deprecated__/common/utils/position.ts","../../src/__deprecated__/common/utils/shopHub.ts","../../src/__deprecated__/common/utils/errors.ts","../../src/__deprecated__/common/utils/removeOnePasswordPrompt.ts","../../src/__deprecated__/common/analytics/trekkie.ts","../../src/__deprecated__/common/analytics/types.ts","../../src/__deprecated__/common/analytics/utils.ts","../../src/__deprecated__/common/analytics/MonorailTracker.ts","../../src/__deprecated__/common/InputListener.ts","../../src/__deprecated__/common/logging.ts","../../src/__deprecated__/common/utils/coerce.ts","../../src/__deprecated__/common/MessageEventSource.ts","../../src/__deprecated__/common/MessageListener.ts","../../src/__deprecated__/common/utils/urls.ts","../../src/__deprecated__/types/avatar.ts","../../src/__deprecated__/types/loginButton.ts","../../src/__deprecated__/common/translator/i18n.ts","../../src/__deprecated__/types/paymentTerms.ts","../../src/__deprecated__/types/classicCustomerAccounts.ts","../../src/__deprecated__/common/WebComponent.ts","../../src/__deprecated__/common/ConnectedWebComponent.ts","../../src/__deprecated__/common/MessageSender.ts","../../src/__deprecated__/constants/loginButton.ts","../../src/__deprecated__/common/shop-sheet-modal/constants.ts","../../src/__deprecated__/constants/followButton.ts","../../src/__deprecated__/common/utils/booleanQueryParam.ts","../../src/__deprecated__/common/colors.ts","../../src/__deprecated__/common/shop-pay-logo.ts","../../src/__deprecated__/common/svg/animated-shop-logo.ts","../../src/__deprecated__/common/svg/large-spinner.ts","../../src/__deprecated__/common/svg/shop-close-icon.ts","../../src/__deprecated__/common/svg/shop-discount-icon.ts","../../src/__deprecated__/common/svg/shop-heart-icon.ts","../../src/__deprecated__/common/svg/shop-logo.ts","../../src/__deprecated__/common/shop-sheet-modal/shop-sheet-modal.utils.ts","../../src/__deprecated__/common/shop-sheet-modal/shop-sheet-modal.ts","../../src/__deprecated__/common/shop-sheet-modal/shop-sheet-modal-builder.ts","../../src/__deprecated__/common/shop-sheet-modal/createSafeWrapperInBody.ts","../../node_modules/dompurify/dist/purify.js","../../src/__deprecated__/components/payButtonBase/shop-pay-button-base.ts","../../src/__deprecated__/components/payButtonBase/constants.ts","../../src/__deprecated__/common/utils/attributeValidator.ts","../../src/__deprecated__/components/payButton/types.ts","../../src/__deprecated__/components/payButton/utils.ts","../../src/__deprecated__/components/payButton/shop-pay-button.ts","../../src/__deprecated__/common/shop-status-indicator.ts","../../src/__deprecated__/common/utils/storageManager.ts"],"sourcesContent":["var b=/^\\s*at .*(\\S+:\\d+|\\(native\\))/m,L=/^(eval@)?(\\[native code])?$/;function p(t){return t.stack?t.stack.match(b)?C(t):w(t):[]}function E(t){if(t.indexOf(\":\")===-1)return[t];let r=/(.+?)(?::(\\d+))?(?::(\\d+))?$/.exec(t.replace(/[()]/g,\"\"));return[r[1],r[2]?Number(r[2]):void 0,r[3]?Number(r[3]):void 0]}function C(t){return t.stack.split(`\n`).filter(r=>!!r.match(b)).map(r=>{let n=r.replace(/^\\s+/,\"\").replace(/^.*?\\s+/,\"\"),a=n.match(/ (\\(.+\\)$)/);n=a?n.replace(a[0],\"\"):n;let s=E(a?a[1]:n),o=a&&n||void 0,i=[\"eval\",\"\"].indexOf(s[0])>-1?void 0:s[0];return{method:o,file:i,lineNumber:s[1],columnNumber:s[2]}})}function w(t){return t.stack.split(`\n`).filter(r=>!r.match(L)).map(r=>{if(r.indexOf(\"@\")===-1&&r.indexOf(\":\")===-1)return{method:r};let n=/((.*\".+\"[^@]*)?[^@]*)(?:@)/,a=r.match(n),s=a&&a[1]?a[1]:void 0,o=E(r.replace(n,\"\"));return{method:s,file:o[0],lineNumber:o[1],columnNumber:o[2]}})}var v=\"5\",m=class{breadcrumbs=[];apiKey;plugins;appId;appType;appVersion;releaseStage;locale;userAgent;metadata;persistedMetadata;onError;onPostErrorListeners=[];constructor(e){this.apiKey=e.apiKey,this.appType=e.appType,this.appId=e.appId,this.appVersion=e.appVersion,this.releaseStage=e.releaseStage,this.locale=e.locale,this.userAgent=e.userAgent,this.metadata=e.metadata,this.onError=e.onError,this.persistedMetadata={},this.plugins=e.plugins??[],this.plugins.forEach(r=>r.load(this)),this.leaveBreadcrumb(\"Bugsnag started\",void 0,\"state\")}addMetadata(e){for(let r of Object.keys(e))this.persistedMetadata[r]=e[r]}leaveBreadcrumb(e,r,n=\"manual\"){this.breadcrumbs.push({name:e,metaData:r,type:n,timestamp:new Date().toISOString()})}notify(e,{errorClass:r,severity:n,severityType:a,handled:s=!0,metadata:o,context:i}={}){let l={...this.metadata,...this.persistedMetadata,...o},u=this.buildBugsnagEvent({error:e,errorClass:r,severityType:a,handled:s,severity:n,metadata:l,context:i});if((this.onError?.(u,e)??!0)&&this.releaseStage!==\"development\"){let g=this.sendToBugsnag(u);return this.onPostErrorListeners.forEach(f=>f(u)),g}return Promise.resolve()}addOnPostError(e){this.onPostErrorListeners.push(e)}buildBugsnagEvent({error:e,errorClass:r,severity:n=\"error\",severityType:a=\"handledException\",handled:s,metadata:o={},context:i}){let d=new Date().toISOString(),{breadcrumbs:l,appId:u,appType:y,appVersion:g,releaseStage:f,locale:R,userAgent:O}=this;return{payloadVersion:v,exceptions:[{errorClass:r??e.name,stacktrace:B(u,e),message:e.message}],severity:n,severityReason:{type:a},unhandled:!s,app:{id:u,type:y,version:g,releaseStage:f},device:{time:d,locale:R,userAgent:O},breadcrumbs:l,context:i,metaData:o}}async sendToBugsnag(e){let{apiKey:r}=this,n={apiKey:r,notifier:{name:\"Bugsnag JavaScript\",version:\"7.22.2\",url:\"https://github.com/bugsnag/bugsnag-js\"},events:[e]};try{await fetch(\"https://notify.bugsnag.com/\",{method:\"POST\",headers:{\"Content-Type\":\"application/json\",\"Bugsnag-Api-Key\":r,\"Bugsnag-Payload-Version\":v,\"Bugsnag-Sent-At\":e.device.time},body:JSON.stringify(n)})}catch(a){console.warn(\"[bugsnag-light] failed to send an event\"),console.warn(a)}}};function B(t,e){return p(e).map(n=>{let a=n.file?.includes(t);return{method:n.method??\"\",file:n.file??\"\",lineNumber:n.lineNumber??0,columnNumber:n.columnNumber,inProject:a}})}function k(t){let e=window.onerror;window.onerror=(r,n,a,s,o)=>{o&&t.notify(o,{severityType:\"unhandledException\",handled:!1}),typeof e==\"function\"&&e.apply(window.onerror,[r,n,a,s,o])}}function T(t){window.addEventListener(\"unhandledrejection\",({reason:e})=>{e&&t.notify(e,{severityType:\"unhandledPromiseRejection\",handled:!1})})}var M={load(t){t.addOnPostError(e=>{t.leaveBreadcrumb(e.exceptions[0].errorClass,{errorClass:e.exceptions[0].errorClass,errorMessage:e.exceptions[0].message,severity:e.severity},\"error\")})}};function c(t){return typeof t==\"object\"&&t!==null&&!Array.isArray(t)}var A={load(t){\"addEventListener\"in self&&self.addEventListener(\"click\",e=>{let r=\"[hidden]\";try{let n=I(e.target)?e.target:null;r=n?P(n):\"(Non-Element Target)\"}catch{}t.leaveBreadcrumb(\"UI click\",{targetSelector:r},\"user\")},!0)}};function I(t){return c(t)&&t.nodeType===Node.ELEMENT_NODE}function P(t){let e=t.tagName;if(t.id&&(e+=`#${t.id}`),t.className?.length&&(e+=`.${t.className.replace(/ /g,\".\")}`),!self.document.querySelectorAll)return e;try{if(self.document.querySelectorAll(e).length===1)return e}catch{return e}if(t.parentNode&&t.parentNode.childNodes.length>1){let r=Array.from(t.parentNode.children).indexOf(t)+1;e+=`:nth-child(${r})`}return self.document.querySelectorAll(e).length===1?e:t.parentElement?`${P(t.parentElement)} > ${e}`:e}var $={load(t){let e=[\"log\",\"debug\",\"info\",\"warn\",\"error\"].filter(r=>typeof console<\"u\"&&typeof console[r]==\"function\");for(let r of e){let n=console[r];console[r]=(...a)=>{t.leaveBreadcrumb(\"Console output\",a.reduce((s,o,i)=>{let d=\"[Unknown value]\";try{d=String(o)}catch{}if(d===\"[object Object]\")try{d=JSON.stringify(o)}catch{}return s[`[${i}]`]=d,s},{severity:r}),\"log\"),n.apply(console,a)}}}};var j={load(t){if(!(\"addEventListener\"in self))return;let e=n=>()=>t.leaveBreadcrumb(n,void 0,\"navigation\");self.addEventListener(\"pagehide\",e(\"Page hidden\"),!0),self.addEventListener(\"pageshow\",e(\"Page shown\"),!0),self.addEventListener(\"load\",()=>{e(\"Page loaded\"),self.addEventListener(\"popstate\",e(\"Navigated back\"),!0)},!0),self.document?.addEventListener(\"DOMContentLoaded\",e(\"DOMContentLoaded\"),!0),self.location&&self.addEventListener(\"hashchange\",n=>t.leaveBreadcrumb(\"Hash changed\",{from:n.oldURL&&h(n.oldURL),to:h(n.oldURL?n.newURL:self.location.href),state:n.oldURL&&x(self)},\"navigation\"),!0);let r=t.leaveBreadcrumb.bind(t);self.history&&self instanceof Window&&(typeof self.history.replaceState==\"function\"&&S({fn:\"replaceState\",target:self.history,leaveBreadcrumb:r,win:self}),typeof self.history.pushState==\"function\"&&S({fn:\"pushState\",target:self.history,leaveBreadcrumb:r,win:self}))}};function h(t){try{let e=new URL(t);return`${e.pathname}${e.search}${e.hash}`}catch{return t}}function x(t){try{return t.history.state}catch{return{}}}function S({fn:t,leaveBreadcrumb:e,target:r,win:n}){let a=r[t];r[t]=(s,o,i)=>{e(`History ${t}`,q({win:n,state:s,title:o,url:i}),\"navigation\"),a.apply(r,[s,o,i])}}function q({win:t,state:e,title:r,url:n}){let a=h(t.location.href);return{title:r,state:e,prevState:x(t),to:n||a,from:a}}var U={load(t){if(!(\"fetch\"in self))return;let e=self.fetch;self.fetch=function(n,a){let s=\"GET\",o;H(n)?(o=n.url,s=n.method):o=n.toString(),a&&typeof a.method==\"string\"&&a.method.length&&(s=a.method);let i=t.leaveBreadcrumb.bind(t);return new Promise((d,l)=>{e(n,a).then(u=>{N({message:`fetch() ${u.status>=400?\"failed\":\"succeeded\"}`,method:s,status:u.status,url:o,leaveBreadcrumb:i}),d(u)}).catch(u=>{N({message:\"fetch() error\",method:s,url:o,leaveBreadcrumb:i}),l(u)})})}}};function H(t){return t instanceof Request||c(t)&&\"url\"in t}function N({message:t,method:e,status:r,url:n,leaveBreadcrumb:a}){n.startsWith(\"https://notify.bugsnag\")||a(t,{status:r,request:`${e} ${n}`},\"request\")}export{m as BugsnagLight,M as ErrorBreadcrumbsPlugin,A as InteractionBreadcrumbsPlugin,$ as LogBreadcrumbsPlugin,j as NavigationBreadcrumbsPlugin,U as RequestBreadcrumbsPlugin,B as formatStackTrace,p as parseErrorStack,k as registerOnErrorHandler,T as registerUnhandledPromiseRejectionHandler};\n//# sourceMappingURL=index.mjs.map","/**\n * The default/standalone component is used for multiple flows. To disambiguate the flow for\n * analytics, we pass in an analytics context to the component. The \"flow\" here is specific\n * to the use-case, whereas the flow we pass to the authorize endpoint is more generic and\n * determines what (if any) side effects should happen after the user is authenticated.\n *\n * NOTE: The context name needs to be match those allow-listed in Pay.\n */\nexport enum DefaultComponentAnalyticsContext {\n Default = 'loginWithShop',\n CheckoutModal = 'loginWithShopCheckoutModal',\n ClassicCustomerAccounts = 'loginWithShopClassicCustomerAccounts',\n Prequal = 'loginWithShopPrequal',\n Web = 'loginWithShopShopWeb',\n SelfServe = 'loginWithShopSelfServe',\n CheckoutExtension = 'loginWithShopCheckoutExtension',\n PaymentRequest = 'loginWithShopPaymentRequest',\n CheckoutSheet = 'checkout_sheet',\n}\nexport const ANALYTICS_CONTEXT_TO_FLOW_MAP: Record<\n DefaultComponentAnalyticsContext,\n string\n> = {\n [DefaultComponentAnalyticsContext.Default]: 'default',\n [DefaultComponentAnalyticsContext.SelfServe]: 'default',\n [DefaultComponentAnalyticsContext.ClassicCustomerAccounts]:\n 'classic_customer_accounts',\n [DefaultComponentAnalyticsContext.Prequal]: 'shop_pay_installments_prequal',\n [DefaultComponentAnalyticsContext.PaymentRequest]: 'payment_request',\n [DefaultComponentAnalyticsContext.CheckoutExtension]: 'default',\n [DefaultComponentAnalyticsContext.CheckoutModal]: 'checkout_modal',\n [DefaultComponentAnalyticsContext.CheckoutSheet]: 'checkout_sheet',\n [DefaultComponentAnalyticsContext.Web]: '',\n};\n\nconst ELEMENT_PREFIX = 'shop-login-default';\nexport const IFRAME_CLASS_NAME = `${ELEMENT_PREFIX}-iframe`;\nexport const IFRAME_COMPACT_CLASS_NAME = `${ELEMENT_PREFIX}-iframe-compact`;\nexport const HEADER_CLASS_NAME = `${ELEMENT_PREFIX}-header`;\nexport const HEADER_CONTENTS_CONTAINER_CLASS_NAME = `${HEADER_CLASS_NAME}-contents-container`;\nexport const HEADER_TITLE_CLASS_NAME = `${HEADER_CLASS_NAME}-title`;\nexport const HEADER_DESCRIPTION_CLASS_NAME = `${HEADER_CLASS_NAME}-description`;\nexport const HEADER_DIVIDER_CLASS_NAME = `${HEADER_CLASS_NAME}-divider`;\nexport const FOOTER_CLASS_NAME = `${ELEMENT_PREFIX}-footer`;\nexport const FOOTER_CONTENT_CLASS_NAME = `${FOOTER_CLASS_NAME}-content`;\nexport const HIDDEN_ELEMENT_CLASS_NAME = `${ELEMENT_PREFIX}-hidden`;\nexport const CONTENT_CLASS_NAME = `${ELEMENT_PREFIX}-content`;\n\nconst RADIUS = `20px`;\nconst SMALL_SCREEN_THRESHOLD = 448;\n\nexport const getShopLoginDefaultTemplate = (extraAttributes = '') => `\n`;\n\nexport const HEADER_STYLE = `\n \n`;\n","import {DefaultComponentAnalyticsContext} from '../../constants/loginDefault';\n\nconst ANALYTICS_CONTEXTS_TO_COMPACT = [\n DefaultComponentAnalyticsContext.CheckoutModal,\n DefaultComponentAnalyticsContext.ClassicCustomerAccounts,\n DefaultComponentAnalyticsContext.Web,\n DefaultComponentAnalyticsContext.SelfServe,\n];\n\n/**\n * @param {string} analyticsContext the analytics context string\n * @returns {boolean} the given comtext is eligible for compact layout\n */\nexport function checkEligibleForCompactLayout(\n analyticsContext: DefaultComponentAnalyticsContext,\n): boolean {\n const applyCompactToAnalyticsContext = analyticsContext\n ? ANALYTICS_CONTEXTS_TO_COMPACT.includes(analyticsContext)\n : false;\n\n return applyCompactToAnalyticsContext;\n}\n","// eslint-disable-next-line import/no-anonymous-default-export\nexport default {\n bugsnagApiKey: 'e35d7136cee78d344ccffdbd5ca710fa',\n};\n","export const BUGSNAG_APP_ID = 'shop-js';\n\n// Set by rollup replace plugin\nexport const APP_VERSION = '__buildVersion';\n\nexport const SHOPIFY_S_COOKIE = '_shopify_s';\nexport const SHOPIFY_Y_COOKIE = '_shopify_y';\n\nexport const SPIN_DOMAIN_SUFFIX = /spin\\.(dev|shopify\\.io)$/;\nexport const SPIN_URL_SUFFIX = /\\.(?:(?:\\w|-)+\\.){3}spin\\.(dev|shopify\\.io)$/;\n\nexport const POPUP_CLOSE_CHECK_INTERVAL = 1000;\n\nexport const SIGN_IN_FORM_DATA_ATTRIBUTE = 'data-login-with-shop-sign-in';\nexport const SIGN_UP_FORM_DATA_ATTRIBUTE = 'data-login-with-shop-sign-up';\nconst SIGN_IN_FORM_SELECTOR = `form[${SIGN_IN_FORM_DATA_ATTRIBUTE}]`;\nconst SIGN_UP_FORM_SELECTOR = `form[${SIGN_UP_FORM_DATA_ATTRIBUTE}]`;\n\n// See https://shopify.dev/docs/themes/customer-engagement/additional-customer-information for input field names\nexport const CUSTOMER_EMAIL_INPUT_SELECTOR = 'input[name=\"customer[email]\"';\nexport const CUSTOMER_FIRST_NAME_INPUT_SELECTOR =\n 'input[name=\"customer[first_name]\"';\nexport const CUSTOMER_LAST_NAME_INPUT_SELECTOR =\n 'input[name=\"customer[last_name]\"';\n\nexport const SIGN_IN_FORM_EMAIL_INPUT_SELECTOR = `${SIGN_IN_FORM_SELECTOR} input[type=\"email\"],${SIGN_IN_FORM_SELECTOR} ${CUSTOMER_EMAIL_INPUT_SELECTOR}`;\nexport const SIGN_UP_FORM_EMAIL_INPUT_SELECTOR = `${SIGN_UP_FORM_SELECTOR} input[type=\"email\"],${SIGN_UP_FORM_SELECTOR} ${CUSTOMER_EMAIL_INPUT_SELECTOR}`;\n\nexport const MAX_Z_INDEX = '2147483647';\n","import type {ReleaseStage} from '@shopify/bugsnag-light-core';\n\nexport const RELEASE_STAGES: Record = {\n dev: 'development',\n spin: 'spin',\n staging: 'staging',\n prod: 'production',\n};\n\n/*\nThis is the notifier object Bugsnag's own JS client sends. It is required to trigger Bugsnag\nserver-side parsing of the `useragent` string as well as client IP logging.\n */\nexport const BUGSNAG_NOTIFIER = {\n name: 'Bugsnag JavaScript',\n version: '7.13.2',\n url: 'https://github.com/bugsnag/bugsnag-js',\n};\n","import {DefaultComponentAnalyticsContext} from '__deprecated__/constants/loginDefault';\nimport {parseErrorStack} from '@shopify/bugsnag-light-core';\nimport type {\n BugsnagClient,\n BugsnagEvent,\n ReleaseStage,\n} from '@shopify/bugsnag-light-core';\n\nimport {checkEligibleForCompactLayout} from '../utils/isCompactLayout';\nimport config from '../../../config';\nimport {BUGSNAG_APP_ID, APP_VERSION} from '../constants';\n\nimport {RELEASE_STAGES} from './constants';\n\n/**\n * Checks which environment shop-js is running in and returns the appropriate\n * release stage string. This corresponds to the Stage filter in the Bugsnag console.\n * @typedef ReleaseStage\n * @returns {ReleaseStage} The release stage that corresponds to this environment.\n */\nexport function getReleaseStage(): ReleaseStage {\n // Gets set at build time by rollup-replace\n // eslint-disable-next-line no-process-env\n const nodeEnv = process.env.NODE_ENV;\n\n switch (nodeEnv) {\n case 'spin':\n return RELEASE_STAGES.spin;\n case 'staging':\n return RELEASE_STAGES.staging;\n case 'production':\n return RELEASE_STAGES.prod;\n case 'development':\n default:\n return RELEASE_STAGES.dev;\n }\n}\n\n/**\n * Checks whether an error originated in shop-js.\n * @param {Error} error An error object.\n * @returns {boolean} `true` if the given error came from shop-js, `false` otherwise.\n */\nexport function isShopJsError(error: Error): boolean {\n const stack = parseErrorStack(error);\n if (stack.length === 0) return false;\n return stack.some((frame) => frame.file?.includes('shopifycloud/shop-js'));\n}\n\n/**\n * Adds the URLs of all shop-js bundles on the page to the Bugsnag event metadata.\n * This does not tell us which bundle the error came from, but it's still valuable\n * data to have.\n * @param {BugsnagEvent} event The Bugsnag Event to add metadata to.\n */\nfunction addBundleMetadata(event: BugsnagEvent) {\n const shopJsUrls = (\n Array.from(\n document.querySelectorAll('script[src*=\"/shop-js/\"]'),\n ) as HTMLScriptElement[]\n ).map((scriptTag) => scriptTag.src);\n addMetadata(event, {shopJsUrls});\n}\n\n/**\n * Adds metadata to the Bugsnag event to indicate whether the window.Shopify.featureAssets\n * object exists. We want to be conscious of the payload we send to Bugsnag, so sending the\n * entire object is not ideal. This is a compromise.\n * @param {BugsnagEvent} event The Bugsnag Event to add metadata to.\n */\nfunction addFeatureAssetsMetadata(event: BugsnagEvent) {\n const featureAssets: Record | undefined =\n window.Shopify?.featureAssets?.['shop-js'];\n const featureAssetsNonEmpty = Boolean(\n featureAssets && Object.keys(featureAssets).length > 0,\n );\n addMetadata(event, {shopJsFeatureAssetsExist: featureAssetsNonEmpty});\n}\n\n/**\n * Adds metadata to the Bugsnag event to indicate whether the compact UX is being used.\n * @param {BugsnagEventType} event The Bugsnag Event to add metadata to.\n */\nfunction addCompactUXMetadata(event: BugsnagEvent) {\n const compactShopLoginButton = Array.from(\n document.querySelectorAll('shop-login-button[compact]'),\n );\n compactShopLoginButton.filter((el) =>\n checkEligibleForCompactLayout(\n el.getAttribute('analytics-context') as DefaultComponentAnalyticsContext,\n ),\n );\n addMetadata(event, {compactUX: compactShopLoginButton.length > 0});\n}\n\n/**\n * Adds metadata to the Bugsnag event to identify the current domain.\n * @param {BugsnagEventType} event The Bugsnag Event to add metadata to.\n */\nfunction addDomainMetadata(event: BugsnagEvent) {\n const domain = window?.location?.hostname;\n addMetadata(event, {domain});\n}\n\n/**\n * Adds the error class and error message as a grouping hash to the Bugsnag event.\n * @param {BugsnagEvent} event The Bugsnag Event to add groupHash to.\n */\nfunction addGroupingHash(event: BugsnagEvent): void {\n const groupingHash = `${event.exceptions[0].errorClass}:${event.exceptions[0].message}`;\n event.groupingHash = groupingHash;\n}\n\n/**\n * Adds metadata to a Bugsnag event.\n * @param {BugsnagEvent} event The Bugsnag Event to add metadata to.\n * @param metadata\n */\nfunction addMetadata(event: BugsnagEvent, metadata: any) {\n event.metaData = {...event.metaData, ...metadata};\n}\n\n/**\n * Adds the current URL to the Bugsnag event request.\n * @param {BugsnagEvent} event The Bugsnag Event to add metadata to.\n */\nfunction addRequest(event: BugsnagEvent) {\n event.request = {\n url: window.location.href,\n };\n}\n\n/**\n * Adds the device information to the Bugsnag event.\n * @param {BugsnagEvent} event The Bugsnag Event to add metadata to.\n */\nfunction addDevice(event: BugsnagEvent) {\n const now = new Date();\n const time = now.toISOString();\n event.device = {\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore\n locale: navigator.userLanguage || navigator.language,\n userAgent: navigator.userAgent,\n orientation: window.screen?.orientation?.type,\n time,\n };\n}\n\n/**\n * Adds the metadata and other relevant information to a Bugsnag event.\n * @param {BugsnagEvent} event The Bugsnag Event to add metadata to.\n */\nfunction onError(event: BugsnagEvent) {\n addBundleMetadata(event);\n addFeatureAssetsMetadata(event);\n addCompactUXMetadata(event);\n addDomainMetadata(event);\n addGroupingHash(event);\n addRequest(event);\n addDevice(event);\n}\n\n/**\n * Creates a Bugsnag client params metadata and with the default params.\n * @param metadata\n * @returns {BugsnagLightParams} The Bugsnag Params.\n */\nexport function createBugsnagParams(metadata: any) {\n return {\n apiKey: config.bugsnagApiKey,\n appId: BUGSNAG_APP_ID,\n appVersion: APP_VERSION,\n metadata: {\n // eslint-disable-next-line no-process-env\n bundleLocale: process.env.BUILD_LOCALE,\n ...metadata,\n } as any,\n onError,\n releaseStage: getReleaseStage(),\n };\n}\n\n/**\n * Adds a generic Bugsnag error handler to the window object.\n * @param {BugsnagLight} bugsnagClient\n */\nexport function addGenericBugsnagOnError(bugsnagClient: BugsnagClient) {\n if (!window) return;\n\n window.addEventListener('error', (event) => {\n const {error} = event;\n if (error && isShopJsError(error)) {\n bugsnagClient.notify(error);\n }\n });\n}\n","import {BugsnagLight} from '@shopify/bugsnag-light-core';\nimport type {BreadcrumbType, NotifyOptions} from '@shopify/bugsnag-light-core';\n\nimport {\n createBugsnagParams,\n getReleaseStage,\n addGenericBugsnagOnError,\n} from './utils';\nimport {RELEASE_STAGES} from './constants';\n\nlet client: BugsnagLight | undefined;\n\nconst Bugsnag = {\n /**\n * Start Bugsnag. Must be called before any other Bugsnag methods.\n * @param params\n * @param params.metadata Initial metadata to send with all captured events.\n */\n start: ({metadata}: {metadata: any}) => {\n if (client) {\n // eslint-disable-next-line no-console\n console.log('Bugsnag.start() has already been called. Ignoring.');\n return;\n }\n client = new BugsnagLight(createBugsnagParams(metadata));\n addGenericBugsnagOnError(client);\n },\n\n /**\n * Add a breadcrumb to the stack. Breadcrumbs are sent to Bugsnag when an error is sent, providing additional\n * data on what happened prior to the error.\n * @param {string} name The name of the breadcrumb.\n * @param {any} metaData Any additional data to send with the breadcrumb.\n * @param {BreadcrumbType} type The type of breadcrumb (i.e. \"navigation\" or \"request\"). See BreadcrumbType for options.\n */\n leaveBreadcrumb: (name: string, metaData: any, type: BreadcrumbType) => {\n if (!client) {\n // eslint-disable-next-line no-console\n console.log('Bugsnag.leaveBreadcrumb() called before start().');\n return;\n }\n\n if (getReleaseStage() === RELEASE_STAGES.spin) {\n // eslint-disable-next-line no-console\n console.log('[Bugsnag leaveBreadcrumb called]', name, metaData, type);\n return;\n }\n\n client.leaveBreadcrumb(name, metaData, type);\n },\n\n /**\n * Send a notification to Bugsnag.\n * @param {Error} error The error to log.\n * @param {BeforeNotifyCallback} onBeforeNotify Optional callback allows modifying the event before it is sent to Bugsnag.\n * Use to set `severity` or add metadata with the `addMetadata` function call. If callback returns false, the event will\n * not be sent. Should behave similar to the `onError` callback of the official Bugsnag client:\n * https://docs.bugsnag.com/platforms/javascript/reporting-handled-errors/#customizing-diagnostic-data\n * @param options\n */\n notify: (error: Error, options?: NotifyOptions) => {\n if (!client) {\n // eslint-disable-next-line no-console\n console.log('Bugsnag.notify() called before start().');\n return;\n }\n\n if (getReleaseStage() === RELEASE_STAGES.spin) {\n // eslint-disable-next-line no-console\n console.log('[Bugsnag notify called]', error);\n return;\n }\n\n client.notify(error, options);\n },\n};\n\nexport default Bugsnag;\n","import Bugsnag from '../bugsnag';\n\n/**\n * @returns {boolean} Whether the browser supports Web Components.\n */\nexport function isBrowserSupported(): boolean {\n return Boolean(window.customElements);\n}\n\n/**\n * Define a custom element (web component) if the browser supports custom elements and if it has not been\n * previously defined.\n * @param {string} name Name for the new custom element. This will be the distinct HTML tag in kebab-case\n * by which the element will be created. Note that custom element names must contain a hyphen.\n * @param {object} component Constructor for the new custom element.\n */\nexport function defineCustomElement(\n name: string,\n component: CustomElementConstructor,\n) {\n // Return early if the browser doesn't support Web Components.\n if (!window.customElements) return;\n\n const existingConstructor = customElements.get(name);\n if (existingConstructor) {\n return;\n }\n\n Reflect.defineProperty?.(component, 'componentVersion', {value: 'vanilla'});\n customElements.define(name, component);\n}\n\n/**\n * Util for starting Bugsnag with the correct configuration. Deliberately put outside /common/bugsnag to\n * keep that as a pure Bugsnag client implementation.\n * @param {object} metadata Diagnostic metadata that you want to send with all captured events.\n */\nexport function startBugsnag(metadata = {}) {\n Bugsnag.start({metadata});\n}\n\n/**\n * Define the window.Shopify.SignInWithShop object if it doesn't exist.\n */\nexport function defineWindowSignInWithShop() {\n if (!window.Shopify) {\n window.Shopify = {};\n }\n\n if (!window.Shopify.SignInWithShop) {\n window.Shopify.SignInWithShop = {};\n }\n}\n\n/**\n * Adds an init function to the window.\n * @param {string} signInWithShopKey The key to be added to window.Shopify.SignInWithShop\n * @param {Function} initFunction The corresponding init function\n */\nexport function defineInitFunction(\n signInWithShopKey: string,\n initFunction: (arg0: any) => any,\n) {\n defineWindowSignInWithShop();\n\n window.Shopify.SignInWithShop[signInWithShopKey] = initFunction;\n}\n\n/**\n * Returns whether the init function was called before.\n * @param {string} signInWithShopKey The key added to window.Shopify.SignInWithShop\n * @returns {boolean} Whether the function was called before.\n */\nexport function getFunctionCalled(signInWithShopKey: string): boolean {\n return Boolean(\n window.Shopify?.SignInWithShop?.[`${signInWithShopKey}Called`],\n );\n}\n\n/**\n * Marks the init function as called.\n * @param {string} signInWithShopKey The key added to window.Shopify.SignInWithShop.\n */\nexport function setFunctionCalled(signInWithShopKey: string) {\n defineWindowSignInWithShop();\n window.Shopify.SignInWithShop[`${signInWithShopKey}Called`] = true;\n}\n","/******************************************************************************\r\nCopyright (c) Microsoft Corporation.\r\n\r\nPermission to use, copy, modify, and/or distribute this software for any\r\npurpose with or without fee is hereby granted.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH\r\nREGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY\r\nAND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,\r\nINDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM\r\nLOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR\r\nOTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR\r\nPERFORMANCE OF THIS SOFTWARE.\r\n***************************************************************************** */\r\n/* global Reflect, Promise, SuppressedError, Symbol */\r\n\r\nvar extendStatics = function(d, b) {\r\n extendStatics = Object.setPrototypeOf ||\r\n ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\r\n function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };\r\n return extendStatics(d, b);\r\n};\r\n\r\nexport function __extends(d, b) {\r\n if (typeof b !== \"function\" && b !== null)\r\n throw new TypeError(\"Class extends value \" + String(b) + \" is not a constructor or null\");\r\n extendStatics(d, b);\r\n function __() { this.constructor = d; }\r\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\r\n}\r\n\r\nexport var __assign = function() {\r\n __assign = Object.assign || function __assign(t) {\r\n for (var s, i = 1, n = arguments.length; i < n; i++) {\r\n s = arguments[i];\r\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];\r\n }\r\n return t;\r\n }\r\n return __assign.apply(this, arguments);\r\n}\r\n\r\nexport function __rest(s, e) {\r\n var t = {};\r\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)\r\n t[p] = s[p];\r\n if (s != null && typeof Object.getOwnPropertySymbols === \"function\")\r\n for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {\r\n if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))\r\n t[p[i]] = s[p[i]];\r\n }\r\n return t;\r\n}\r\n\r\nexport function __decorate(decorators, target, key, desc) {\r\n var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;\r\n if (typeof Reflect === \"object\" && typeof Reflect.decorate === \"function\") r = Reflect.decorate(decorators, target, key, desc);\r\n else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;\r\n return c > 3 && r && Object.defineProperty(target, key, r), r;\r\n}\r\n\r\nexport function __param(paramIndex, decorator) {\r\n return function (target, key) { decorator(target, key, paramIndex); }\r\n}\r\n\r\nexport function __esDecorate(ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) {\r\n function accept(f) { if (f !== void 0 && typeof f !== \"function\") throw new TypeError(\"Function expected\"); return f; }\r\n var kind = contextIn.kind, key = kind === \"getter\" ? \"get\" : kind === \"setter\" ? \"set\" : \"value\";\r\n var target = !descriptorIn && ctor ? contextIn[\"static\"] ? ctor : ctor.prototype : null;\r\n var descriptor = descriptorIn || (target ? Object.getOwnPropertyDescriptor(target, contextIn.name) : {});\r\n var _, done = false;\r\n for (var i = decorators.length - 1; i >= 0; i--) {\r\n var context = {};\r\n for (var p in contextIn) context[p] = p === \"access\" ? {} : contextIn[p];\r\n for (var p in contextIn.access) context.access[p] = contextIn.access[p];\r\n context.addInitializer = function (f) { if (done) throw new TypeError(\"Cannot add initializers after decoration has completed\"); extraInitializers.push(accept(f || null)); };\r\n var result = (0, decorators[i])(kind === \"accessor\" ? { get: descriptor.get, set: descriptor.set } : descriptor[key], context);\r\n if (kind === \"accessor\") {\r\n if (result === void 0) continue;\r\n if (result === null || typeof result !== \"object\") throw new TypeError(\"Object expected\");\r\n if (_ = accept(result.get)) descriptor.get = _;\r\n if (_ = accept(result.set)) descriptor.set = _;\r\n if (_ = accept(result.init)) initializers.unshift(_);\r\n }\r\n else if (_ = accept(result)) {\r\n if (kind === \"field\") initializers.unshift(_);\r\n else descriptor[key] = _;\r\n }\r\n }\r\n if (target) Object.defineProperty(target, contextIn.name, descriptor);\r\n done = true;\r\n};\r\n\r\nexport function __runInitializers(thisArg, initializers, value) {\r\n var useValue = arguments.length > 2;\r\n for (var i = 0; i < initializers.length; i++) {\r\n value = useValue ? initializers[i].call(thisArg, value) : initializers[i].call(thisArg);\r\n }\r\n return useValue ? value : void 0;\r\n};\r\n\r\nexport function __propKey(x) {\r\n return typeof x === \"symbol\" ? x : \"\".concat(x);\r\n};\r\n\r\nexport function __setFunctionName(f, name, prefix) {\r\n if (typeof name === \"symbol\") name = name.description ? \"[\".concat(name.description, \"]\") : \"\";\r\n return Object.defineProperty(f, \"name\", { configurable: true, value: prefix ? \"\".concat(prefix, \" \", name) : name });\r\n};\r\n\r\nexport function __metadata(metadataKey, metadataValue) {\r\n if (typeof Reflect === \"object\" && typeof Reflect.metadata === \"function\") return Reflect.metadata(metadataKey, metadataValue);\r\n}\r\n\r\nexport function __awaiter(thisArg, _arguments, P, generator) {\r\n function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }\r\n return new (P || (P = Promise))(function (resolve, reject) {\r\n function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\r\n function rejected(value) { try { step(generator[\"throw\"](value)); } catch (e) { reject(e); } }\r\n function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }\r\n step((generator = generator.apply(thisArg, _arguments || [])).next());\r\n });\r\n}\r\n\r\nexport function __generator(thisArg, body) {\r\n var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;\r\n return g = { next: verb(0), \"throw\": verb(1), \"return\": verb(2) }, typeof Symbol === \"function\" && (g[Symbol.iterator] = function() { return this; }), g;\r\n function verb(n) { return function (v) { return step([n, v]); }; }\r\n function step(op) {\r\n if (f) throw new TypeError(\"Generator is already executing.\");\r\n while (g && (g = 0, op[0] && (_ = 0)), _) try {\r\n if (f = 1, y && (t = op[0] & 2 ? y[\"return\"] : op[0] ? y[\"throw\"] || ((t = y[\"return\"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;\r\n if (y = 0, t) op = [op[0] & 2, t.value];\r\n switch (op[0]) {\r\n case 0: case 1: t = op; break;\r\n case 4: _.label++; return { value: op[1], done: false };\r\n case 5: _.label++; y = op[1]; op = [0]; continue;\r\n case 7: op = _.ops.pop(); _.trys.pop(); continue;\r\n default:\r\n if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }\r\n if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }\r\n if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }\r\n if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }\r\n if (t[2]) _.ops.pop();\r\n _.trys.pop(); continue;\r\n }\r\n op = body.call(thisArg, _);\r\n } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }\r\n if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };\r\n }\r\n}\r\n\r\nexport var __createBinding = Object.create ? (function(o, m, k, k2) {\r\n if (k2 === undefined) k2 = k;\r\n var desc = Object.getOwnPropertyDescriptor(m, k);\r\n if (!desc || (\"get\" in desc ? !m.__esModule : desc.writable || desc.configurable)) {\r\n desc = { enumerable: true, get: function() { return m[k]; } };\r\n }\r\n Object.defineProperty(o, k2, desc);\r\n}) : (function(o, m, k, k2) {\r\n if (k2 === undefined) k2 = k;\r\n o[k2] = m[k];\r\n});\r\n\r\nexport function __exportStar(m, o) {\r\n for (var p in m) if (p !== \"default\" && !Object.prototype.hasOwnProperty.call(o, p)) __createBinding(o, m, p);\r\n}\r\n\r\nexport function __values(o) {\r\n var s = typeof Symbol === \"function\" && Symbol.iterator, m = s && o[s], i = 0;\r\n if (m) return m.call(o);\r\n if (o && typeof o.length === \"number\") return {\r\n next: function () {\r\n if (o && i >= o.length) o = void 0;\r\n return { value: o && o[i++], done: !o };\r\n }\r\n };\r\n throw new TypeError(s ? \"Object is not iterable.\" : \"Symbol.iterator is not defined.\");\r\n}\r\n\r\nexport function __read(o, n) {\r\n var m = typeof Symbol === \"function\" && o[Symbol.iterator];\r\n if (!m) return o;\r\n var i = m.call(o), r, ar = [], e;\r\n try {\r\n while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);\r\n }\r\n catch (error) { e = { error: error }; }\r\n finally {\r\n try {\r\n if (r && !r.done && (m = i[\"return\"])) m.call(i);\r\n }\r\n finally { if (e) throw e.error; }\r\n }\r\n return ar;\r\n}\r\n\r\n/** @deprecated */\r\nexport function __spread() {\r\n for (var ar = [], i = 0; i < arguments.length; i++)\r\n ar = ar.concat(__read(arguments[i]));\r\n return ar;\r\n}\r\n\r\n/** @deprecated */\r\nexport function __spreadArrays() {\r\n for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length;\r\n for (var r = Array(s), k = 0, i = 0; i < il; i++)\r\n for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)\r\n r[k] = a[j];\r\n return r;\r\n}\r\n\r\nexport function __spreadArray(to, from, pack) {\r\n if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {\r\n if (ar || !(i in from)) {\r\n if (!ar) ar = Array.prototype.slice.call(from, 0, i);\r\n ar[i] = from[i];\r\n }\r\n }\r\n return to.concat(ar || Array.prototype.slice.call(from));\r\n}\r\n\r\nexport function __await(v) {\r\n return this instanceof __await ? (this.v = v, this) : new __await(v);\r\n}\r\n\r\nexport function __asyncGenerator(thisArg, _arguments, generator) {\r\n if (!Symbol.asyncIterator) throw new TypeError(\"Symbol.asyncIterator is not defined.\");\r\n var g = generator.apply(thisArg, _arguments || []), i, q = [];\r\n return i = {}, verb(\"next\"), verb(\"throw\"), verb(\"return\"), i[Symbol.asyncIterator] = function () { return this; }, i;\r\n function verb(n) { if (g[n]) i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; }\r\n function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(q[0][3], e); } }\r\n function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); }\r\n function fulfill(value) { resume(\"next\", value); }\r\n function reject(value) { resume(\"throw\", value); }\r\n function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); }\r\n}\r\n\r\nexport function __asyncDelegator(o) {\r\n var i, p;\r\n return i = {}, verb(\"next\"), verb(\"throw\", function (e) { throw e; }), verb(\"return\"), i[Symbol.iterator] = function () { return this; }, i;\r\n function verb(n, f) { i[n] = o[n] ? function (v) { return (p = !p) ? { value: __await(o[n](v)), done: false } : f ? f(v) : v; } : f; }\r\n}\r\n\r\nexport function __asyncValues(o) {\r\n if (!Symbol.asyncIterator) throw new TypeError(\"Symbol.asyncIterator is not defined.\");\r\n var m = o[Symbol.asyncIterator], i;\r\n return m ? m.call(o) : (o = typeof __values === \"function\" ? __values(o) : o[Symbol.iterator](), i = {}, verb(\"next\"), verb(\"throw\"), verb(\"return\"), i[Symbol.asyncIterator] = function () { return this; }, i);\r\n function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; }\r\n function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); }\r\n}\r\n\r\nexport function __makeTemplateObject(cooked, raw) {\r\n if (Object.defineProperty) { Object.defineProperty(cooked, \"raw\", { value: raw }); } else { cooked.raw = raw; }\r\n return cooked;\r\n};\r\n\r\nvar __setModuleDefault = Object.create ? (function(o, v) {\r\n Object.defineProperty(o, \"default\", { enumerable: true, value: v });\r\n}) : function(o, v) {\r\n o[\"default\"] = v;\r\n};\r\n\r\nexport function __importStar(mod) {\r\n if (mod && mod.__esModule) return mod;\r\n var result = {};\r\n if (mod != null) for (var k in mod) if (k !== \"default\" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);\r\n __setModuleDefault(result, mod);\r\n return result;\r\n}\r\n\r\nexport function __importDefault(mod) {\r\n return (mod && mod.__esModule) ? mod : { default: mod };\r\n}\r\n\r\nexport function __classPrivateFieldGet(receiver, state, kind, f) {\r\n if (kind === \"a\" && !f) throw new TypeError(\"Private accessor was defined without a getter\");\r\n if (typeof state === \"function\" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError(\"Cannot read private member from an object whose class did not declare it\");\r\n return kind === \"m\" ? f : kind === \"a\" ? f.call(receiver) : f ? f.value : state.get(receiver);\r\n}\r\n\r\nexport function __classPrivateFieldSet(receiver, state, value, kind, f) {\r\n if (kind === \"m\") throw new TypeError(\"Private method is not writable\");\r\n if (kind === \"a\" && !f) throw new TypeError(\"Private accessor was defined without a setter\");\r\n if (typeof state === \"function\" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError(\"Cannot write private member to an object whose class did not declare it\");\r\n return (kind === \"a\" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;\r\n}\r\n\r\nexport function __classPrivateFieldIn(state, receiver) {\r\n if (receiver === null || (typeof receiver !== \"object\" && typeof receiver !== \"function\")) throw new TypeError(\"Cannot use 'in' operator on non-object\");\r\n return typeof state === \"function\" ? receiver === state : state.has(receiver);\r\n}\r\n\r\nexport function __addDisposableResource(env, value, async) {\r\n if (value !== null && value !== void 0) {\r\n if (typeof value !== \"object\" && typeof value !== \"function\") throw new TypeError(\"Object expected.\");\r\n var dispose;\r\n if (async) {\r\n if (!Symbol.asyncDispose) throw new TypeError(\"Symbol.asyncDispose is not defined.\");\r\n dispose = value[Symbol.asyncDispose];\r\n }\r\n if (dispose === void 0) {\r\n if (!Symbol.dispose) throw new TypeError(\"Symbol.dispose is not defined.\");\r\n dispose = value[Symbol.dispose];\r\n }\r\n if (typeof dispose !== \"function\") throw new TypeError(\"Object not disposable.\");\r\n env.stack.push({ value: value, dispose: dispose, async: async });\r\n }\r\n else if (async) {\r\n env.stack.push({ async: true });\r\n }\r\n return value;\r\n}\r\n\r\nvar _SuppressedError = typeof SuppressedError === \"function\" ? SuppressedError : function (error, suppressed, message) {\r\n var e = new Error(message);\r\n return e.name = \"SuppressedError\", e.error = error, e.suppressed = suppressed, e;\r\n};\r\n\r\nexport function __disposeResources(env) {\r\n function fail(e) {\r\n env.error = env.hasError ? new _SuppressedError(e, env.error, \"An error was suppressed during disposal.\") : e;\r\n env.hasError = true;\r\n }\r\n function next() {\r\n while (env.stack.length) {\r\n var rec = env.stack.pop();\r\n try {\r\n var result = rec.dispose && rec.dispose.call(rec.value);\r\n if (rec.async) return Promise.resolve(result).then(next, function(e) { fail(e); return next(); });\r\n }\r\n catch (e) {\r\n fail(e);\r\n }\r\n }\r\n if (env.hasError) throw env.error;\r\n }\r\n return next();\r\n}\r\n\r\nexport default {\r\n __extends: __extends,\r\n __assign: __assign,\r\n __rest: __rest,\r\n __decorate: __decorate,\r\n __param: __param,\r\n __metadata: __metadata,\r\n __awaiter: __awaiter,\r\n __generator: __generator,\r\n __createBinding: __createBinding,\r\n __exportStar: __exportStar,\r\n __values: __values,\r\n __read: __read,\r\n __spread: __spread,\r\n __spreadArrays: __spreadArrays,\r\n __spreadArray: __spreadArray,\r\n __await: __await,\r\n __asyncGenerator: __asyncGenerator,\r\n __asyncDelegator: __asyncDelegator,\r\n __asyncValues: __asyncValues,\r\n __makeTemplateObject: __makeTemplateObject,\r\n __importStar: __importStar,\r\n __importDefault: __importDefault,\r\n __classPrivateFieldGet: __classPrivateFieldGet,\r\n __classPrivateFieldSet: __classPrivateFieldSet,\r\n __classPrivateFieldIn: __classPrivateFieldIn,\r\n __addDisposableResource: __addDisposableResource,\r\n __disposeResources: __disposeResources,\r\n};\r\n","/**\n * @file Contains a function to restrict resizing iframe width beyond the boundaries of viewport.\n * We are facing an issue regarding a new IOS update (17.4) which is firing resize event on the iframe\n * with width higher than expected. (Possibly a regression in Safari IOS 17.4)\n *\n * Events are fired twice: 1 before the content wrapper has a proper width, and 1 after with a the proper width.\n */\n\n/**\n * Calculate the size with boundaries to the parent element of iframe.\n * @param width - new width of the iframe\n * @param iframe - the iframe element\n * @returns {ResizeEvent} - the new size of the iframe\n */\nexport function constraintWidthInViewport(\n width: number,\n iframe: HTMLIFrameElement,\n): number {\n /**\n * At first render, the contentWidth is 0, so we need to wait for the next frame to get the correct value.\n * Meanwhile, we accept what it comes from the browser forcing the element to push.\n */\n const contentWidth = iframe.parentElement?.offsetWidth ?? 0;\n return Math.min(contentWidth, width) || width;\n}\n","function ownKeys(e, r) {\n var t = Object.keys(e);\n if (Object.getOwnPropertySymbols) {\n var o = Object.getOwnPropertySymbols(e);\n r && (o = o.filter(function (r) {\n return Object.getOwnPropertyDescriptor(e, r).enumerable;\n })), t.push.apply(t, o);\n }\n return t;\n}\nfunction _objectSpread2(e) {\n for (var r = 1; r < arguments.length; r++) {\n var t = null != arguments[r] ? arguments[r] : {};\n r % 2 ? ownKeys(Object(t), !0).forEach(function (r) {\n _defineProperty(e, r, t[r]);\n }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) {\n Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r));\n });\n }\n return e;\n}\nfunction _toPrimitive(t, r) {\n if (\"object\" != typeof t || !t) return t;\n var e = t[Symbol.toPrimitive];\n if (void 0 !== e) {\n var i = e.call(t, r || \"default\");\n if (\"object\" != typeof i) return i;\n throw new TypeError(\"@@toPrimitive must return a primitive value.\");\n }\n return (\"string\" === r ? String : Number)(t);\n}\nfunction _toPropertyKey(t) {\n var i = _toPrimitive(t, \"string\");\n return \"symbol\" == typeof i ? i : i + \"\";\n}\nfunction _defineProperty(obj, key, value) {\n key = _toPropertyKey(key);\n if (key in obj) {\n Object.defineProperty(obj, key, {\n value: value,\n enumerable: true,\n configurable: true,\n writable: true\n });\n } else {\n obj[key] = value;\n }\n return obj;\n}\n\nexport { _defineProperty as defineProperty, _objectSpread2 as objectSpread2, _toPrimitive as toPrimitive, _toPropertyKey as toPropertyKey };\n","const DEVELOPMENT_DOMAIN = 'http://localhost:8082';\nconst PRODUCTION_DOMAIN = 'https://monorail-edge.shopifysvc.com';\nconst PRODUCE_BATCH_ENDPOINT = '/unstable/produce_batch';\nconst PRODUCE_ENDPOINT = '/v1/produce';\nconst PRODUCTION_CANADA_ENDPOINT = 'https://monorail-edge-ca.shopifycloud.com/v1/produce';\nfunction extractDomain(urlString) {\n return `https://${new URL(urlString).hostname}`;\n}\n\nexport { DEVELOPMENT_DOMAIN, PRODUCE_BATCH_ENDPOINT, PRODUCE_ENDPOINT, PRODUCTION_CANADA_ENDPOINT, PRODUCTION_DOMAIN, extractDomain };\n","import { isCompositeMonorailEvent } from '../events/events.mjs';\n\nclass ProducerMiddleware {\n constructor(producer) {\n this.producer = producer;\n }\n do(event, proceed) {\n if (isCompositeMonorailEvent(event)) {\n return this.producer.produce(event);\n } else {\n return this.producer.produceBatch(event);\n }\n }\n}\n\nexport { ProducerMiddleware };\n","function isCompositeMonorailEvent(monorailEvent) {\n return monorailEvent.schemaId !== undefined;\n}\n\nexport { isCompositeMonorailEvent };\n","// This was using uuid package, but to reduce bundle size we'll fallback to Math.random instead\n//\n// The value is used to deduplicate messages and so does not need to be cryptographically secure\nfunction v4() {\n if (typeof crypto !== 'undefined' && crypto && typeof crypto.randomUUID === 'function') {\n return crypto.randomUUID();\n }\n const uuid = new Array(36);\n for (let i = 0; i < 36; i++) {\n uuid[i] = Math.floor(Math.random() * 16);\n }\n\n // set bits 12-15 of time-high-and-version to 0100\n uuid[14] = 4;\n\n /* eslint-disable no-multi-assign */\n\n // set bit 6 of clock-seq-and-reserved to zero\n uuid[19] = uuid[19] &= ~(1 << 2);\n\n // set bit 7 of clock-seq-and-reserved to one\n uuid[19] = uuid[19] |= 1 << 3;\n uuid[8] = uuid[13] = uuid[18] = uuid[23] = '-';\n\n /* eslint-enable no-multi-assign */\n\n return uuid.map(x => x.toString(16)).join('');\n}\n\nexport { v4 };\n","import { objectSpread2 as _objectSpread2 } from '../_virtual/_rollupPluginBabelHelpers.mjs';\n\nfunction toUnderscoreCase(object, convertToUnderscoreCase = true) {\n if (object && Object.keys(object).length && convertToUnderscoreCase) {\n return Object.keys(object).map(key => ({\n [convertStringToUnderscoreCase(key)]: object[key]\n })).reduce((prev, next) => _objectSpread2(_objectSpread2({}, prev), next));\n }\n return object;\n}\nfunction convertStringToUnderscoreCase(camelCaseString) {\n return camelCaseString.split(/(?=[A-Z])/).join('_').toLowerCase();\n}\nfunction convertAllEventsToUnderscoreCase(monorailEvent) {\n return monorailEvent.events.map(event => {\n let convertToUnderscoreCase = true;\n let convertMetaToUnderscoreCase = true;\n if (event && event.options && Object.prototype.hasOwnProperty.call(event.options, 'convertEventCase')) {\n convertToUnderscoreCase = Boolean(event.options.convertEventCase);\n }\n if (event && event.options && Object.prototype.hasOwnProperty.call(event.options, 'convertMetaDataCase')) {\n convertMetaToUnderscoreCase = Boolean(event.options.convertMetaDataCase);\n }\n return {\n /* eslint-disable @typescript-eslint/naming-convention */\n schema_id: event.schemaId,\n /* eslint-enable @typescript-eslint/naming-convention */\n payload: toUnderscoreCase(event.payload, convertToUnderscoreCase),\n metadata: toUnderscoreCase(event.metadata, convertMetaToUnderscoreCase)\n };\n });\n}\n\nexport { convertAllEventsToUnderscoreCase, convertStringToUnderscoreCase, toUnderscoreCase };\n","/*\nPlease note that in both of the super calls below we are setting\nthe prototype chain manually. This needs to be done when extending built-ins like\n`Error`, `Array` and `Map`.\nThe detailed reason why we are doing this is because of the following recommendations\nfrom the typescript team:\nhttps://github.com/Microsoft/TypeScript/wiki/FAQ#why-doesnt-extending-built-ins-like-error-array-and-map-work\n */\n\nclass MonorailUnableToProduceError extends Error {\n constructor(response) {\n super(`Error producing to the Monorail Edge. Response received: ${JSON.stringify(response)}`);\n this.response = response;\n Object.setPrototypeOf(this, MonorailUnableToProduceError.prototype);\n }\n}\nclass MonorailBatchProduceError extends Error {\n constructor(response) {\n super(`Error producing to the Monorail Edge. Response received: ${JSON.stringify(response)}`);\n Object.setPrototypeOf(this, MonorailBatchProduceError.prototype);\n this.response = response;\n }\n}\nclass MonorailRequestError extends Error {\n constructor(error) {\n super(`Error completing request. A network failure may have prevented the request from completing. Error: ${error}`);\n Object.setPrototypeOf(this, MonorailRequestError.prototype);\n }\n}\nclass MonorailRetriesExceededError extends Error {\n constructor(error) {\n super(`${error}`);\n Object.setPrototypeOf(this, MonorailRetriesExceededError.prototype);\n }\n}\n\nexport { MonorailBatchProduceError, MonorailRequestError, MonorailRetriesExceededError, MonorailUnableToProduceError };\n","import { objectSpread2 as _objectSpread2 } from '../_virtual/_rollupPluginBabelHelpers.mjs';\nimport { extractDomain, DEVELOPMENT_DOMAIN, PRODUCE_BATCH_ENDPOINT, PRODUCE_ENDPOINT, PRODUCTION_DOMAIN } from '../config/endpoints.mjs';\nimport { convertAllEventsToUnderscoreCase, toUnderscoreCase } from '../helpers/convert-case.mjs';\nimport { v4 } from '../helpers/uuid.mjs';\nimport { MonorailRequestError, MonorailBatchProduceError, MonorailUnableToProduceError } from './producer-errors.mjs';\n\nclass HttpProducer {\n static withEndpoint(edgeEndpoint) {\n return new HttpProducer(extractDomain(edgeEndpoint));\n }\n constructor(edgeDomain = DEVELOPMENT_DOMAIN, keepalive = false) {\n this.edgeDomain = edgeDomain;\n this.keepalive = keepalive;\n }\n async produceBatch(monorailEvent) {\n const body = {\n events: convertAllEventsToUnderscoreCase(monorailEvent),\n metadata: toUnderscoreCase(monorailEvent.metadata)\n };\n let edgeResponse;\n try {\n edgeResponse = await fetch(this.produceBatchEndpoint(), {\n method: 'post',\n headers: getHeadersFromMetadata(monorailEvent.metadata),\n body: JSON.stringify(body),\n keepalive: this.keepalive\n });\n } catch (error) {\n // @ts-ignore\n throw new MonorailRequestError(error);\n }\n if (edgeResponse.status === 207) {\n const response = await edgeResponse.json();\n throw new MonorailBatchProduceError(response);\n }\n if (!edgeResponse.ok) {\n throw new MonorailUnableToProduceError({\n status: edgeResponse.status,\n message: await edgeResponse.text()\n });\n }\n return {\n status: edgeResponse.status\n };\n }\n async produce(monorailEvent) {\n let convertToUnderscoreCase = true;\n if (monorailEvent && monorailEvent.options && Object.prototype.hasOwnProperty.call(monorailEvent.options, 'convertEventCase')) {\n convertToUnderscoreCase = Boolean(monorailEvent.options.convertEventCase);\n }\n let edgeResponse;\n try {\n edgeResponse = await produceHttpEvent({\n endpoint: this.produceEndpoint(),\n keepalive: this.keepalive,\n event: _objectSpread2(_objectSpread2({}, monorailEvent), {}, {\n payload: toUnderscoreCase(monorailEvent.payload, convertToUnderscoreCase)\n })\n });\n } catch (error) {\n // @ts-ignore\n throw new MonorailRequestError(error);\n }\n if (!edgeResponse) {\n throw new MonorailUnableToProduceError({\n message: 'No response from edge'\n });\n }\n if (!edgeResponse.ok) {\n throw new MonorailUnableToProduceError({\n status: edgeResponse.status,\n message: await edgeResponse.text()\n });\n }\n return {\n status: edgeResponse.status\n };\n }\n produceBatchEndpoint() {\n return this.edgeDomain + PRODUCE_BATCH_ENDPOINT;\n }\n produceEndpoint() {\n return this.edgeDomain + PRODUCE_ENDPOINT;\n }\n}\n/* eslint-enable @typescript-eslint/ban-ts-comment */\n\nfunction getHeadersFromMetadata(metadata) {\n /* eslint-disable @typescript-eslint/naming-convention */\n const headers = {\n 'Content-Type': 'application/json; charset=utf-8',\n 'X-Monorail-Edge-Event-Created-At-Ms': (metadata && metadata.eventCreatedAtMs || Date.now()).toString(),\n 'X-Monorail-Edge-Event-Sent-At-Ms': Date.now().toString(),\n 'X-Monorail-Edge-Client-Message-Id': (metadata && metadata.clientMessageId || v4()).toString()\n };\n /* eslint-enable @typescript-eslint/naming-convention */\n\n if (metadata && metadata.userAgent) {\n headers['User-Agent'] = metadata.userAgent;\n }\n if (metadata && metadata.remoteIp) {\n headers['X-Forwarded-For'] = metadata.remoteIp;\n }\n return headers;\n}\n\n// Allows avoiding HttpProducer entirely by passing in snake-cased events (but we still get typechecking)\nasync function produceHttpEvent({\n endpoint,\n event,\n keepalive\n}) {\n return fetch(endpoint !== null && endpoint !== void 0 ? endpoint : PRODUCTION_DOMAIN + PRODUCE_ENDPOINT, {\n method: 'post',\n headers: getHeadersFromMetadata(event.metadata),\n /* eslint-disable @typescript-eslint/naming-convention */\n body: JSON.stringify({\n schema_id: event.schemaId,\n payload: event.payload\n }),\n /* eslint-enable @typescript-eslint/naming-convention */\n keepalive\n });\n}\n\nexport { HttpProducer, produceHttpEvent };\n","class LogProducer {\n static printWelcomeMessage(sendToConsole) {\n // eslint-disable-next-line no-console\n console.log(`%c👋 from Monorail%c\\n\\n` + `We've noticed that you're${sendToConsole ? '' : ' not'} ` + `running in debug mode. ` + `As such, we will ${sendToConsole ? 'produce' : 'not produce'} ` + `Monorail events to the console. ` + `\\n\\nIf you want Monorail events to ${sendToConsole ? 'stop' : 'start'} ` + `appearing here, %cset debugMode=${(!sendToConsole).toString()}%c, ` + `for the Monorail Log Producer in your code.`, 'font-size: large;', 'font-size: normal;', 'font-weight: bold;', 'font-weight: normal;');\n }\n constructor(sendToConsole) {\n this.sendToConsole = sendToConsole;\n if (sendToConsole) {\n LogProducer.printWelcomeMessage(sendToConsole);\n }\n }\n produce(monorailEvent) {\n if (this.sendToConsole) {\n // eslint-disable-next-line no-console\n console.log('Monorail event produced', monorailEvent);\n }\n return new Promise(resolve => {\n resolve(monorailEvent);\n });\n }\n produceBatch(monorailBatchEvent) {\n if (this.sendToConsole) {\n // eslint-disable-next-line no-console\n console.log('Monorail Batch event produced', monorailBatchEvent);\n }\n return new Promise(resolve => {\n resolve(monorailBatchEvent);\n });\n }\n}\n\nexport { LogProducer };\n","import { objectSpread2 as _objectSpread2 } from '../_virtual/_rollupPluginBabelHelpers.mjs';\nimport { PRODUCTION_DOMAIN, DEVELOPMENT_DOMAIN } from '../config/endpoints.mjs';\nimport { ProducerMiddleware } from '../middleware/producer-middleware.mjs';\nimport { v4 } from '../helpers/uuid.mjs';\nimport { HttpProducer } from './http-producer.mjs';\nimport { LogProducer } from './log-producer.mjs';\n\nclass Monorail {\n static createLogProducer(config) {\n return new Monorail(new LogProducer(config.debugMode), config.middleware || []);\n }\n static createHttpProducerWithEndpoint(edgeEndpoint, middleware = []) {\n return new Monorail(HttpProducer.withEndpoint(edgeEndpoint), middleware);\n }\n static createHttpProducer(config) {\n const keepalive = config.options && config.options.keepalive;\n return new Monorail(config.production ? new HttpProducer(PRODUCTION_DOMAIN, keepalive) : new HttpProducer(DEVELOPMENT_DOMAIN, keepalive), config.middleware || []);\n }\n static buildMiddlewareChain(middleware, index = 0) {\n if (index === middleware.length) {\n return this.identityFn;\n }\n return event => middleware[index].do(event, this.buildMiddlewareChain(middleware, index + 1));\n }\n constructor(producer, middleware) {\n this.producer = producer;\n this.middleware = middleware;\n this.executeChain = Monorail.buildMiddlewareChain(this.middleware.concat(new ProducerMiddleware(producer)));\n }\n produce(monorailEvent) {\n monorailEvent.metadata = _objectSpread2({\n eventCreatedAtMs: Date.now(),\n clientMessageId: v4()\n }, monorailEvent.metadata);\n return this.executeChain(monorailEvent);\n }\n produceBatch(monorailBatchEvent) {\n return this.executeChain(monorailBatchEvent);\n }\n}\n\nexport { Monorail };\n","/* eslint-disable @shopify/typescript-prefer-pascal-case-enums */\nimport type {MetricsConfig} from '@shopify/opentelemetry-sdk';\n\nenum MetricInstrumentType {\n Histogram = 'Histogram',\n Counter = 'Counter',\n UpDownCounter = 'UpDownCounter',\n}\n\nenum ValueType {\n INT = 0,\n DOUBLE = 1,\n}\n\nexport enum TelemetryMetricId {\n InvalidStorefrontOrigin = 'shop_js_invalid_storefront_origin',\n RequestShowCalledBeforeIframeLoaded = 'shop_js_request_show_called_before_iframe_loaded',\n HandleSilentError = 'shop_js_handle_silent_error',\n MonorailProducerError = 'shop_js_monorail_producer_error',\n}\n\nexport const metrics: MetricsConfig = {\n [TelemetryMetricId.InvalidStorefrontOrigin]: {\n type: MetricInstrumentType.Counter,\n description: 'Number of times the storefront origin is invalid',\n valueType: ValueType.INT,\n },\n [TelemetryMetricId.RequestShowCalledBeforeIframeLoaded]: {\n type: MetricInstrumentType.Counter,\n description:\n 'Number of times requestShow is called before iframe is loaded',\n valueType: ValueType.INT,\n },\n [TelemetryMetricId.HandleSilentError]: {\n type: MetricInstrumentType.Counter,\n description: 'Number of times silent errors are handled',\n valueType: ValueType.INT,\n },\n [TelemetryMetricId.MonorailProducerError]: {\n type: MetricInstrumentType.Counter,\n description: 'Number of times Monorail Producer failed to send event',\n valueType: ValueType.INT,\n },\n};\n","import type {DefaultOtelServiceOptions} from '@shopify/opentelemetry-sdk';\n\nimport {metrics} from './metrics';\n\nexport const options: DefaultOtelServiceOptions = {\n serviceName: 'shop-js',\n throttleLimit: 1000,\n prefixMetric: false,\n metrics,\n // NOTE:\n // If OtelService env variable is any value different from 'staging' or 'production',\n // it will attempt to send otel metrics to http://localhost:4318/v1/metrics\n // Since we are not running the otel collector locally, we will always use the staging.\n // eslint-disable-next-line no-process-env\n env: process.env.NODE_ENV === 'production' ? 'production' : 'staging',\n};\n","import type {OtelService} from '@shopify/opentelemetry-sdk';\n\nimport {getOtelService} from './opentelemetry';\n\nlet OtelServicePromise: Promise;\nlet retriesLeft = 3;\n\nexport const getOtelServiceSingleton: (\n overrideSingleton?: boolean,\n) => Promise = (overrideSingleton = false) => {\n if (OtelServicePromise && !overrideSingleton) {\n return OtelServicePromise;\n }\n\n OtelServicePromise = getOtelService();\n return OtelServicePromise;\n};\n\nexport const getOtelServiceSingletonWithRetries: () => Promise =\n async () => {\n try {\n const opentelService = await getOtelServiceSingleton(true);\n return opentelService;\n } catch (error) {\n retriesLeft--;\n if (retriesLeft > 0) {\n return getOtelServiceSingletonWithRetries();\n }\n throw error;\n }\n };\n","import type {OtelService} from '@shopify/opentelemetry-sdk';\n\nimport {options} from './options';\n\nexport const getOtelService: () => Promise = () => {\n return new Promise((resolve, reject) => {\n import('@shopify/opentelemetry-sdk')\n .then((OpentelImport) => {\n const DefaultOtelService = OpentelImport.DefaultOtelService;\n const otelService = new DefaultOtelService(options);\n resolve(otelService);\n })\n .catch((error) => {\n reject(error);\n });\n });\n};\n","import type {Attributes} from '@shopify/opentelemetry-sdk';\nimport Bugsnag from '__deprecated__/common/bugsnag';\n\nimport {getOtelServiceSingletonWithRetries} from './singleton';\nimport {TelemetryMetricId} from './metrics';\n\nexport const record: (\n telemetryMetricId: TelemetryMetricId,\n value: number,\n tags: Attributes,\n) => void = (telemetryMetricId, value, tags) => {\n // eslint-disable-next-line no-process-env\n if (!process.env.ENABLE_OPENTEL) return;\n\n getOtelServiceSingletonWithRetries()\n .then((otelService) => {\n otelService.record(telemetryMetricId, value, tags);\n })\n .catch((error) => {\n Bugsnag.notify(error);\n });\n};\n","/**\n * Returns the value of the cookie with the given key.\n * @param {string} key The name of the cookie.\n * @returns {string | null} The value of the cookie or null if it doesn't exist.\n */\nexport function getCookie(key: string): string | null {\n try {\n const value = new RegExp(`(${key})=([^;]+)`).exec(document.cookie);\n return value ? value[2] : null;\n } catch (_ignore) {\n return null;\n }\n}\n","export const COOKIE_EXCHANGE_PATH_CORE = '/services/login_with_shop/finalize';\n\nexport const buildCookieExchangeUrl = (origin: string): string => {\n return `${origin}${COOKIE_EXCHANGE_PATH_CORE}`;\n};\n\n/**\n * function which exchanges the temporary login cookie for the proper pay one\n * @param {string} storefrontOrigin - the origin string of the storefront\n * @param {Function} errorCallback - a function which covers the error path\n * for when the API is unresponsive; note that all other errors are handled server-side\n * @returns {Promise} Api request promise\n */\nexport function exchangeLoginCookie(\n storefrontOrigin: string = window.location.origin,\n errorCallback: (error: any) => void,\n): Promise {\n const cookieExchangeUrl = buildCookieExchangeUrl(storefrontOrigin);\n return fetch(cookieExchangeUrl).catch(errorCallback);\n}\n","/**\n *\n * @param {boolean} session Whether to use sessionStorage or localStorage.\n * @returns {boolean} Whether the storage is available.\n */\nfunction storageAvailable(session?: boolean) {\n const type = session ? 'sessionStorage' : 'localStorage';\n\n try {\n const storage = window[type];\n const testValue = '__storage_test__';\n storage.setItem(testValue, testValue);\n storage.removeItem(testValue);\n return true;\n } catch (_e) {\n return false;\n }\n}\n\n/**\n * Sets the value of the item in the given storage.\n * @param {string} name The name of the item.\n * @param {string} value The value of the item.\n * @param {object} options The options for the storage.\n * @param {boolean} options.session Whether to use sessionStorage or localStorage.\n * @returns {boolean} Whether the operation was successful.\n */\nexport function setStorageItem(\n name: string,\n value: string,\n {session}: {session?: boolean} = {},\n): boolean {\n if (!storageAvailable(session)) {\n return false;\n }\n\n const storage = session ? 'sessionStorage' : 'localStorage';\n window[storage].setItem(name, value);\n return true;\n}\n\n/**\n * Gets the value of the item in the given storage.\n * @param {string} name The name of the item.\n * @param {object} options The options for the storage.\n * @param {boolean} options.session Whether to use sessionStorage or localStorage.\n * @returns {string | null} The value of the item or null if it doesn't exist\n */\nexport function getStorageItem(\n name: string,\n {session}: {session?: boolean} = {},\n): string | null {\n if (!storageAvailable(session)) {\n return null;\n }\n\n const storage = session ? 'sessionStorage' : 'localStorage';\n return window[storage].getItem(name);\n}\n\n/**\n * Deletes the item in the given storage.\n * @param {string} name The name of the item.\n * @param {object} options The options for the storage.\n * @param {boolean} options.session Whether to use sessionStorage or localStorage.\n * @returns {boolean} Whether the operation was successful.\n */\nexport function removeStorageItem(\n name: string,\n {session}: {session?: boolean} = {},\n): boolean {\n if (!storageAvailable(session)) {\n return false;\n }\n\n const storage = session ? 'sessionStorage' : 'localStorage';\n window[storage].removeItem(name);\n return true;\n}\n","import validate from './validate.js';\n\n/**\n * Convert array of 16 byte values to UUID string format of the form:\n * XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX\n */\nvar byteToHex = [];\nfor (var i = 0; i < 256; ++i) {\n byteToHex.push((i + 0x100).toString(16).slice(1));\n}\nexport function unsafeStringify(arr, offset = 0) {\n // Note: Be careful editing this code! It's been tuned for performance\n // and works in ways you may not expect. See https://github.com/uuidjs/uuid/pull/434\n //\n // Note to future-self: No, you can't remove the `toLowerCase()` call.\n // REF: https://github.com/uuidjs/uuid/pull/677#issuecomment-1757351351\n return (byteToHex[arr[offset + 0]] + byteToHex[arr[offset + 1]] + byteToHex[arr[offset + 2]] + byteToHex[arr[offset + 3]] + '-' + byteToHex[arr[offset + 4]] + byteToHex[arr[offset + 5]] + '-' + byteToHex[arr[offset + 6]] + byteToHex[arr[offset + 7]] + '-' + byteToHex[arr[offset + 8]] + byteToHex[arr[offset + 9]] + '-' + byteToHex[arr[offset + 10]] + byteToHex[arr[offset + 11]] + byteToHex[arr[offset + 12]] + byteToHex[arr[offset + 13]] + byteToHex[arr[offset + 14]] + byteToHex[arr[offset + 15]]).toLowerCase();\n}\nfunction stringify(arr, offset = 0) {\n var uuid = unsafeStringify(arr, offset);\n // Consistency check for valid UUID. If this throws, it's likely due to one\n // of the following:\n // - One or more input array values don't map to a hex octet (leading to\n // \"undefined\" in the uuid)\n // - Invalid input values for the RFC `version` or `variant` fields\n if (!validate(uuid)) {\n throw TypeError('Stringified UUID is invalid');\n }\n return uuid;\n}\nexport default stringify;","// Unique ID creation requires a high quality random # generator. In the browser we therefore\n// require the crypto API and do not support built-in fallback to lower quality random number\n// generators (like Math.random()).\n\nvar getRandomValues;\nvar rnds8 = new Uint8Array(16);\nexport default function rng() {\n // lazy load so that environments that need to polyfill have a chance to do so\n if (!getRandomValues) {\n // getRandomValues needs to be invoked in a context where \"this\" is a Crypto implementation.\n getRandomValues = typeof crypto !== 'undefined' && crypto.getRandomValues && crypto.getRandomValues.bind(crypto);\n if (!getRandomValues) {\n throw new Error('crypto.getRandomValues() not supported. See https://github.com/uuidjs/uuid#getrandomvalues-not-supported');\n }\n }\n return getRandomValues(rnds8);\n}","var randomUUID = typeof crypto !== 'undefined' && crypto.randomUUID && crypto.randomUUID.bind(crypto);\nexport default {\n randomUUID\n};","import native from './native.js';\nimport rng from './rng.js';\nimport { unsafeStringify } from './stringify.js';\nfunction v4(options, buf, offset) {\n if (native.randomUUID && !buf && !options) {\n return native.randomUUID();\n }\n options = options || {};\n var rnds = options.random || (options.rng || rng)();\n\n // Per 4.4, set bits for version and `clock_seq_hi_and_reserved`\n rnds[6] = rnds[6] & 0x0f | 0x40;\n rnds[8] = rnds[8] & 0x3f | 0x80;\n\n // Copy bytes to buffer, if provided\n if (buf) {\n offset = offset || 0;\n for (var i = 0; i < 16; ++i) {\n buf[offset + i] = rnds[i];\n }\n return buf;\n }\n return unsafeStringify(rnds);\n}\nexport default v4;","import {v4 as uuidv4} from 'uuid';\n\nimport {POPUP_CLOSE_CHECK_INTERVAL} from '../constants';\n\nimport {StoreMetadata} from './types';\n\nconst getWindowPosition = () => {\n const left =\n window.screenLeft === undefined ? window.screenX : window.screenLeft;\n const top =\n window.screenTop === undefined ? window.screenY : window.screenTop;\n return {\n left,\n top,\n };\n};\n\nexport const getWindowSize = () => {\n const width = window.innerWidth || document.documentElement.clientWidth;\n const height = window.innerHeight || document.documentElement.clientHeight;\n return {\n width,\n height,\n };\n};\n\nconst getSystemZoom = () => {\n return screen.width && window.screen.availWidth\n ? screen.width / window.screen.availWidth\n : 1;\n};\n\ninterface PopupParameters {\n url: string;\n width: number;\n height: number;\n windowName?: string;\n onClose?: () => void;\n}\n\n/**\n * Opens a popup widow. Tries to put the window into the middle of the parent,\n * if possible. Otherwise puts it into the middle of the screen.\n * @param {object} root The root parameter object.\n * @param {string} root.url URL to display in the popup.\n * @param {number} root.width Target width of the popup.\n * @param {number} root.height Target height of the popup.\n * @param {string} root.windowName Optional name given to the popup window.\n * Should not contain whitespace. This will not be used as the window's title.\n * @param {Function} root.onClose Optional function called when the popup is closed.\n * @returns {Window} A reference to the popup window object.\n */\nexport function openPopupWindow({\n url,\n width,\n height,\n windowName,\n onClose,\n}: PopupParameters): Window | null {\n const windowPosition = getWindowPosition();\n const windowSize = getWindowSize();\n\n const clientWidth = windowSize.width || screen.width;\n const clientHeight = windowSize.height || screen.height;\n\n const systemZoom = getSystemZoom();\n const left = (clientWidth - width) / 2 / systemZoom + windowPosition.left;\n const top = (clientHeight - height) / 2 / systemZoom + windowPosition.top;\n\n const popupWindow: Window | null = window.open(\n url,\n windowName,\n `scrollbars=yes,width=${width},height=${height},top=${top},left=${left}`,\n );\n if (!popupWindow) return null;\n popupWindow.focus();\n\n if (onClose) {\n const closeCheckInterval = setInterval(() => {\n if (!popupWindow.closed) return;\n onClose();\n clearInterval(closeCheckInterval);\n }, POPUP_CLOSE_CHECK_INTERVAL);\n }\n\n return popupWindow;\n}\n\n/**\n * Updates the value on an HTML element if it's different to the current one.\n * @param {HTMLElement} element The HTML element to update.\n * @param {string} attribute The name of the attribute to set.\n * @param {string} value The new value for the attribute.\n * @param {boolean | undefined} forced whether to force a reload even if the URL matches\n */\nexport function updateAttribute(\n element: HTMLElement,\n attribute: string,\n value: string,\n forced?: boolean,\n) {\n if (!forced && element.getAttribute(attribute) === value) return;\n if ((element as Record)[attribute] === true) return;\n element.setAttribute(attribute, value);\n}\n\n/**\n * Updates an attribute in a given list of attributes, based on a given flag\n * @param {boolean} flag should this attribute be there?\n * @param {string} attributeName the name of the attribute\n * @param {string[]} attributeList pointer to the list in which to update it\n */\nexport function updateAttributeConditionally(\n flag: boolean,\n attributeName: string,\n attributeList: string[],\n) {\n const attributeIncluded = attributeList.includes(attributeName);\n\n if (flag && !attributeIncluded) {\n attributeList.push(attributeName);\n } else if (!flag && attributeIncluded) {\n attributeList.splice(attributeList.indexOf(attributeName), 1);\n }\n}\n\n/**\n * Updates the iframe src without pushing to the browser history stack. Does this by\n * removing the iframe from the DOM, updating the src attribute and then re-adding it.\n * @param {HTMLIFrameElement} iframe The iframe to navigate.\n * @param {string} src The new URL to navigate to.\n * @param {boolean | undefined} forced Whether to force a reload even if the URL matches.\n */\nexport function updateIframeSrc(\n iframe: HTMLIFrameElement,\n src: string,\n forced?: boolean,\n) {\n if (!forced && iframe.src === src) return;\n\n const parent = iframe.parentNode;\n if (!parent) return;\n\n parent.removeChild(iframe);\n iframe.setAttribute('src', src);\n parent.appendChild(iframe);\n}\n\n/**\n * Returns the UUID to be used as the Analytics Trace ID, to link events from one session together.\n * @returns {string} The Analytics Trace ID.\n */\nexport function getAnalyticsTraceId(): string {\n return uuidv4();\n}\n\n/**\n * Returns the duration in milliseconds between two dates, if defined.\n * @param {Date} from The earlier date\n * @param {Date} to The later date\n * @returns {number | undefined} The duration in ms between the given dates or undefined if it's not possible to calculate.\n */\nexport function getDuration(from?: Date, to?: Date): number | undefined {\n if (!from || !to) return undefined;\n return to.getTime() - from.getTime();\n}\n\n/**\n * Gets the store's metadata from meta.json file.\n * @param {string} storefrontOrigin The origin of the storefront.\n * @returns {Promise} The store's metadata, or null if it's not available.\n */\nexport async function getStoreMeta(\n storefrontOrigin: string = location.origin,\n): Promise {\n const response = fetch(`${storefrontOrigin}/meta.json`);\n try {\n const res = await response;\n const meta = await res.json();\n return meta;\n } catch {\n return null;\n }\n}\n\n/**\n * @param {string} storeUrl store url (e.g. `https://merchant.com` or\n * `http://store.myshopify.com`). Will validate that it's a valid URL and not\n * a subset.\n * @returns {string} The extracted hostname of the provided URL, or null if an error occurs in parsing hostname\n */\nexport function getHostName(storeUrl: string): string | null {\n try {\n return new URL(storeUrl).hostname;\n } catch (error) {\n // eslint-disable-next-line no-console\n console.error(`[Shop Pay] Store URL (${storeUrl}) is not valid`, error);\n return null;\n }\n}\n\n/**\n *\n *Extract a query parameter from the current URL.\n * @param {string} name The name of the query parameter to get.\n * @returns {string | null} The value of the query parameter or null if it doesn't exist.\n */\nexport function getQueryParam(name: string): string | null {\n const urlParams = new URLSearchParams(window.location.search);\n return urlParams.get(name);\n}\n\n/**\n * Climbs the DOM tree from the given shadow root to the document body. Yielding each HTML element along the way.\n * @param {ShadowRoot | Element} base The shadow root or element to start climbing from.\n * @yields {Element} The next HTML element in the DOM tree.\n */\nexport function* climbDomTree(base: ShadowRoot | Element): Generator {\n let current: ShadowRoot | Element | null = base;\n\n while (current) {\n if (current.parentElement) {\n current = current.parentElement;\n } else if (current instanceof ShadowRoot) {\n current = current.host;\n } else if (current instanceof Element) {\n const root = current.getRootNode();\n if (root instanceof ShadowRoot) {\n current = root.host;\n } else {\n break;\n }\n } else {\n break;\n }\n\n yield current;\n\n if (current === document.body) {\n break;\n }\n }\n}\n\ntype Callback = (...args: T) => void;\n/**\n * Debounces a function call by the given timeout.\n * @param {Callback} callback The function to call after the timeout has elapsed.\n * @param {number} timeout The timeout in milliseconds.\n * @returns {Callback} A function that will call the callback after the timeout has elapsed.\n */\nexport function debounce(\n callback: Callback,\n timeout: number,\n): (...args: T) => void {\n let timer: NodeJS.Timeout;\n\n return (...args: T) => {\n clearTimeout(timer);\n timer = setTimeout(() => {\n callback(...args);\n }, timeout);\n };\n}\n\n/**\n *\n *Remove trailing slash from a URL. If the URL is only a slash, it will be returned as is.\n * @param {string} urlString The URL to remove the trailing slash from.\n * @returns {string} The URL without the trailing slash.\n */\nexport function removeTrailingSlash(urlString: string): string {\n if (urlString === '/') return urlString;\n return urlString.endsWith('/') ? urlString.slice(0, -1) : urlString;\n}\n\n/**\n * Returns `true` if the given URLs are considered to have matching root domains. A \"match\"\n * in this case means that one domain is either a superdomain or a subdomain of the other.\n *\n * This solves the specific case of allowing postMessaging between domains like `lang.storefront.com`\n * and `storefront.com`. However once Sign in with Shop can be deployed on any surface this restriction\n * may need to be reconsidered.\n * @param {string} urlString1 A URL with a root domain or subdomain (i.e. \"http://merchant.com\" or \"http://fr.merchant.com\")\n * @param {string} urlString2 A URL with a root domain or subdomain (i.e. \"http://merchant.com\" or \"http://fr.merchant.com\")\n * @returns {boolean} `true` if the root domains of the given URLs match\n */\nexport function isRootDomainMatch(\n urlString1: string,\n urlString2: string,\n): boolean {\n try {\n const host1Tokens = new URL(urlString1).host.split('.').reverse();\n const host2Tokens = new URL(urlString2).host.split('.').reverse();\n for (let i = 0; i < Math.min(host1Tokens.length, host2Tokens.length); i++) {\n if (host1Tokens[i] !== host2Tokens[i]) {\n return false;\n }\n }\n return true;\n } catch (err) {\n return false;\n }\n}\n\n/**\n * Applies a partial set of styles to an element.\n * @param {HTMLElement} element The element to apply the styles to.\n * @param {Partial} styles The (partial) styles to apply to the element.\n * @returns {CSSStyleDeclaration} The element's style object.\n */\nexport function applyStylesToElement(\n element: HTMLElement,\n styles: Partial,\n): CSSStyleDeclaration {\n return Object.assign(element.style, styles);\n}\n\n/**\n * Detect if user is using mobile (logic inspired from Core)\n * @returns {boolean} Whether the user is using a mobile browser\n */\nexport function isMobileBrowser(): boolean {\n return (\n Boolean(navigator.userAgent) &&\n /(android|iphone|ipad|mobile|phone)/i.test(navigator.userAgent)\n );\n}\n\n/**\n * Detect specifically if this is an iOS platform\n * @returns {boolean} Whether the device is running iOS\n */\nexport function isIOSPlatform(): boolean {\n return (\n Boolean(navigator.userAgent) &&\n /(iphone|ipad|ipod)/i.test(navigator.userAgent)\n );\n}\n\n/**\n * On iOS, the keyboard zooms in when a form input is focused.\n * For the email listener flows, this results in a zoomed-in\n * OTP modal. To force an unzoom, we create an input element\n * and focus it, which unzooms the view.\n *\n * This problem arises from both:\n * Autozoom functionality in iOS\n * Inability to autofocus a field in an IFRAME\n * @returns {void}\n */\nexport function unzoomIos() {\n if (!isiOSSafari()) {\n return;\n }\n\n const elementId = 'shop-pay-safari-unzoom';\n const existingElement = document.getElementById(elementId);\n if (existingElement) return existingElement.focus();\n\n const input = document.createElement('input');\n input.id = elementId;\n input.style.fontSize = '16px';\n input.style.width = '1px';\n input.style.height = '1px';\n input.style.position = 'fixed';\n input.style.bottom = '-1000px';\n input.style.right = '-1000px';\n input.style.transform = 'translate(1000px, 1000px)';\n input.setAttribute('aria-hidden', 'true');\n\n document.body.appendChild(input);\n input.focus({preventScroll: true});\n}\n\n/**\n * Determines if we are using iOS.\n * @returns {boolean} True if we are using iOS Safari\n */\nfunction isiOSSafari() {\n const ua = window.navigator.userAgent;\n const iOS = Boolean(ua.match(/iPad/i)) || Boolean(ua.match(/iPhone/i));\n const webkit = Boolean(ua.match(/WebKit/i));\n const iOSSafari = iOS && webkit && !ua.match(/CriOS/i);\n return iOSSafari;\n}\n\n/**\n * Checks whether the given value passed to a component attribute is empty.\n * @param {string} value The value passed to a component attribute.\n * @returns {boolean} `true` if the given value is null or empty, `false` otherwise.\n */\nexport function isEmptyAttributeValue(value: string | null) {\n return value === null || value.trim() === '';\n}\n\n/**\n * A function that resolves a promise with a max timeout\n * This function was written by Chat-GPT3.5. Prompt by gioele\n * @param {Promise} promise the promise to race with a timeout\n * @param {number} timeoutMs the timeout in milliseconds\n * @returns {Promise} either the resolved promise or a rejected promise with a timeout error\n */\nexport function promiseWithTimeout(\n promise: Promise,\n timeoutMs: number,\n): Promise {\n let timeoutId: NodeJS.Timeout;\n\n const timeoutPromise = new Promise((resolve) => {\n timeoutId = setTimeout(() => {\n resolve();\n }, timeoutMs);\n });\n\n return Promise.race([promise, timeoutPromise]).finally(() => {\n clearTimeout(timeoutId);\n });\n}\n\n/**\n * Extract feature flags exported from a storefront-renderer Shop Pay specific script tag\n * @returns {Record} feature name and value pairs\n */\nexport function getFeatures(): Record {\n const featuresTag = document.querySelector(\n 'script#shop-js-features',\n )?.innerHTML;\n if (featuresTag) {\n return JSON.parse(featuresTag);\n } else {\n return {};\n }\n}\n\n/**\n * Find and parse the storefront analytics meta tag\n * @returns {Record} storefront analytics information\n */\nexport function getStorefrontAnalytics(): Record {\n const analyticsTag = document.querySelector(\n 'script#shop-js-analytics',\n )?.innerHTML;\n if (analyticsTag) {\n return JSON.parse(analyticsTag);\n } else {\n return {};\n }\n}\n","// Taken from the Modal flow in Pay, requires at least 2 characters for TLDs.\nconst EMAIL_REGEX = /^[^@]+@[^@]+\\.[^@]{2,}$/i;\n\n/**\n * Checks if the given string is a valid email address.\n * @param {string} email The email to check.\n * @returns {boolean} `true` if the given string is a valid email address.\n */\nexport function isValidEmail(email?: string): boolean {\n if (!email) return false;\n return RegExp(EMAIL_REGEX).test(email);\n}\n","import Bugsnag from '../bugsnag';\n\n/**\n * Creates an element locator that will call the provided callbacks when elements are added to the DOM.\n * @param {object} params The root parameter object.\n * @param {string} params.selector Any valid CSS selector\n * @param {Function} params.onElementFound Called when an element is added to the DOM\n * @returns {MutationObserver} An object that handles starting and stopping a mutation observer\n */\nexport function createElementLocator({\n selector,\n onElementFound,\n}: {\n selector: string;\n onElementFound: (element: TElementType) => void;\n}): MutationObserver {\n const instances = new WeakSet();\n\n const observer = new MutationObserver((mutations) => {\n let hasNewNodes = false;\n\n for (const mutation of mutations) {\n if (mutation.addedNodes.length > 0) {\n hasNewNodes = true;\n break;\n }\n }\n\n if (hasNewNodes) {\n locateElements();\n }\n });\n\n /**\n * Locates elements that match the provided selector, and calls the onElementFound callback for each one.\n */\n function locateElements() {\n document.querySelectorAll(selector).forEach((element) => {\n if (!instances.has(element)) {\n onElementFound(element);\n instances.add(element);\n }\n });\n }\n\n /**\n * Waits for the DOM to be ready before starting the mutation observer.\n */\n async function locateAndObserveElements() {\n await waitForDOM();\n locateElements();\n\n observer.observe(document.body || document.documentElement, {\n childList: true,\n subtree: true,\n });\n }\n\n locateAndObserveElements();\n\n return observer;\n}\n\n/**\n * Creates an element visibility observer that will call the provided callbacks when elements become visible.\n *\n * If an element is visible, and opacity of itself, or it's parent elements is '1', we will call the onVisible callback.\n * If an element is visible, and opacity of itself, or it's parent elements is not '1', we will call the onFallback callback.\n * @param {object} params The root parameter object.\n * @param {Function} params.onVisible Called when an element is visible\n * @param {Function} params.onFallback Called when an element is visible but has invalid styles\n * @returns {IntersectionObserver} An object that handles registering elements, and disabling the observer\n */\nexport function createElementVisibilityObserver<\n TElementType extends Element = Element,\n>({\n onVisible,\n onFallback,\n}: {\n onVisible: (element: TElementType) => void;\n onFallback: (element: TElementType) => void;\n}): IntersectionObserver {\n const observer = new IntersectionObserver(\n (entries) => {\n for (const entry of entries) {\n const {target, isIntersecting} = entry;\n\n if (isIntersecting) {\n if (validateStyles(target)) {\n onVisible(target as TElementType);\n } else {\n onFallback(target as TElementType);\n }\n\n observer.unobserve(target);\n }\n }\n },\n {\n threshold: 1,\n },\n );\n\n /**\n * Validates that styles of a given element are sufficient enough to be considered visible.\n * @param {Element} element The element to check\n * @returns {boolean} Whether the element is visible\n */\n function validateStyles(element: Element): boolean {\n let currentElement: Element | null = element;\n\n while (currentElement) {\n // Intersection observer does not respect opacity\n if (!['', '1'].includes(getComputedStyle(currentElement).opacity)) {\n return false;\n }\n\n currentElement = currentElement.parentElement;\n }\n\n return true;\n }\n\n return observer;\n}\n\n/**\n * Returns whether the given element is available or not. Emits a bugsnag error if not available.\n * @param {HTMLElement | null} element The html element to check for availability\n * @param {boolean} emitErrorIfNotAvailable Whether to emit a bugsnag error if the element is not available\n * @returns {boolean} Where the element is available or not\n */\nexport function isHTMLElementAvailable(\n element: HTMLElement | null,\n emitErrorIfNotAvailable = true,\n): element is HTMLElement {\n const available = Boolean(element);\n if (!available && emitErrorIfNotAvailable) {\n emitBugsnagErrorOnElementNotAvailable();\n }\n return available;\n}\n\n/**\n * Emit monorail event on html element not available\n *\n */\nfunction emitBugsnagErrorOnElementNotAvailable(): void {\n Bugsnag.notify(new Error(`HTML Element was not provided`));\n}\n\n/**\n * Utility method to wait for the DOM to be ready, if the body tag already exists, we will\n * return without waiting for the DOMContentLoaded event.\n * @returns {Promise} A promise that resolves when the DOM is ready\n */\nfunction waitForDOM(): Promise {\n if (document.body) {\n return Promise.resolve();\n }\n\n return new Promise((resolve) => {\n window.addEventListener('DOMContentLoaded', () => resolve());\n });\n}\n\n/**\n * Copies the template element from the template source to the DOM. Then extracts\n * the template contents and appends it as a child to the parent element.\n * @param {string} templateSource A string containing the