{"version":3,"file":"advantage.cjs","sources":["../../src/utils/logging.ts","../../src/utils/misc.ts","../../src/utils/messaging.ts","../../src/utils/wrapping-helper.ts","../../src/types/index.ts","../../src/advantage/formats/format-helper.ts","../../src/advantage/formats/topscroll.ts","../../src/advantage/formats/midscroll.ts","../../src/advantage/formats/welcomepage.ts","../../src/advantage/formats/multi-midscroll-base.ts","../../src/advantage/formats/double-midscroll.ts","../../src/advantage/formats/triple-midscroll.ts","../../src/advantage/formats/double-midscroll-single.ts","../../src/advantage/formats/index.ts","../../src/advantage/advantage.ts","../../src/advantage/messaging/publisher-side.ts","../../src/advantage/wrapper.ts","../../src/advantage/ui-layer.ts","../../src/advantage/messaging/creative-side.ts","../../src/advantage/index.ts"],"sourcesContent":["type LogLevel = \"log\" | \"info\" | \"error\";\n\nclass Logger {\n    private debugMode: boolean;\n    private style: string =\n        \"color: #f3f1ff; font-weight: bold; background-color: #6b04fd; padding: 2px; border-radius: 2px;\";\n\n    constructor() {\n        this.debugMode = new URLSearchParams(window.location.search).has(\n            \"adv_debug\"\n        );\n    }\n\n    private formatMessage(level: LogLevel): string {\n        const timestamp = new Date().toISOString();\n        return `${timestamp} [${level.toUpperCase()}] %cADVANTAGE`;\n    }\n\n    private log(level: LogLevel, message: any, ...optionalParams: any) {\n        if (this.debugMode) {\n            console[level](\n                this.formatMessage(level),\n                this.style,\n                `- ${message}`,\n                ...optionalParams\n            );\n            if (level === \"error\") {\n                console.trace();\n            }\n        }\n    }\n\n    debug(message: any, ...optionalParams: any) {\n        this.log(\"log\", message, ...optionalParams);\n    }\n\n    info(message: any, ...optionalParams: any) {\n        this.log(\"info\", message, ...optionalParams);\n    }\n\n    error(message: any, ...optionalParams: any) {\n        this.log(\"error\", message, ...optionalParams);\n    }\n\n    /**\n     * Enables debug mode for logging.\n     */\n    enableDebugMode() {\n        this.debugMode = true;\n    }\n}\n\nconst logger = new Logger();\nexport default logger;\n","/**\n * Collects all the iframes within a given node and its children.\n * @param node - The node to start collecting iframes from.\n * @returns An array of HTMLIFrameElement objects representing the iframes found.\n */\nexport const collectIframes = (node: Node): HTMLIFrameElement[] => {\n    let iframes: HTMLIFrameElement[] = [];\n\n    // If the node is an element, check if it's an iframe and then traverse its children\n    if (node.nodeType === Node.ELEMENT_NODE) {\n        const element = node as HTMLElement;\n\n        // If the element is an iframe, add it to the iframes array\n        if (element.tagName === \"IFRAME\") {\n            iframes.push(element as HTMLIFrameElement);\n        }\n\n        // Loop through all child nodes\n        element.childNodes.forEach((child) => {\n            iframes = iframes.concat(collectIframes(child));\n        });\n    }\n\n    return iframes;\n};\n\n/**\n * Traverses the DOM tree starting from a given node and applies a function to each element node.\n * @param node - The starting node for traversal.\n * @param func - The function to be applied to each element node.\n */\nexport const traverseNodes = (\n    node: Node,\n    func: (node: HTMLElement) => void\n) => {\n    // If the node is an element, apply func and traverse its children\n    if (node.nodeType === Node.ELEMENT_NODE) {\n        func(node as HTMLElement);\n        // Loop through all child nodes\n        for (let child of node.childNodes) {\n            traverseNodes(child, func);\n        }\n    }\n};\n\n/**\n * Checks if the browser supports adopting style sheets.\n */\nexport const supportsAdoptingStyleSheets =\n    \"adoptedStyleSheets\" in Document.prototype &&\n    \"replace\" in CSSStyleSheet.prototype;\n","import { AdvantageMessage, ADVANTAGE_MESSAGE } from \"../types\";\n\nexport const ADVANTAGE = \"ADVANTAGE\" as ADVANTAGE_MESSAGE;\n\n/**\n * Sends a message and opens a message channel to receive the reply.\n * @param message - The message to send.\n * @param retryInterval - The interval (in milliseconds) between retry attempts. Default is 100ms.\n * @param maxAttempts - The maximum number of retry attempts. Default is 25.\n * @returns A promise that resolves with the reply and the message channel.\n */\nexport function sendMessageAndOpenChannel(\n    message: Partial<AdvantageMessage>,\n    retryInterval: number = 200,\n    maxAttempts: number = 25\n): Promise<{ reply: AdvantageMessage; messageChannel: MessageChannel }> {\n    let attempts = 0;\n    let replyReceived = false;\n\n    const getTargetWindow = (currentWindow: Window = window) => {\n        let targetWindow: Window = currentWindow;\n        try {\n            while (currentWindow !== window.top && currentWindow.document) {\n                targetWindow = currentWindow;\n                currentWindow = currentWindow.parent;\n            }\n        } catch (error) {\n            return targetWindow;\n        }\n        return targetWindow;\n    };\n\n    const createMessageContext = (\n        targetWindow: Window,\n        message: Partial<AdvantageMessage>\n    ) => {\n        const avic = targetWindow.document\n            .querySelector(\"[id^=avic_]\")\n            ?.id.replace(\"avic_\", \"\");\n        const qemid =\n            targetWindow.document.querySelector<HTMLElement>(\n                \"[data-jcp-qem-id]\"\n            )?.dataset.jcpQemId;\n        const targetingMap = targetWindow.ucTagData?.targetingMap;\n        const origins = Array.from([\n            ...(targetWindow.location.ancestorOrigins || []),\n            targetWindow.location.origin\n        ]);\n        const backgroundAdURL = location.href;\n\n        return {\n            ...message,\n            gqid: avic || qemid,\n            targetingMap: targetingMap,\n            origins: origins,\n            backgroundAdURL: backgroundAdURL\n        };\n    };\n\n    return new Promise((resolve, reject) => {\n        // Define a function that we'll call to send the message\n        const sendMessage = (messageWithContext: Partial<AdvantageMessage>) => {\n            attempts++;\n            // Create a new MessageChannel for each attempt\n            const channel = new MessageChannel();\n\n            // Define the response listener\n            channel.port1.onmessage = (event: MessageEvent) => {\n                // Check if this is the response we're waiting for\n                if (\n                    event.data.type === ADVANTAGE &&\n                    event.data.sessionID === message.sessionID\n                ) {\n                    replyReceived = true;\n\n                    resolve({\n                        reply: event.data as AdvantageMessage,\n                        messageChannel: channel\n                    });\n                }\n            };\n\n            window.top?.postMessage(messageWithContext, \"*\", [channel.port2]);\n        };\n\n        // try to find direct child window under top window\n        const targetWindow = getTargetWindow();\n        const messageWithContext = createMessageContext(targetWindow, message);\n\n        // Send the first message\n        sendMessage(messageWithContext);\n\n        // Set up the retry interval\n        const retryIntervalRef = setInterval(() => {\n            if (attempts < maxAttempts && !replyReceived) {\n                sendMessage(messageWithContext);\n            } else {\n                // Clean up and reject promise\n                clearInterval(retryIntervalRef);\n                if (!replyReceived) {\n                    reject(new Error(\"Max attempts reached without response\"));\n                }\n            }\n        }, retryInterval);\n    });\n}\n\n/**\n * Sends a message and awaits a response.\n *\n * @param message - The message to send.\n * @param messageChannel - The message channel to use for communication.\n * @param timeout - The timeout in milliseconds.\n * @returns A promise that resolves with the response message.\n */\nexport function sendMessageAndAwaitResponse(\n    message: Partial<AdvantageMessage>,\n    messageChannel: MessageChannel,\n    timeout: number\n): Promise<AdvantageMessage> {\n    return new Promise((resolve, reject) => {\n        const timeoutID = setTimeout(() => {\n            reject(new Error(\"Timeout reached without response\"));\n        }, timeout);\n\n        const responseListener = (event: MessageEvent) => {\n            if (\n                event.data.type === ADVANTAGE &&\n                event.data.sessionID === message.sessionID\n            ) {\n                clearTimeout(timeoutID);\n                messageChannel.port1.removeEventListener(\n                    \"message\",\n                    responseListener\n                );\n                resolve(event.data as AdvantageMessage);\n            }\n        };\n\n        messageChannel.port1.onmessage = responseListener;\n        messageChannel.port1.postMessage(message);\n    });\n}\n","/**\n * Moves an element into a wrapper structure and creates a new slot in the wrapper structure.\n * The wrapper structure is inserted into the DOM before the element.\n * If the function is passed an array of formats that should not be allowed for this wrapper, it adds an attribute to the wrapper structure.\n * If the function is passed an array of formats that should be allowed for this wrapper, it adds an attribute to the wrapper structure.\n * @param target - The target element or selector string.\n * @param excludedFormats - An optional array of excluded formats.\n * @param allowedFormats - An optional array of allowed formats.\n */\nexport function advantageWrapAdSlotElement(\n    target: HTMLElement | string,\n    excludedFormats?: string[],\n    allowedFormats?: string[]\n) {\n    let element: HTMLElement | null;\n\n    // Check if target is an HTMLElement or a selector string\n    if (typeof target === \"string\") {\n        element = document.querySelector(target);\n    } else {\n        element = target;\n    }\n\n    // If the element is not found, exit the function\n    if (!element) {\n        console.warn(\"Target element not found.\");\n        return;\n    }\n\n    // Create the wrapper structure\n    const advantageWrapper = document.createElement(\"advantage-wrapper\");\n\n    // Add forbidden/excluded formats if provided\n    if (excludedFormats && excludedFormats.length > 0) {\n        const formats = excludedFormats.join(\", \");\n        advantageWrapper.setAttribute(\"exclude-formats\", formats);\n    }\n\n    // Add allowed formats if provided\n    if (allowedFormats && allowedFormats.length > 0) {\n        const formats = allowedFormats.join(\", \");\n        advantageWrapper.setAttribute(\"allowed-formats\", formats);\n    }\n\n    const slotDiv = document.createElement(\"div\");\n    slotDiv.setAttribute(\"slot\", \"advantage-ad-slot\");\n\n    // Insert the wrapper structure into the DOM\n    element.parentNode?.insertBefore(advantageWrapper, element);\n\n    // Move the target element into the wrapper structure\n    advantageWrapper.appendChild(slotDiv);\n    slotDiv.appendChild(element);\n}\n","export type ADVANTAGE_MESSAGE = \"ADVANTAGE\";\n\nexport enum AdvantageMessageAction {\n    START_SESSION = \"START_SESSION\",\n    CONFIRM_SESSION = \"CONFIRM_SESSION\",\n    REQUEST_FORMAT = \"REQUEST_FORMAT\",\n    FORMAT_CONFIRMED = \"FORMAT_CONFIRMED\",\n    FORMAT_REJECTED = \"FORMAT_REJECTED\",\n    SCROLL_PROGRESS = \"SCROLL_PROGRESS\"\n}\n\nexport enum AdvantageFormatName {\n    TopScroll = \"TOPSCROLL\",\n    DoubleMidscroll = \"DOUBLE_MIDSCROLL\",\n    DoubleMidscrollSingleCreative = \"DOUBLE_MIDSCROLL_SINGLE_CREATIVE\",\n    Midscroll = \"MIDSCROLL\",\n    TripleMidscroll = \"TRIPLE_MIDSCROLL\",\n    WelcomePage = \"WELCOME_PAGE\"\n}\n\nexport interface AdvantageAd {\n    eventSource: MessageEventSource;\n    port: MessagePort;\n    iframe?: HTMLElement;\n}\n\nexport interface AdvantageConfig {\n    configUrlResolver?: () => string;\n    formats?: AdvantageFormat[];\n    formatIntegrations?: AdvantageFormatIntegration[];\n    messageValidator?: (\n        parentElement: HTMLElement | IAdvantageWrapper,\n        message: MessageEvent<any>\n    ) => boolean;\n}\n\nexport interface IAdvantageWrapper extends HTMLElement {\n    container: HTMLElement;\n    content: HTMLElement;\n    currentFormat?: AdvantageFormatName | string;\n    uiLayer: IAdvantageUILayer;\n    contentNodes: Node[];\n    allowedFormats: string[] | null;\n    morphIntoFormat: (\n        format: AdvantageFormatName | string,\n        message?: AdvantageMessage\n    ) => Promise<void>;\n    forceFormat: (\n        format: AdvantageFormatName | string,\n        iframe?: HTMLIFrameElement,\n        options?: any\n    ) => Promise<void>;\n    applyStylesToAllChildElements: (styles: string) => void;\n    insertCSS: (CSS: string) => void;\n    resetCSS: () => void;\n    reset: () => void;\n    close: () => void;\n    changeContent: (content: string | HTMLElement) => void;\n    simulateFormat: (format: AdvantageFormatName | string) => Promise<void>;\n    animateClose: (callback?: () => void) => void;\n    setAllowedFormats: (formats: string[]) => void;\n    clearAllowedFormats: () => void;\n}\n\nexport interface IAdvantageUILayer extends HTMLElement {\n    changeContent: (content: string | HTMLElement) => void;\n    insertCSS: (CSS: string) => void;\n    getSlottedElement: (selector: string) => HTMLElement | null;\n    getAllSlottedElements: (selector: string) => HTMLElement[];\n    querySlottedElements: (selector: string) => HTMLElement[];\n}\n\nexport interface AdvantageFormat {\n    name: AdvantageFormatName | string;\n    description: string;\n    setup: (\n        wrapper: IAdvantageWrapper,\n        adIframe?: HTMLElement,\n        options?: AdvantageFormatOptions\n    ) => Promise<void>;\n    reset: (wrapper: IAdvantageWrapper, adIframe?: HTMLElement) => void;\n    close?: (wrapper: IAdvantageWrapper, adIframe?: HTMLElement) => void;\n    simulate?: (wrapper: IAdvantageWrapper) => void;\n}\n\nexport interface AdvantageFormatOptions {\n    closeButton?: boolean;\n    closeButtonText?: string;\n    closeButtonAnimationDuration?: number;\n    downArrow?: boolean;\n    height?: number;\n    sessionID?: string;\n    /**\n     * The duration in seconds before the format closes automatically.\n     * If set to 0, the format will not close automatically.\n     *\n     * @type {number}\n     * @defult 12\n     */\n    autoCloseDuration?: number;\n    /**\n     * You can customize this item to replace the default site title.\n     * When set to `false`, title will be hidden. Useful when you have customize `continueToLabel`.\n     *\n     * @type {(string | boolean)}\n     * @default window.location.hostname\n     */\n    siteTitle?: string | boolean;\n    /**\n     * Logo file to display in Welcome page header bar, right before the `continueToLabel`. Accepts a path string to the image.\n     * If not set, current sites favicon will be displayed.\n     * If set to `false`, logo will be hidden.\n     *\n     * @type {string | boolean}\n     * @default https://icons.duckduckgo.com/ip3/[hostname].ico\n     */\n    logo?: string;\n    scrollBackToTop?: boolean;\n    adLabel?: string;\n    /**\n     * Can be used to customize the label of the continue to site\n     * @defaul Continue to */\n    continueToLabel?: string;\n    /**\n     * URL to the background ad. Only used in the Double Midscroll format.\n     * This is set from the foreground ad.\n     */\n    backgroundAdURL?: string;\n    allowedOrigins?: string[];\n    dangerouslyAllowAllOrigins?: boolean;\n}\n\nexport interface AdvantageFormatIntegration {\n    format: AdvantageFormatName | string;\n    options?: AdvantageFormatOptions;\n    setup: (\n        wrapper: IAdvantageWrapper,\n        adIframe?: HTMLIFrameElement | HTMLElement\n    ) => Promise<void>;\n    teardown?: (\n        wrapper: IAdvantageWrapper,\n        adIframe?: HTMLIFrameElement | HTMLElement\n    ) => void;\n    close?: (\n        wrapper: IAdvantageWrapper,\n        adIframe?: HTMLIFrameElement | HTMLElement\n    ) => void;\n    reset?: (\n        wrapper: IAdvantageWrapper,\n        adIframe?: HTMLIFrameElement | HTMLElement\n    ) => void;\n    /** @deprecated use close */\n    onClose?: (\n        wrapper: IAdvantageWrapper,\n        adIframe?: HTMLIFrameElement | HTMLElement\n    ) => void;\n    /** @deprecated use reset */\n    onReset?: (\n        wrapper: IAdvantageWrapper,\n        adIframe?: HTMLIFrameElement | HTMLElement\n    ) => void;\n}\n\nexport interface AdvantageMessage {\n    sessionID: string;\n    type: ADVANTAGE_MESSAGE;\n    action: AdvantageMessageAction;\n    format?: AdvantageFormatName;\n    origins?: string[];\n    gqid?: string;\n    targetingMap?: { [key: string]: string[] };\n    backgroundAdURL?: string;\n}\n","export function setDimensionsUntilAdvantageAdSlot(\n    ad?: HTMLElement,\n    inclusive: boolean = true\n) {\n    function setDimensionsTo100Percent(element: HTMLElement | null) {\n        if (element) {\n            element.style.height = \"100%\";\n            element.style.width = \"100%\";\n        }\n    }\n\n    if (ad) {\n        let parent = ad.parentElement;\n        setDimensionsTo100Percent(ad);\n        while (parent) {\n            if (parent.slot === \"advantage-ad-slot\") {\n                if (inclusive) {\n                    setDimensionsTo100Percent(parent);\n                }\n                break;\n            }\n            setDimensionsTo100Percent(parent);\n            parent = parent.parentElement;\n        }\n    }\n}\n\nexport function resetDimensionsUntilAdvantageAdSlot(\n    ad?: HTMLElement,\n    inclusive: boolean = true\n) {\n    function resetDimensions(element: HTMLElement | null) {\n        if (element) {\n            element.style.height = \"\";\n            element.style.width = \"\";\n        }\n    }\n\n    if (ad) {\n        // loop through the parent elements of the ad to find advantage-ad-slot\n        let parent = ad.parentElement;\n        resetDimensions(ad);\n        while (parent) {\n            if (parent.slot === \"advantage-ad-slot\") {\n                if (inclusive) {\n                    resetDimensions(parent);\n                }\n                break;\n            }\n            resetDimensions(parent);\n            parent = parent.parentElement;\n        }\n    }\n}\n\nexport function createIframe(\n    src: string,\n    id: string,\n    className?: string,\n    styles?: string\n): HTMLIFrameElement {\n    const iframe = document.createElement(\"iframe\");\n    iframe.src = src;\n    iframe.id = id;\n    if (className) {\n        iframe.className = className;\n    }\n    if (styles) {\n        iframe.style.cssText = styles;\n    }\n    iframe.setAttribute(\n        \"sandbox\",\n        \"allow-scripts allow-same-origin allow-popups\"\n    );\n    iframe.setAttribute(\"scrolling\", \"no\");\n    return iframe;\n}\n","import {\n    AdvantageFormat,\n    AdvantageFormatName,\n    AdvantageFormatOptions\n} from \"../../types\";\nimport topscrollCSS from \"./topscroll.css?inline\";\nimport topscrollUICSS from \"./topscroll-ui.css?inline\";\nimport {\n    setDimensionsUntilAdvantageAdSlot,\n    resetDimensionsUntilAdvantageAdSlot\n} from \"./format-helper\";\nimport logger from \"../../utils/logging\";\n\nconst DEFAULT_HEIGHT = 80;\n\n/**\n * Handles the scroll behavior when the down arrow is clicked\n * @param height - The configured height of the ad (in vh percentage)\n */\nconst handleDownArrowClick = (height?: number) => {\n    logger.debug(\"Down arrow clicked\");\n    const scrollHeight =\n        height && height <= 100\n            ? window.innerHeight * (height / 100)\n            : window.innerHeight * (DEFAULT_HEIGHT / 100);\n    window.scrollBy({\n        top: scrollHeight,\n        behavior: \"smooth\"\n    });\n};\n\nexport const topscroll: AdvantageFormat = {\n    name: AdvantageFormatName.TopScroll,\n    description:\n        \"A format that sticks the ad to the top of the page as the user scrolls down.\",\n    setup: (wrapper, ad, options) => {\n        const defaults: AdvantageFormatOptions = {\n            closeButton: true,\n            closeButtonText: \"Close ad\",\n            downArrow: true,\n            height: DEFAULT_HEIGHT,\n            closeButtonAnimationDuration: 0.5\n        };\n        const config = { ...defaults, ...(options || {}) };\n\n        return new Promise((resolve) => {\n            // Inser the CSS for the top scroll format\n            wrapper.insertCSS(topscrollCSS);\n            // Set the styles for the ad iframe\n            if (ad) {\n                setDimensionsUntilAdvantageAdSlot(ad);\n            }\n\n            // Change the content of the UI layer\n            const uiContainer = document.createElement(\"div\");\n            uiContainer.id = \"ui-container\";\n\n            if (config.height && config.height <= 100) {\n                wrapper.style.setProperty(\n                    \"--adv-topscroll-height\",\n                    `${config.height}svh`\n                );\n            }\n\n            if (config?.closeButton) {\n                const closeBtn = document.createElement(\"div\");\n                closeBtn.id = \"close\";\n                closeBtn.addEventListener(\"click\", () => {\n                    logger.debug(\"Close button clicked\");\n                    wrapper.close();\n                });\n                uiContainer.appendChild(closeBtn);\n                wrapper.uiLayer.style.setProperty(\n                    \"--before-content\",\n                    `'${config.closeButtonText}'`\n                );\n                wrapper.style.setProperty(\n                    \"--adv-close-button-animation-duration\",\n                    `${config.closeButtonAnimationDuration}s`\n                );\n            }\n\n            if (config?.downArrow) {\n                const downArrow = document.createElement(\"div\");\n                downArrow.id = \"down-arrow\";\n                downArrow.addEventListener(\"click\", () =>\n                    handleDownArrowClick(config.height)\n                );\n                uiContainer.appendChild(downArrow);\n            }\n\n            wrapper.uiLayer.insertCSS(topscrollUICSS);\n            wrapper.uiLayer.changeContent(uiContainer);\n\n            resolve();\n        });\n    },\n    simulate: (wrapper) => {\n        wrapper.resetCSS();\n        wrapper.insertCSS(topscrollCSS);\n        const ad = document.createElement(\"div\");\n        ad.id = \"simulated-ad\";\n        wrapper.changeContent(ad);\n\n        // Change the content of the UI layer\n        const uiContainer = document.createElement(\"div\");\n        uiContainer.id = \"ui-container\";\n        const closeBtn = document.createElement(\"div\");\n        closeBtn.id = \"close\";\n        const downArrow = document.createElement(\"div\");\n        downArrow.id = \"down-arrow\";\n        uiContainer.appendChild(closeBtn);\n        uiContainer.appendChild(downArrow);\n        wrapper.uiLayer.insertCSS(topscrollUICSS);\n        wrapper.uiLayer.changeContent(uiContainer);\n\n        closeBtn.addEventListener(\"click\", () => {\n            logger.debug(\"Close button clicked\");\n            wrapper.close();\n        });\n\n        downArrow.addEventListener(\"click\", () =>\n            handleDownArrowClick(DEFAULT_HEIGHT)\n        );\n    },\n    reset: (wrapper, ad?) => {\n        if (ad) {\n            resetDimensionsUntilAdvantageAdSlot(ad);\n        }\n        wrapper.resetCSS();\n        wrapper.style.removeProperty(\"--adv-topscroll-height\");\n        wrapper.style.removeProperty(\"--adv-close-button-animation-duration\");\n        wrapper.uiLayer.style.removeProperty(\"--before-content\");\n    },\n    close: (wrapper) => {\n        wrapper.animateClose(() => {\n            wrapper.resetCSS();\n            wrapper.style.removeProperty(\"--adv-topscroll-height\");\n            wrapper.style.removeProperty(\n                \"--adv-close-button-animation-duration\"\n            );\n            wrapper.uiLayer.style.removeProperty(\"--before-content\");\n        });\n    }\n};\n","import { AdvantageFormat, AdvantageFormatName } from \"../../types\";\nimport styles from \"./midscroll.css?inline\";\nimport {\n    setDimensionsUntilAdvantageAdSlot,\n    resetDimensionsUntilAdvantageAdSlot\n} from \"./format-helper\";\n\nexport const midscroll: AdvantageFormat = {\n    name: AdvantageFormatName.Midscroll,\n    description:\n        \"A fullscreen format that fixes the ad to the middle of the page as the user scrolls down.\",\n    setup: (wrapper, ad) => {\n        return new Promise((resolve) => {\n            wrapper.insertCSS(styles);\n            if (ad) setDimensionsUntilAdvantageAdSlot(ad);\n\n            const uiContainer = document.createElement(\"div\");\n            uiContainer.id = \"ui-container\";\n\n            wrapper.uiLayer.changeContent(uiContainer);\n\n            resolve();\n        });\n    },\n    reset: (wrapper, ad?) => {\n        if (ad) {\n            resetDimensionsUntilAdvantageAdSlot(ad);\n        }\n        wrapper.resetCSS();\n    },\n    close: (wrapper) => {\n        wrapper.animateClose();\n    }\n};\n","import {\n    AdvantageFormat,\n    AdvantageFormatName,\n    AdvantageFormatOptions\n} from \"../../types\";\nimport varsCSS from \"./vars.css?inline\";\nimport welcomepageCSS from \"./welcomepage.css?inline\";\nimport welcomepageUICSS from \"./welcomepage-ui.css?inline\";\nimport {\n    setDimensionsUntilAdvantageAdSlot,\n    resetDimensionsUntilAdvantageAdSlot\n} from \"./format-helper\";\nimport logger from \"../../utils/logging\";\n\nexport const welcomePage: AdvantageFormat = {\n    name: AdvantageFormatName.WelcomePage,\n    description:\n        \"Positioned on top of the site content with a close button to continue to the site\",\n    setup: (wrapper, ad, options) => {\n        const defaults: AdvantageFormatOptions = {\n            autoCloseDuration: 21,\n            siteTitle: window.location.hostname,\n            logo: `https://icons.duckduckgo.com/ip3/${window.location.hostname}.ico`,\n            continueToLabel: \"To\",\n            scrollBackToTop: false,\n            adLabel: \"Advertisement\"\n        };\n        const config = { ...defaults, ...(options || {}) };\n\n        return new Promise((resolve) => {\n            // Inser the CSS for the top scroll format\n            wrapper.insertCSS(varsCSS.concat(welcomepageCSS));\n            // Set the styles for the ad iframe\n            if (ad) {\n                setDimensionsUntilAdvantageAdSlot(ad);\n            }\n            if (config.closeButtonAnimationDuration !== undefined) {\n                wrapper.style.setProperty(\n                    \"--adv-wp-transition-duration\",\n                    `${config.closeButtonAnimationDuration}s`\n                );\n            }\n\n            // Change the content of the UI layer\n            const uiContainer = document.createElement(\"div\");\n            uiContainer.id = \"ui-container\";\n\n            uiContainer.insertAdjacentHTML(\n                \"afterbegin\",\n                `<div class=\"close-area\">\n                  <div class=\"mw\">\n                    <div class=\"countdown ${\n                        config.autoCloseDuration\n                            ? \"countdown--show\"\n                            : \"countdown--hide\"\n                    }\">\n                      <div class=\"loader\"></div>\n                      <span class=\"cdw\"><span class=\"cd\">${\n                          config.autoCloseDuration\n                      }</span></span>\n                    </div>\n                    <div class=\"label\">${config.adLabel}</div>\n                    <div class=\"continue\">\n                        ${\n                            config.logo\n                                ? `<img class=\"favico\" src=\"${config.logo}\" onerror=\"this.style.display='none'\" />`\n                                : \"\"\n                        }<span class=\"to-label\">${config.continueToLabel} ${\n                    config.siteTitle ? config.siteTitle : \"\"\n                }</span><span class=\"arrow\">➜</span>\n                    </div>\n                  </div>\n                </div>`\n            );\n\n            let countdownInterval = 0;\n            let autoCloseTimeout = 0;\n\n            if (config?.autoCloseDuration) {\n                const countdownElement = uiContainer.querySelector(\".cd\");\n                let count = config.autoCloseDuration;\n                if (countdownElement) {\n                    countdownInterval = setInterval(() => {\n                        count--;\n                        countdownElement.textContent = count.toString();\n                        if (count === 0) {\n                            clearInterval(countdownInterval);\n                        }\n                    }, 1000);\n                }\n\n                wrapper.uiLayer.style.setProperty(\n                    \"--adv-wp-countdown-duration\",\n                    `${config.autoCloseDuration}s`\n                );\n\n                autoCloseTimeout = setTimeout(() => {\n                    logger.debug(\"Auto closing the ad\");\n                    wrapper.close();\n                }, config.autoCloseDuration * 1000);\n            }\n\n            const countinueElement = uiContainer.querySelector(\".continue\");\n            if (countinueElement) {\n                countinueElement.addEventListener(\"click\", () => {\n                    clearInterval(countdownInterval);\n                    clearTimeout(autoCloseTimeout);\n                    wrapper.close();\n                });\n            }\n\n            wrapper.uiLayer.insertCSS(welcomepageUICSS);\n            wrapper.uiLayer.changeContent(uiContainer);\n\n            wrapper.classList.add(\"show\");\n\n            resolve();\n        });\n    },\n    simulate: (wrapper) => {\n        wrapper.resetCSS();\n        wrapper.insertCSS(varsCSS.concat(welcomepageCSS));\n        const ad = document.createElement(\"div\");\n        ad.id = \"simulated-ad\";\n        wrapper.changeContent(ad);\n    },\n    reset: (wrapper, ad?) => {\n        if (ad) {\n            resetDimensionsUntilAdvantageAdSlot(ad);\n        }\n        wrapper.resetCSS();\n        wrapper.style.removeProperty(\"--adv-wp-transition-duration\");\n    },\n    close: (wrapper) => {\n        const container = wrapper.shadowRoot?.getElementById(\"container\");\n\n        function handleTransitionEnd() {\n            wrapper.style.display = \"none\";\n            // Remove the event listener after it has been executed\n            container?.removeEventListener(\n                \"transitionend\",\n                handleTransitionEnd\n            );\n        }\n\n        if (container) {\n            const computedStyle = window.getComputedStyle(container);\n            const transitionProperty = computedStyle.transitionProperty;\n            const transitionDuration = computedStyle.transitionDuration;\n\n            const hasTransition =\n                transitionProperty !== \"none\" &&\n                transitionDuration.split(\",\").some((d) => parseFloat(d) > 0);\n\n            if (!hasTransition) {\n                wrapper.style.display = \"none\";\n                wrapper.classList.remove(\"show\");\n                wrapper.style.height = \"0px\";\n                return;\n            }\n\n            container.addEventListener(\"transitionend\", handleTransitionEnd);\n        }\n\n        wrapper.classList.remove(\"show\");\n        wrapper.style.height = \"0px\";\n    }\n};\n","import {\n    AdvantageFormat,\n    AdvantageFormatName,\n    AdvantageFormatOptions\n} from \"../../types\";\nimport styles from \"./multi-midscroll-base.css?inline\";\nimport {\n    setDimensionsUntilAdvantageAdSlot,\n    resetDimensionsUntilAdvantageAdSlot,\n    createIframe\n} from \"./format-helper\";\nimport logger from \"../../utils/logging\";\n\nexport function createMultiMidscroll(\n    name: AdvantageFormatName,\n    description: string,\n    multiplier: number\n): AdvantageFormat {\n    return {\n        name,\n        description,\n        setup: (wrapper, ad, options) => {\n            const defaults: AdvantageFormatOptions = {\n                allowedOrigins: [],\n                dangerouslyAllowAllOrigins: false\n            };\n            const config = { ...defaults, ...(options || {}) };\n\n            function validateBackgroundAdURL(\n                backgroundAdURL: string,\n                allowedOrigins: string[]\n            ): boolean {\n                try {\n                    const urlOrigin = new URL(backgroundAdURL).origin;\n\n                    // Check if the origin is in the allowedOrigins list\n                    return (\n                        urlOrigin.startsWith(\"http\") &&\n                        allowedOrigins.includes(urlOrigin)\n                    );\n                } catch (error) {\n                    logger.error(\n                        \"Invalid backgroundAdURL:\",\n                        backgroundAdURL,\n                        error\n                    );\n                    return false; // Return false if the URL is invalid\n                }\n            }\n\n            return new Promise((resolve, reject) => {\n                if (!config.backgroundAdURL || !config.sessionID) {\n                    reject(new Error(\"backgroundAdURL or sessionID is required\"));\n                    return;\n                }\n                if (\n                    !validateBackgroundAdURL(\n                        config.backgroundAdURL,\n                        config.allowedOrigins ?? []\n                    ) &&\n                    !config.dangerouslyAllowAllOrigins\n                ) {\n                    reject(new Error(\"backgroundAdURL is not allowed\"));\n                    return;\n                }\n\n                // Set the CSS custom property for the multiplier and insert CSS\n                wrapper.insertCSS(`:host { --adv-midscroll-multiplier: ${multiplier}; } ${styles}`);\n                setDimensionsUntilAdvantageAdSlot(ad, false);\n\n                const backgroundURL = new URL(config.backgroundAdURL);\n                backgroundURL.searchParams.set(\"sessionId\", config.sessionID);\n                const background = document.createElement(\"div\");\n                background.id = \"advantage-ad-background\";\n                const backgroundIframe = createIframe(\n                    backgroundURL.toString(),\n                    \"background\",\n                    \"advantage-background-iframe\"\n                );\n                background.appendChild(backgroundIframe);\n                // maybe wait for load?\n                wrapper.shadowRoot\n                    ?.getElementById(\"ad-slot\")\n                    ?.insertAdjacentElement(\"afterbegin\", background);\n\n                logger.debug(\"GOT BACKGROUND_AD_URL\", config.backgroundAdURL);\n                resolve();\n            });\n        },\n        reset: (wrapper, ad?) => {\n            resetDimensionsUntilAdvantageAdSlot(ad, false);\n            wrapper.resetCSS();\n            wrapper.shadowRoot\n                ?.getElementById(\"ad-slot\")\n                ?.querySelector(\"#advantage-ad-background\")\n                ?.remove();\n        },\n        close: () => {}\n    };\n}","import { AdvantageFormatName } from \"../../types\";\nimport { createMultiMidscroll } from \"./multi-midscroll-base\";\n\nexport const doubleMidscroll = createMultiMidscroll(\n    AdvantageFormatName.DoubleMidscroll,\n    \"A double fullscreen format that fixes the ad to the middle of the page as the user scrolls down.\",\n    2\n);\n","import { AdvantageFormatName } from \"../../types\";\nimport { createMultiMidscroll } from \"./multi-midscroll-base\";\n\nexport const tripleMidscroll = createMultiMidscroll(\n    AdvantageFormatName.TripleMidscroll,\n    \"A triple fullscreen format that fixes the ad to the middle of the page as the user scrolls down.\",\n    3\n);","import { AdvantageFormat, AdvantageFormatName, AdvantageMessageAction } from \"../../types\";\nimport styles from \"./double-midscroll-single.css?inline\";\nimport {\n    setDimensionsUntilAdvantageAdSlot,\n    resetDimensionsUntilAdvantageAdSlot\n} from \"./format-helper\";\nimport logger from \"../../utils/logging\";\n\n// WeakMap to store cleanup functions for scroll containers\nconst scrollCleanupMap = new WeakMap<Element, () => void>();\n\n/**\n * Single-creative DoubleMidscroll format\n * \n * This format provides a 2x viewport height scroll area with scroll progress events,\n * allowing a single creative to respond to scroll position without requiring a separate\n * background creative.\n * \n * Key differences from standard DoubleMidscroll:\n * - Only one creative required (no backgroundAdURL needed)\n * - Provides scroll progress (0-1) instead of waypoint events\n * - Creative can implement its own scroll-based animations\n * - Simpler setup for advertisers who don't need separate background/foreground,\n *   for example when delivering creative as a tag\n */\nexport const doubleMidscrollSingle: AdvantageFormat = {\n    name: AdvantageFormatName.DoubleMidscrollSingleCreative,\n    description:\n        \"A double fullscreen format (2x viewport height) with scroll progress events for a single creative.\",\n    setup: (wrapper, ad) => {\n        return new Promise((resolve) => {\n            wrapper.insertCSS(styles);\n            if (ad) setDimensionsUntilAdvantageAdSlot(ad, false);\n\n            const uiContainer = document.createElement(\"div\");\n            uiContainer.id = \"ui-container\";\n            wrapper.uiLayer.changeContent(uiContainer);\n\n            // Setup scroll progress tracking\n            setupScrollProgressTracking(wrapper, ad);\n\n            logger.debug(\"DoubleMidscrollSingle format setup complete\");\n            resolve();\n        });\n    },\n    reset: (wrapper, ad?) => {\n        if (ad) {\n            resetDimensionsUntilAdvantageAdSlot(ad, false);\n        }\n        wrapper.resetCSS();\n        \n        // Clean up scroll listener using WeakMap\n        const scrollContainer = wrapper.shadowRoot?.querySelector('#ad-slot');\n        if (scrollContainer) {\n            const cleanup = scrollCleanupMap.get(scrollContainer);\n            if (cleanup) {\n                cleanup();\n                scrollCleanupMap.delete(scrollContainer);\n            }\n        }\n    },\n    close: (wrapper) => {\n        wrapper.animateClose();\n    }\n};\n\n/**\n * Sets up scroll progress tracking for the creative\n * Sends scroll progress (0-1) to the creative iframe\n */\nfunction setupScrollProgressTracking(wrapper: any, ad?: HTMLIFrameElement | HTMLElement) {\n    if (!ad) return;\n\n    const scrollContainer = wrapper.shadowRoot?.querySelector('#ad-slot');\n    if (!scrollContainer) return;\n\n    let rafId: number | null = null;\n\n    // Calculate and send scroll progress\n    const updateScrollProgress = () => {\n        const rect = scrollContainer.getBoundingClientRect();\n        const viewportHeight = window.innerHeight;\n        const containerHeight = scrollContainer.clientHeight;\n        \n        let progress = 0;\n        \n        // Calculate progress: 0 when container top enters viewport, 1 when scrolled through full container height\n        if (rect.top <= 0 && rect.bottom > viewportHeight) {\n            // Container is filling viewport - calculate progress through the 200vh\n            const scrolled = Math.abs(rect.top);\n            const totalScrollDistance = containerHeight - viewportHeight;\n            progress = Math.min(1, Math.max(0, scrolled / totalScrollDistance));\n        } else if (rect.bottom <= viewportHeight) {\n            // Scrolled past container\n            progress = 1;\n        }\n\n        // Send scroll progress to creative\n        sendScrollProgress(wrapper, progress);\n    };\n\n    // Use scroll event with requestAnimationFrame for smooth updates\n    const handleScroll = () => {\n        if (rafId) {\n            cancelAnimationFrame(rafId);\n        }\n        rafId = requestAnimationFrame(updateScrollProgress);\n    };\n\n    window.addEventListener('scroll', handleScroll, { passive: true });\n    \n    // Initial calculation\n    updateScrollProgress();\n    \n    // Store cleanup function in WeakMap to avoid polluting DOM\n    scrollCleanupMap.set(scrollContainer, () => {\n        window.removeEventListener('scroll', handleScroll);\n        if (rafId) {\n            cancelAnimationFrame(rafId);\n        }\n    });\n\n    logger.debug(\"Scroll progress tracking initialized for DoubleMidscrollSingle\");\n}\n\n/**\n * Sends scroll progress to the creative using the established MessagePort channel.\n * This ensures the message reaches the creative even when nested in multiple iframes.\n */\nfunction sendScrollProgress(wrapper: any, progress: number) {\n    if (!wrapper.messageHandler) {\n        logger.debug('Cannot send scroll progress: messageHandler not available');\n        return;\n    }\n\n    wrapper.messageHandler.sendMessage({\n        action: AdvantageMessageAction.SCROLL_PROGRESS,\n        progress: progress\n    });\n}\n","import { topscroll } from \"./topscroll\";\nimport { midscroll } from \"./midscroll\";\nimport { welcomePage } from \"./welcomepage\";\nimport { doubleMidscroll } from \"./double-midscroll\";\nimport { tripleMidscroll } from \"./triple-midscroll\";\nimport { doubleMidscrollSingle } from \"./double-midscroll-single\";\n\nexport const defaultFormats = [\n    topscroll,\n    midscroll,\n    welcomePage,\n    doubleMidscroll,\n    tripleMidscroll,\n    doubleMidscrollSingle\n];\n","import { logger } from \"../utils\";\n\nimport type {\n    AdvantageConfig,\n    IAdvantageWrapper,\n    AdvantageFormat,\n    AdvantageFormatIntegration\n} from \"../types\";\nimport { defaultFormats } from \"./formats\";\n\n/**\n * The main class for the Advantage library. This class is a singleton and is used to configure the library, register wrappers, and register custom elements.\n * @public\n */\nexport class Advantage {\n    private static instance: Advantage | null = null;\n    config: AdvantageConfig | null = null;\n    defaultFormats: AdvantageFormat[] = defaultFormats;\n    wrappers: IAdvantageWrapper[] = [];\n    #customWrappers: HTMLElement[] = [];\n    formats: Map<string, AdvantageFormat> = new Map();\n    formatIntegrations: Map<string, AdvantageFormatIntegration> = new Map();\n    public static id = 0;\n\n    private constructor() {\n        Advantage.id++;\n        logger.info(\"Advantage constructor\", Advantage.id);\n    }\n    // Entry point for the library. This is where the configuration is loaded and the library is initialized.\n    public configure(config: AdvantageConfig) {\n        if (config.configUrlResolver) {\n            logger.info(\"Config URL resolver provided\");\n            this.loadConfig(config.configUrlResolver());\n        } else {\n            logger.info(\n                \"No config URL resolver provided, using provided config\"\n            );\n            this.applyConfig(config);\n        }\n    }\n\n    // Public method to register a wrapper with the library.\n    public registerWrapper(wrapper: IAdvantageWrapper) {\n        this.wrappers.push(wrapper);\n        logger.info(\"Wrapper registered\", wrapper);\n    }\n\n    // Public method to unregister a wrapper from the library.\n    public unregisterWrapper(wrapper: IAdvantageWrapper) {\n        const index = this.wrappers.indexOf(wrapper);\n        if (index > -1) {\n            this.wrappers.splice(index, 1);\n            logger.info(\"Wrapper unregistered\", wrapper);\n        }\n    }\n\n    // Public method to register a custom wrapper with the library.\n    public registerCustomWrapper(wrapper: HTMLElement) {\n        this.#customWrappers.push(wrapper);\n        logger.info(\"Custom wrapper registered\", wrapper);\n    }\n\n    // Public method to get a reference to the singleton instance of the library.\n    public static getInstance(): Advantage {\n        if (!Advantage.instance) {\n            logger.info(\"Creating a new instance of Advantage\");\n            Advantage.instance = new Advantage();\n        }\n        return Advantage.instance;\n    }\n\n    // Private method to load the configuration from a remote file.\n    private loadConfig(configUrl: string) {\n        logger.info(`⬇ Loading config from remote URL: ${configUrl}`);\n        import(/* @vite-ignore */ configUrl)\n            .then((module) => {\n                this.applyConfig(module.default);\n            })\n            .catch((e) => {\n                logger.error(\"Error fetching config\", e);\n            });\n    }\n\n    // Private method to apply the configuration to the library.\n    private applyConfig(config: AdvantageConfig) {\n        this.config = config;\n        if (config.formats) {\n            this.mergeUniqueFormats(this.defaultFormats, config.formats);\n        } else {\n            this.formats = new Map(defaultFormats.map((f) => [f.name, f]));\n        }\n        logger.info(\"Format configurations applied ✅\", this.formats);\n        if (config.formatIntegrations) {\n            for (const integration of config.formatIntegrations) {\n                this.formatIntegrations.set(integration.format, integration);\n            }\n            logger.info(\n                \"Format integrations applied ✅\",\n                this.formatIntegrations\n            );\n        }\n    }\n\n    // Private helper method to merge the default formats with the user provided formats.\n    private mergeUniqueFormats(\n        localFormats: AdvantageFormat[],\n        userFormats: AdvantageFormat[]\n    ): AdvantageFormat[] {\n        const mergedArray = [...localFormats, ...userFormats];\n        const formatsMap = new Map<string, AdvantageFormat>();\n        for (const item of mergedArray) {\n            formatsMap.set(item.name, item);\n        }\n        this.formats = formatsMap;\n        return Array.from(formatsMap.values());\n    }\n}\n","import {\n    IAdvantageWrapper,\n    AdvantageAd,\n    AdvantageMessage,\n    AdvantageMessageAction\n} from \"../../types\";\nimport { Advantage } from \"../advantage\";\nimport { collectIframes, logger, ADVANTAGE } from \"../../utils\";\n\n/**\n * AdvantageAdSlotResponder can be used by website owners/publishers if they already have their own custom implementations of high impact ad formats\n * or if they do not want to use the AdvantageWrapper component for some reason. It takes care of listening for messages from Advantage ads and handling them.\n * It will handle the creation of a new session, format requests, and format confirmations.\n * @public\n * @remarks\n * This class is internally used by the AdvantageWrapper component to handle messages from Advantage ads. It can also be used by website owners/publishers to handle messages from ads if they have their own custom implementations of high-impact ad formats.\n *\n * @example\n * To handle messages from Advantage ads in a custom implementation, you can create an instance of the AdvantageAdSlotResponder class and pass in the configuration object.\n * ```typescript\n * new AdvantageAdSlotResponder({\n *      adSlotElement: document.querySelector(\"#the-ad-slot-element\")!,\n *      formatRequestHandler: (format, parentElement) => {\n *           return new Promise((resolve, reject) => {\n *              // handle the format request here, e.g. by transforming the parent element into the requested format\n *              // resolve the promise if the format transformation was succesful or reject it if it failed\n *          });\n * });\n * ```\n */\nexport class AdvantageAdSlotResponder {\n    #element: HTMLElement | IAdvantageWrapper;\n    #messageValidator:\n        | ((\n              adSlotElement: HTMLElement | IAdvantageWrapper,\n              message: MessageEvent<any>\n          ) => boolean)\n        | undefined = undefined;\n    #defaultMessageValidator(\n        _adSlotElement: HTMLElement | IAdvantageWrapper,\n        event: MessageEvent<AdvantageMessage>\n    ): boolean {\n        // Basic validation - check if message has expected properties\n        if (!event.data || typeof event.data !== \"object\") {\n            return false;\n        }\n\n        // Check if the message has a type field that matches ADVANTAGE\n        if (event.data.type !== \"ADVANTAGE\") {\n            return false;\n        }\n\n        // Check for essential action property\n        if (!event.data.action) {\n            return false;\n        }\n\n        return true;\n    }\n    #isWrapper: boolean;\n    #messagePort: MessagePort | null = null;\n    #formatRequestHandler:\n        | ((format: string, parentElement: HTMLElement) => Promise<void>)\n        | undefined = undefined;\n    ad: AdvantageAd | null = null;\n    /**\n     * Constructs a new instance of the AdvantageAdSlotResponder, initializing it with the provided configuration.\n     *\n     * @param config - The configuration object for the class instance.\n     * @param config.adSlotElement - The HTML element that is/contains the ad slot where Advantage ads will loaded/displayed.\n     * @param config.formatRequestHandler - An optional function that handles format requests. It takes a format string and a parent element as arguments. This function can be used to customize the handling of different ad formats.\n     * @param config.messageValidator - An optional function that validates incoming messages. It takes a parent element (which can be an `HTMLElement` or an `IAdvantageWrapper`) and the message event as arguments. It should return a boolean indicating whether the message is valid.\n     */\n    constructor(config: {\n        adSlotElement: HTMLElement;\n        formatRequestHandler?: (\n            format: string,\n            parentElement: HTMLElement\n        ) => Promise<void>;\n        messageValidator?: (\n            parentElement: HTMLElement | IAdvantageWrapper,\n            message: MessageEvent<any>\n        ) => boolean;\n    }) {\n        if (!config.adSlotElement) {\n            throw new Error(\"An adSlotElement must be provided\");\n        }\n        this.#element = config.adSlotElement;\n        this.#formatRequestHandler = config.formatRequestHandler;\n        this.#messageValidator = config.messageValidator;\n        this.#isWrapper = this.#isAdvantageWrapper(config.adSlotElement);\n\n        if (!this.#isWrapper) {\n            /* Advantage wrappers will report themselves to the Advantage instance\n            But since this is a custom wrapper, we need to register it manually */\n            Advantage.getInstance().registerCustomWrapper(config.adSlotElement);\n        }\n        // Bind the listenForMessages function to ensure 'this' context\n        this.#listenForMessages = this.#listenForMessages.bind(this);\n        window.addEventListener(\"message\", this.#listenForMessages);\n    }\n    /**\n     * This method handles incoming messages from Advantage ads and processes them accordingly.\n     * @internal\n     */\n    #handleMessage = async (event: MessageEvent<AdvantageMessage>) => {\n        // Handle the message here\n        const message = event.data;\n        // The message is a request to start a session\n        if (message.action === AdvantageMessageAction.START_SESSION) {\n            logger.debug(\"start session!\", event);\n\n            // A new session starting means a new ad has loaded. If the wrapper still\n            // has an active format from a previous session, reset it now so stale\n            // styles and state are cleared before the new ad can request a format.\n            if (this.#isWrapper) {\n                const wrapper = this.#element as IAdvantageWrapper;\n                if (wrapper.currentFormat) {\n                    logger.info(\n                        `New START_SESSION received while format \"${wrapper.currentFormat}\" is active. ` +\n                            \"Resetting the wrapper.\"\n                    );\n                    wrapper.reset();\n                }\n            }\n\n            this.#messagePort = event.ports[0];\n            this.#messagePort.postMessage({\n                type: ADVANTAGE,\n                action: AdvantageMessageAction.CONFIRM_SESSION,\n                sessionID: message.sessionID\n            });\n            this.#messagePort.onmessage = this.#handleMessage.bind(this);\n        }\n        if (message.action === AdvantageMessageAction.REQUEST_FORMAT) {\n            if (this.#isWrapper) {\n                (this.#element as IAdvantageWrapper)\n                    .morphIntoFormat(message.format!, message)\n                    .then(() => {\n                        logger.info(\"morphed into format\", message.format!);\n                        this.#messagePort?.postMessage({\n                            type: ADVANTAGE,\n                            action: AdvantageMessageAction.FORMAT_CONFIRMED,\n                            sessionID: message.sessionID\n                        });\n                    })\n                    .catch((error) => {\n                        logger.error(\"morphing failed\", message.format!, error);\n                        this.#messagePort?.postMessage({\n                            type: ADVANTAGE,\n                            action: AdvantageMessageAction.FORMAT_REJECTED,\n                            sessionID: message.sessionID\n                        });\n                    });\n            } else {\n                if (this.#formatRequestHandler) {\n                    logger.debug(\n                        \"Sending format request\",\n                        this.#formatRequestHandler\n                    );\n                    this.#formatRequestHandler(message.format!, this.#element)\n                        .then(() => {\n                            this.#messagePort?.postMessage({\n                                type: ADVANTAGE,\n                                action: AdvantageMessageAction.FORMAT_CONFIRMED,\n                                sessionID: message.sessionID\n                            });\n                        })\n                        .catch(() => {\n                            this.#messagePort?.postMessage({\n                                type: ADVANTAGE,\n                                action: AdvantageMessageAction.FORMAT_REJECTED,\n                                sessionID: message.sessionID\n                            });\n                        });\n                }\n            }\n        }\n    };\n    /**\n     * Checks if the message is from an ad that is already registered\n     * @internal\n     */\n    #childAdIsAlreadyRegistered(source: MessageEventSource | null) {\n        if (!source) {\n            return false;\n        }\n        return this.ad && this.ad.eventSource === source;\n    }\n\n    /**\n     * This method listens for incoming messages from Advantage ads and processes them accordingly.\n     * @internal\n     */\n    #listenForMessages = (event: MessageEvent) => {\n        if (this.#childAdIsAlreadyRegistered(event.source)) {\n            logger.info(\n                \"A message was received from a child of the component. 👍\",\n                event\n            );\n            this.#handleMessage(event as MessageEvent<AdvantageMessage>);\n            return;\n        }\n\n        const validator =\n            this.#messageValidator || this.#defaultMessageValidator.bind(this);\n        if (!validator(this.#element, event)) {\n            return;\n        }\n\n        const childAdFinder = (iframe: HTMLIFrameElement) => {\n            /*\n             * The message is from an iframe. We need to check if the iframe is a child of the component.\n             * This is done by checking if the iframe.contentWindow is equal to the event.source.\n             * If it is, we can be sure that the message is from a child of the component.\n             * But the event can also be from a child of a child of the component.\n             */\n            const MAX_ITERATIONS = 10;\n            let iterations = 0;\n            let currentWindow: Window | null = event.source as Window;\n\n            while (\n                currentWindow &&\n                currentWindow !== window.top &&\n                iterations < MAX_ITERATIONS\n            ) {\n                iterations++;\n                try {\n                    if (iframe.contentWindow === currentWindow) {\n                        logger.info(\n                            \"The message is from a child of the component. 👍\"\n                        );\n                        this.ad = {\n                            iframe,\n                            eventSource: event.source!,\n                            port: event.ports[0]\n                        };\n                        this.#handleMessage(\n                            event as MessageEvent<AdvantageMessage>\n                        );\n                        break;\n                    }\n                    currentWindow = currentWindow.parent;\n                } catch (error) {\n                    logger.error(\n                        \"Error while traversing iframe hierarchy\",\n                        error\n                    );\n                    break;\n                }\n            }\n        };\n        if (this.#isWrapper) {\n            const iframes = (\n                this.#element as IAdvantageWrapper\n            ).contentNodes.flatMap((node) => collectIframes(node));\n            if (iframes.length === 0) {\n                return;\n            }\n            iframes.forEach(childAdFinder);\n        } else {\n            // Check if the source window is a child of the #element\n            logger.debug(\"NOT A WRAPPER!\", this.#element);\n            Array.from(this.#element.getElementsByTagName(\"iframe\")).forEach(\n                childAdFinder\n            );\n        }\n    };\n    /**\n     * Checks if the provided element is an instance of IAdvantageWrapper.\n     * @internal\n     */\n    #isAdvantageWrapper(\n        element: HTMLElement | IAdvantageWrapper\n    ): element is IAdvantageWrapper {\n        return (\n            \"container\" in element &&\n            \"currentFormat\" in element &&\n            \"uiLayer\" in element &&\n            \"morphIntoFormat\" in element\n        );\n    }\n\n    /**\n     * Sends a message to the creative through the established MessagePort channel.\n     * This method ensures messages are delivered even when the creative is nested in multiple iframes.\n     * \n     * @param message - The message to send to the creative\n     * @returns true if the message was sent successfully, false if no message channel is established\n     * \n     * @public\n     * @example\n     * ```typescript\n     * // Send a scroll progress update to the creative\n     * responder.sendMessage({\n     *     type: 'advantage',\n     *     action: 'SCROLL_PROGRESS',\n     *     progress: 0.5\n     * });\n     * ```\n     */\n    sendMessage(message: Partial<AdvantageMessage>): boolean {\n        if (!this.#messagePort) {\n            logger.debug('Cannot send message: MessagePort not established');\n            return false;\n        }\n\n        try {\n            this.#messagePort.postMessage({\n                type: ADVANTAGE,\n                ...message\n            });\n            return true;\n        } catch (error) {\n            logger.error('Failed to send message via MessagePort:', error);\n            return false;\n        }\n    }\n}\n","import { Advantage } from \"./advantage\";\nimport {\n    AdvantageFormatName,\n    IAdvantageUILayer,\n    IAdvantageWrapper,\n    AdvantageMessage,\n    AdvantageMessageAction\n} from \"../types\";\n\nimport {\n    logger,\n    traverseNodes,\n    supportsAdoptingStyleSheets,\n    ADVANTAGE\n} from \"../utils\";\n\nimport { AdvantageAdSlotResponder } from \"./messaging/publisher-side\";\n\n/**\n * Represents the AdvantageWrapper class, which extends the HTMLElement class and implements the IAdvantageWrapper interface.\n * This class is responsible for creating and managing the wrapper element for Advantage ads.\n * @noInheritDoc\n */\nexport class AdvantageWrapper extends HTMLElement implements IAdvantageWrapper {\n    // Constants\n    static readonly DISCONNECT_TIMEOUT_MS = 100;\n\n    // Private fields\n    #styleSheet: CSSStyleSheet | HTMLStyleElement;\n    #root: ShadowRoot;\n    #slotAdvantageContent: HTMLSlotElement;\n    #slotChangeRegistered = false;\n    #trackedIframes = new WeakSet<HTMLIFrameElement>();\n    #activeFormatIframe: HTMLIFrameElement | null = null;\n    #mutationObserver: MutationObserver | null = null;\n    #slotChangeHandler: (() => void) | null = null;\n    #disconnectTimeout: ReturnType<typeof setTimeout> | null = null;\n    // Whitelist set via attribute or API; when present it overrides exclude‑formats\n    allowedFormats: string[] | null = null;\n    // Public fields\n    container: HTMLDivElement;\n    content: HTMLDivElement;\n    uiLayer: IAdvantageUILayer;\n    currentFormat: AdvantageFormatName | string = \"\";\n    messageHandler: AdvantageAdSlotResponder;\n    simulating = false;\n\n    /**\n     * Creates an instance of AdvantageWrapper.\n     */\n    constructor() {\n        super();\n        if (supportsAdoptingStyleSheets) {\n            this.#styleSheet = new CSSStyleSheet();\n        } else {\n            this.#styleSheet = document.createElement(\n                \"style\"\n            ) as HTMLStyleElement;\n        }\n\n        this.#root = this.attachShadow({ mode: \"open\" });\n\n        if (supportsAdoptingStyleSheets) {\n            this.#root.adoptedStyleSheets = [this.#styleSheet as CSSStyleSheet];\n        } else {\n            this.#root.appendChild(this.#styleSheet as HTMLStyleElement);\n        }\n\n        // Create the container div\n        this.container = document.createElement(\"div\");\n        this.container.id = \"container\";\n\n        // Create the content div\n        this.content = document.createElement(\"div\");\n        this.content.id = \"ad-slot\";\n        this.content.className = \"advantage-ad-slot\";\n\n        // Create the first slot, this is for advantage-content\n        this.#slotAdvantageContent = document.createElement(\"slot\");\n        this.#slotAdvantageContent.name = \"advantage-ad-slot\";\n\n        // Create the second slot, this is for the ui layer\n        const slotOverlay = document.createElement(\"slot\");\n        slotOverlay.name = \"overlay\";\n\n        // Create the advantage-ui-layer element\n        this.uiLayer = document.createElement(\n            \"advantage-ui-layer\"\n        ) as IAdvantageUILayer;\n\n        // Append the slots and the advantage-overlay to the content div\n        this.content.appendChild(this.#slotAdvantageContent);\n        this.content.appendChild(slotOverlay);\n        this.content.appendChild(this.uiLayer);\n\n        // Append the content div to the container\n        this.container.appendChild(this.content);\n\n        // Append the container to the shadow root\n        this.#root.append(this.container);\n\n        // Register the wrapper with the hub, so that it is aware of its existence\n        Advantage.getInstance().registerWrapper(this);\n\n        this.#slotChangeHandler = () => {\n            if (!this.#slotChangeRegistered) {\n                logger.info(\"The content slot has been changed\");\n                this.#slotChangeRegistered = true;\n                return;\n            }\n            //logger.error(\"The advantage-content slot should not be changed\");\n        };\n        this.#slotAdvantageContent.addEventListener(\n            \"slotchange\",\n            this.#slotChangeHandler\n        );\n        this.#detectDOMChanges();\n        this.messageHandler = new AdvantageAdSlotResponder({\n            adSlotElement: this,\n            messageValidator: Advantage.getInstance().config?.messageValidator\n        });\n\n        // Temporary log for testing the new iframe tracking version\n        logger.info(\n            \"🔍 AdvantageWrapper initialized with ENHANCED iframe tracking (fix/detect-reset branch) 🔍\"\n        );\n    }\n\n    /**\n     * Updates the current-format attribute to match the currentFormat property.\n     * Sets the attribute when currentFormat has a value, removes it when empty.\n     */\n    #updateCurrentFormatAttribute() {\n        if (this.currentFormat) {\n            this.setAttribute(\"current-format\", this.currentFormat);\n        } else {\n            this.removeAttribute(\"current-format\");\n        }\n    }\n\n    /**\n     * Detects DOM changes and resets the wrapper if a new ad is loaded.\n     * Tracks iframes and resets the wrapper when an iframe that requested a format is removed.\n     */\n    #detectDOMChanges = () => {\n        this.#mutationObserver = new MutationObserver((mutations) => {\n            // Loop through all mutation records\n            mutations.forEach((mutation) => {\n                // We only care about added or removed nodes\n                if (mutation.type === \"childList\") {\n                    // Check for added nodes\n                    mutation.addedNodes.forEach((node) => {\n                        // Is this node an iframe?\n                        if ((node as Element).tagName === \"IFRAME\") {\n                            const iframe = node as HTMLIFrameElement;\n                            logger.debug(\"An <iframe> was added:\", iframe);\n\n                            // Track this iframe\n                            this.#trackedIframes.add(iframe);\n\n                            // If we have an active format but the active iframe was replaced,\n                            // we need to reset\n                            if (\n                                this.currentFormat &&\n                                this.#activeFormatIframe &&\n                                this.#activeFormatIframe !== iframe &&\n                                !this.simulating\n                            ) {\n                                logger.info(\n                                    \"A new <iframe> was added while a format is active. \" +\n                                        \"The previous iframe may have been replaced. Resetting wrapper.\"\n                                );\n                                this.reset();\n                            }\n                        }\n                    });\n\n                    // Check for removed nodes\n                    mutation.removedNodes.forEach((node) => {\n                        if ((node as Element).tagName === \"IFRAME\") {\n                            const iframe = node as HTMLIFrameElement;\n\n                            // Only reset if this was the iframe that requested a format\n                            if (this.#activeFormatIframe === iframe) {\n                                if (\n                                    this.currentFormat &&\n                                    this.simulating === false\n                                ) {\n                                    logger.debug(\n                                        \"The active format <iframe> was removed. \" +\n                                            \"This probably means that a new ad was loaded. \" +\n                                            \"Resetting the wrapper.\"\n                                    );\n                                    this.reset();\n                                }\n                            } else if (this.#trackedIframes.has(iframe)) {\n                                logger.debug(\n                                    \"A tracked <iframe> was removed, but it wasn't the active format iframe.\"\n                                );\n                            } else {\n                                logger.debug(\n                                    \"An untracked <iframe> was removed.\"\n                                );\n                            }\n                        }\n                    });\n                }\n            });\n        });\n        this.#mutationObserver.observe(this, {\n            childList: true,\n            subtree: true\n        });\n    };\n\n    /**\n     * Gets the content nodes assigned to the advantage-ad-slot.\n     * @returns An array of content nodes.\n     */\n    get contentNodes() {\n        return this.#slotAdvantageContent.assignedNodes() ?? [];\n    }\n\n    /**\n     * Simulates a specific ad format.\n     * @param format - The format to simulate.\n     */\n    simulateFormat = async (format: string) => {\n        if (this.simulating) {\n            return;\n        }\n        this.simulating = true;\n        const formatConfig = Advantage.getInstance().formats.get(format);\n        if (formatConfig && formatConfig.simulate) {\n            logger.debug(\"SIMULATE FORMAT\");\n            formatConfig.simulate(this);\n        }\n    };\n\n    /**\n     * Restrict this wrapper to the given list of formats.\n     * Calling this method overrides any list previously set via attribute or API.\n     * @param formats Array of format names that are allowed for this wrapper.\n     */\n    setAllowedFormats(formats: string[]) {\n        this.allowedFormats = formats.map((f) => f.trim().toUpperCase());\n    }\n\n    /**\n     * Clears the programmatic whitelist so the wrapper falls back to attribute or default behaviour.\n     */\n    clearAllowedFormats() {\n        this.allowedFormats = null;\n    }\n\n    /**\n     * Morphs the wrapper into a specific ad format.\n     * If `allowed-formats` is set (via attribute or API) it takes precedence over `exclude-formats`.\n     * Comparisons are case-insensitive.\n     * @param format - The format to morph into.\n     * @param sessionID - The session ID for the ad.\n     * @param backgroundAdURL - The URL for the background ad.\n     * @returns A promise that resolves when the morphing is complete.\n     */\n    morphIntoFormat = async (\n        format: AdvantageFormatName | string,\n        message?: AdvantageMessage\n    ) => {\n        logger.debug(\"MORPH INTO FORMAT\");\n        return new Promise<void>(async (resolve, reject) => {\n            const formatId = format.toUpperCase();\n            // 1. Check for an explicit allow‑list (attribute or programmatic).\n            const attrAllowed = this.getAttribute(\"allowed-formats\")\n                ?.split(\",\")\n                .map((f) => f.trim().toUpperCase())\n                .filter(Boolean);\n            const allowedList = this.allowedFormats ?? attrAllowed;\n            if (allowedList && !allowedList.includes(formatId)) {\n                logger.info(\n                    `The format \"${formatId}\" is not in the allowed-formats list (${allowedList.join(\n                        \", \"\n                    )}).`\n                );\n                reject(\n                    `The format ${formatId} is not allowed for this wrapper. 🛑`\n                );\n                return;\n            }\n\n            // 2. If no allow‑list, fall back to exclude‑list logic.\n            const forbiddenFormats = !allowedList\n                ? this.getAttribute(\"exclude-formats\")\n                      ?.split(\",\")\n                      .map((f) => f.trim().toUpperCase())\n                : undefined;\n            if (forbiddenFormats && forbiddenFormats.includes(formatId)) {\n                logger.info(\n                    `This wrapper does not support the format(s): \"${forbiddenFormats.join(\n                        \", \"\n                    )}\".`\n                );\n                reject(\n                    `The format ${formatId} is forbidden for this wrapper. 🛑`\n                );\n                return;\n            }\n            // If a format is already active, reset it before applying the new one.\n            // This handles the case where a placement is refreshed and a new ad requests\n            // a different format before the previous session has been torn down.\n            if (this.currentFormat) {\n                logger.info(\n                    `A new format \"${format}\" was requested while \"${this.currentFormat}\" is still active. ` +\n                        \"Resetting the current format first.\"\n                );\n                this.reset();\n            }\n\n            this.currentFormat = format;\n            this.#updateCurrentFormatAttribute();\n            let formatConfig = Advantage.getInstance().formats.get(\n                format as string\n            );\n\n            if (!formatConfig) {\n                formatConfig = Advantage.getInstance().defaultFormats.find(\n                    (f) => f.name === format\n                );\n                if (!formatConfig) {\n                    reject(\n                        `😱 The format ${format} is not supported. No configuration was found.`\n                    );\n                    this.currentFormat = \"\";\n                    this.#updateCurrentFormatAttribute();\n                    return;\n                }\n            }\n\n            const integration = Advantage.getInstance().formatIntegrations.get(\n                this.currentFormat as string\n            );\n\n            try {\n                // Track the iframe that is requesting this format\n                if (this.messageHandler.ad?.iframe) {\n                    this.#activeFormatIframe = this.messageHandler.ad\n                        .iframe as HTMLIFrameElement;\n                    logger.debug(\n                        `Set active format iframe for format: ${format}`,\n                        this.#activeFormatIframe\n                    );\n                }\n\n                // 1. First we call the format setup function with optinal user defined format options\n                await formatConfig.setup(this, this.messageHandler.ad?.iframe, {\n                    ...integration?.options,\n                    backgroundAdURL: message?.backgroundAdURL,\n                    sessionID: message?.sessionID\n                });\n\n                // 2. Then we call the integration setup function to apply site-specific adjustments\n                await integration?.setup(this, this.messageHandler.ad?.iframe);\n\n                resolve();\n            } catch (error) {\n                this.reset();\n                reject(error);\n            }\n        });\n    };\n\n    /**\n     * Forces a specific ad format without waiting for a message from the iframe.\n     * This allows publishers to directly control which format to display.\n     *\n     * @param format - The format to apply\n     * @param iframe - The iframe element to use for the ad (optional)\n     * @param options - Additional options to pass to the format's setup function\n     * @returns A promise that resolves when the format has been applied\n     */\n    forceFormat = async (\n        format: AdvantageFormatName | string,\n        iframe?: HTMLIFrameElement,\n        options?: any\n    ) => {\n        logger.debug(\"FORCE FORMAT\", format);\n\n        // If iframe is provided, create an AdvantageAd object\n        if (iframe) {\n            // Create a dummy MessageChannel for type compatibility\n            const channel = new MessageChannel();\n\n            this.messageHandler.ad = {\n                iframe,\n                eventSource: iframe.contentWindow!,\n                port: channel.port1 // Using port1 from the MessageChannel instead of null\n            };\n        }\n\n        // Create a session ID if needed for the format\n        const sessionID = Math.random().toString(36).substring(2, 15);\n\n        // Construct a message object with the format and session ID\n        const message: AdvantageMessage = {\n            type: ADVANTAGE,\n            action: AdvantageMessageAction.REQUEST_FORMAT,\n            format: format,\n            sessionID: sessionID,\n            ...options\n        };\n\n        // Call morphIntoFormat with the constructed message\n        return this.morphIntoFormat(format, message);\n    };\n\n    /**\n     * Changes the content of the wrapper.\n     * @param content - The new content to be added to the wrapper.\n     */\n    changeContent(content: string | HTMLElement) {\n        // Access the projected content in the light DOM\n        const projectedContent = this.querySelector(\n            '[slot=\"advantage-ad-slot\"]'\n        );\n        projectedContent?.remove();\n        // Check the type of the new content and add it accordingly\n        if (typeof content === \"string\") {\n            // If the content is a string, create a container for it\n            const container = document.createElement(\"div\");\n            container.innerHTML = content;\n            // Assign the slot attribute so it gets projected correctly\n            container.setAttribute(\"slot\", \"advantage-ad-slot\");\n            this.appendChild(container); // Add to the light DOM of the custom element\n        } else {\n            // If the content is an HTMLElement, directly set the slot attribute and append\n            content.setAttribute(\"slot\", \"advantage-ad-slot\");\n            this.appendChild(content); // Add to the light DOM of the custom element\n        }\n    }\n\n    /**\n     * Resets the current ad format.\n     */\n    reset() {\n        if (!this.currentFormat) {\n            return;\n        }\n\n        logger.debug(\"Resetting wrapper. Current format:\", this.currentFormat);\n\n        const formatConfig = Advantage.getInstance().formats.get(\n            this.currentFormat\n        );\n        if (formatConfig) {\n            formatConfig.reset(this, this.messageHandler?.ad?.iframe);\n        }\n        const integration = Advantage.getInstance().formatIntegrations.get(\n            this.currentFormat\n        );\n        if (integration) {\n            if (typeof integration.reset === \"function\") {\n                integration.reset(this, this.messageHandler?.ad?.iframe);\n            } else if (typeof integration.onReset === \"function\") {\n                integration.onReset(this, this.messageHandler?.ad?.iframe);\n            }\n        }\n        this.uiLayer.changeContent(\"\");\n        this.currentFormat = \"\";\n        this.#updateCurrentFormatAttribute();\n\n        // Always clear injected styles, even if the format's reset forgot to\n        this.resetCSS();\n\n        // Clear the active format iframe reference\n        this.#activeFormatIframe = null;\n        logger.debug(\"Wrapper reset complete. Active iframe cleared.\");\n    }\n\n    animateClose(callback?: () => void) {\n        this.classList.add(\"animate\");\n        this.addEventListener(\n            \"transitionend\",\n            () => {\n                // If a new format has started (currentFormat is set), abort cleanup\n                if (this.currentFormat) {\n                    return;\n                }\n                this.style.display = \"none\";\n                if (callback) {\n                    callback();\n                }\n            },\n            { once: true }\n        );\n        this.style.height = \"0px\";\n    }\n\n    /**\n     * Closes the current ad format.\n     */\n    close() {\n        if (!this.currentFormat) {\n            logger.info(\"No format to close.\");\n            return;\n        }\n        const formatConfig = Advantage.getInstance().formats.get(\n            this.currentFormat\n        );\n        logger.info(\n            \"Advantage.getInstance().formats\",\n            Advantage.getInstance().formats\n        );\n        logger.info(\"Advantage.getInstance().id\", Advantage.id);\n        logger.info(\"Closing the current format.\", formatConfig);\n        if (formatConfig) {\n            logger.info(\"Closing the current format.\", formatConfig);\n            formatConfig.close\n                ? formatConfig.close(this, this.messageHandler?.ad?.iframe)\n                : undefined;\n        }\n        const integration = Advantage.getInstance().formatIntegrations.get(\n            this.currentFormat\n        );\n        if (integration) {\n            if (typeof integration.close === \"function\") {\n                integration.close(this, this.messageHandler?.ad?.iframe);\n            } else if (typeof integration.onClose === \"function\") {\n                integration.onClose(this, this.messageHandler?.ad?.iframe);\n            }\n        }\n        this.currentFormat = \"\";\n        this.#updateCurrentFormatAttribute();\n\n        // Clear the active format iframe reference\n        this.#activeFormatIframe = null;\n        logger.debug(\"Format closed. Active iframe cleared.\");\n    }\n\n    /**\n     * Applies styles to all child elements of the wrapper.\n     * @param styles - The CSS styles to apply.\n     */\n    applyStylesToAllChildElements(styles: string) {\n        this.contentNodes.forEach((node) =>\n            traverseNodes(node, (node) => {\n                if (\n                    node instanceof HTMLDivElement ||\n                    node instanceof HTMLIFrameElement\n                ) {\n                    node.style.cssText = styles;\n                }\n            })\n        );\n    }\n\n    /**\n     * Inserts CSS into the shadow root of the wrapper.\n     * @param CSS - The CSS to insert.\n     */\n    insertCSS(CSS: string) {\n        if (supportsAdoptingStyleSheets) {\n            (this.#styleSheet as CSSStyleSheet).replaceSync(CSS);\n        } else {\n            (this.#styleSheet as HTMLStyleElement).textContent = CSS;\n        }\n    }\n\n    /**\n     * Resets the CSS in the shadow root of the wrapper.\n     */\n    resetCSS() {\n        if (supportsAdoptingStyleSheets) {\n            (this.#styleSheet as CSSStyleSheet).replaceSync(\"\");\n        } else {\n            (this.#styleSheet as HTMLStyleElement).textContent = \"\";\n        }\n    }\n\n    /**\n     * Lifecycle method called when the element is disconnected from the DOM.\n     * Uses a timeout to distinguish between temporary removal and actual cleanup.\n     */\n    disconnectedCallback() {\n        logger.debug(\"AdvantageWrapper disconnected from DOM. Cleaning up.\");\n\n        // Disconnect the mutation observer\n        this.#mutationObserver?.disconnect();\n\n        // Remove event listener\n        if (this.#slotChangeHandler) {\n            this.#slotAdvantageContent.removeEventListener(\n                \"slotchange\",\n                this.#slotChangeHandler\n            );\n        }\n\n        // Unregister from Advantage instance\n        Advantage.getInstance().unregisterWrapper(this);\n\n        // Use a timeout to distinguish between temporary removal and actual cleanup\n        this.#disconnectTimeout = setTimeout(() => {\n            logger.debug(\"AdvantageWrapper disconnected from DOM. Resetting.\");\n            this.reset();\n            this.#disconnectTimeout = null;\n        }, AdvantageWrapper.DISCONNECT_TIMEOUT_MS);\n    }\n\n    /**\n     * Lifecycle method called when the element is connected to the DOM.\n     * Clears the disconnect timeout if the element reconnects quickly.\n     */\n    connectedCallback() {\n        // Clear the timeout if reconnected quickly (element was temporarily removed)\n        if (this.#disconnectTimeout) {\n            logger.debug(\n                \"AdvantageWrapper reconnected to DOM. Canceling reset.\"\n            );\n            clearTimeout(this.#disconnectTimeout);\n            this.#disconnectTimeout = null;\n        }\n    }\n}\n","import { supportsAdoptingStyleSheets } from \"../utils\";\n/**\n * Represents the UI layer for an Advantage high-impact format.\n * This class extends the HTMLElement class and provides methods for manipulating the UI content and styles.\n * @noInheritDoc\n */\nexport class AdvantageUILayer extends HTMLElement {\n    #root: ShadowRoot;\n    #styleSheet: CSSStyleSheet | HTMLStyleElement;\n    #container: HTMLDivElement;\n    #content: HTMLDivElement;\n    slotName = \"advantage-ui-content\";\n    /**\n     * Creates an instance of AdvantageUILayer.\n     * Attaches a shadow root to the element and initializes the necessary elements.\n     */\n    constructor() {\n        super();\n        if (supportsAdoptingStyleSheets) {\n            this.#styleSheet = new CSSStyleSheet();\n        } else {\n            this.#styleSheet = document.createElement(\n                \"style\"\n            ) as HTMLStyleElement;\n        }\n        this.#root = this.attachShadow({ mode: \"open\" });\n        if (supportsAdoptingStyleSheets) {\n            this.#root.adoptedStyleSheets = [this.#styleSheet as CSSStyleSheet];\n        } else {\n            this.#root.appendChild(this.#styleSheet as HTMLStyleElement);\n        }\n        this.#container = document.createElement(\"div\");\n        this.#container.id = \"container\";\n        this.#content = document.createElement(\"div\");\n        this.#content.id = \"content\";\n        this.#container.appendChild(this.#content);\n        this.#root.append(this.#container);\n    }\n\n    /**\n     * Changes the content of the UI layer.\n     * @param content - The new content to be displayed. It can be either a string or an HTMLElement.\n     */\n    changeContent(content: string | HTMLElement) {\n        if (typeof content === \"string\") {\n            this.#content.innerHTML = content;\n        } else {\n            this.#content.innerHTML = \"\";\n            this.#content.appendChild(content);\n        }\n    }\n\n    /**\n     * Inserts CSS styles into the UI layer.\n     * @param CSS - The CSS styles to be inserted.\n     */\n    insertCSS(CSS: string) {\n        if (supportsAdoptingStyleSheets) {\n            (this.#styleSheet as CSSStyleSheet).replaceSync(CSS);\n        } else {\n            (this.#styleSheet as HTMLStyleElement).textContent = CSS;\n        }\n    }\n}\n","import {\n    sendMessageAndOpenChannel,\n    sendMessageAndAwaitResponse\n} from \"../../utils/messaging\";\nimport {\n    AdvantageMessage,\n    AdvantageMessageAction,\n    AdvantageFormatName\n} from \"../../types\";\nexport { AdvantageMessageAction, AdvantageFormatName };\nimport logger from \"../../utils/logging\";\n\n/**\n * AdvantageCreativeMessenger is the class that should be used in creative ads to communicate with Advantage on the publisher side. This class is used to request formats and other information from the parent website.\n * @public\n *\n * @example\n * Here's an example on how to request a format from the parent website and then start the ad when the format is confirmed:\n *\n * ::: code-group\n * ```typescript\n * const advantageMessenger = new AdvantageCreativeMessenger();\n * const session = await advantageMessenger.startSession();\n *\n * if (session) {\n *  // Request the midscroll format\n *  const response = await advantageMessenger.sendMessage({\n *      action: AdvantageMessageAction.REQUEST_FORMAT,\n *      format: AdvantageFormatName.Midscroll\n *  });\n *  // The format is confirmed, start the ad\n *  if (response?.action === AdvantageMessageAction.FORMAT_CONFIRMED) {\n *      document.body.classList.add(\"midscroll\");\n *  }\n * } else {\n *      console.log(\"Session failed to start\");\n * }\n * ```\n * ```javascript\n * const advantageMessenger = new AdvantageCreativeMessenger();\n * advantageMessenger.startSession().then((confirmed) => {\n *  if (confirmed) {\n *      advantageMessenger.sendMessage({\n *          action: \"REQUEST_FORMAT\",\n *          format: \"MIDSCROLL\"\n *      }).then((response) => {\n *          if (response.action === \"FORMAT_CONFIRMED\") {\n *              // The format is confirmed, start the ad\n *              document.body.classList.add(\"midscroll\");\n *          }\n *      });\n *  } else {\n *     console.log(\"Session failed to start\");\n *  }\n * });\n * ```\n */\nexport class AdvantageCreativeMessenger {\n    #messageChannel: MessageChannel | null = null;\n    #sessionID: string;\n    #validSession = false;\n    #broadcastChannel: BroadcastChannel | null = null;\n\n    constructor() {\n        // check if its a sessionId in the URL, if not create a new one\n        const urlParams = new URLSearchParams(window.location.search);\n        const sessionId = urlParams.get(\"sessionId\");\n        if (sessionId) {\n            this.#sessionID = sessionId;\n            this.#validSession = true;\n        } else {\n            // Create a new session ID\n            // This is a random string that will be used to identify the session\n            this.#sessionID = Math.random().toString(36).substring(2, 15);\n        }\n    }\n\n    async startSession(): Promise<boolean> {\n        try {\n            const { messageChannel, reply } = await sendMessageAndOpenChannel({\n                type: \"ADVANTAGE\",\n                action: AdvantageMessageAction.START_SESSION,\n                sessionID: this.#sessionID\n            });\n            this.#messageChannel = messageChannel;\n            this.#validSession =\n                reply.action === AdvantageMessageAction.CONFIRM_SESSION;\n            return this.#validSession;\n        } catch (e) {\n            this.#validSession = false;\n            return false;\n        }\n    }\n\n    async sendMessage(message: Partial<AdvantageMessage>) {\n        if (!this.#validSession || !this.#messageChannel) {\n            throw new Error(\"There is no valid session to send messages to.\");\n        }\n        try {\n            const response = await sendMessageAndAwaitResponse(\n                {\n                    ...message,\n                    sessionID: this.#sessionID,\n                    type: \"ADVANTAGE\"\n                },\n                this.#messageChannel,\n                1000\n            );\n\n            return response;\n        } catch (e) {\n            logger.error(\"Error sending message\", e);\n        }\n    }\n\n    onMessage(callback: (message: AdvantageMessage) => void) {\n        if (!this.#messageChannel) {\n            throw new Error(\"No message port available\");\n        }\n        this.#messageChannel.port1.addEventListener(\n            \"message\",\n            (event: MessageEvent) => {\n                callback(event.data as AdvantageMessage);\n            }\n        );\n    }\n\n    setupWaypoints(waypoints: HTMLElement[]): { disconnect: () => void } {\n        if (!this.#validSession) {\n            throw new Error(\"There is no valid session to send messages to.\");\n        }\n\n        this.#broadcastChannel = new BroadcastChannel(this.#sessionID);\n\n        // Setup Intersection Observer\n        const observer = new IntersectionObserver((entries) => {\n            entries.forEach((entry) => {\n                const waypointId = (entry.target as HTMLElement).dataset.id;\n                const isIntersecting = entry.isIntersecting;\n\n                // Broadcast waypoint status\n                this.#broadcastChannel!.postMessage({\n                    type: \"waypoint\",\n                    waypointId,\n                    isIntersecting\n                });\n            });\n        });\n\n        // Observe each waypoint\n        waypoints.forEach((waypoint) => observer.observe(waypoint));\n\n        return {\n            disconnect: () => {\n                observer.disconnect();\n                this.#broadcastChannel!.close();\n            }\n        };\n    }\n\n    listenToWaypoints(\n        onWaypointTrigger: (waypointId: string, isIntersecting: boolean) => void\n    ): { disconnect: () => void } {\n        if (!this.#validSession) {\n            throw new Error(\"No valid session available.\");\n        }\n\n        // Create a new BroadcastChannel for this context\n        this.#broadcastChannel = new BroadcastChannel(this.#sessionID);\n\n        const listener = (event: MessageEvent) => {\n            const { waypointId, isIntersecting } = event.data;\n            if (waypointId !== undefined && isIntersecting !== undefined) {\n                onWaypointTrigger(waypointId, isIntersecting);\n            }\n        };\n\n        //this.#broadcastChannel.onmessage = listener;\n        this.#broadcastChannel.addEventListener(\"message\", (event) => {\n            listener(event);\n        });\n\n        return {\n            disconnect: () => this.#broadcastChannel!.close()\n        };\n    }\n}\n","export { Advantage } from \"./advantage\";\nimport { AdvantageWrapper } from \"./wrapper\";\nimport { AdvantageUILayer } from \"./ui-layer\";\nimport logger from \"../utils/logging\";\nimport { advantageWrapAdSlotElement as actualAdvantageWrapAdSlotElement } from \"../utils/wrapping-helper\";\nexport { actualAdvantageWrapAdSlotElement as advantageWrapAdSlotElement };\nexport * from \"./messaging\";\nexport * from \"../types\";\n\n// Process any queued items\nif ((window as any).advantageWrapQueue) {\n    for (let item of (window as any).advantageWrapQueue) {\n        const [target, excludedFormats] = item;\n        actualAdvantageWrapAdSlotElement(target, excludedFormats);\n    }\n}\n\n// Replace the global function with the actual function\n(window as any).advantageWrapAdSlotElement = actualAdvantageWrapAdSlotElement;\n\n// Process the advantageCmdQueue\nif ((window as any).advantageCmdQueue) {\n    for (let callback of (window as any).advantageCmdQueue) {\n        try {\n            callback(actualAdvantageWrapAdSlotElement);\n        } catch (error) {\n            logger.error(\"Error executing callback:\", error);\n        }\n    }\n} else {\n    (window as any).advantageCmdQueue = [];\n}\n\n(window as any).advantageCmdQueue.push = function (callback: any) {\n    Array.prototype.push.call(this, callback);\n    try {\n        callback(actualAdvantageWrapAdSlotElement);\n    } catch (error) {\n        logger.error(\"Error executing callback:\", error);\n    }\n};\n\n// Run new commands immediately\n(window as any).advantageCmd = function (callback: any) {\n    try {\n        callback(actualAdvantageWrapAdSlotElement);\n    } catch (error) {\n        logger.error(\"Error executing callback:\", error);\n    }\n};\n\ncustomElements.define(\"advantage-wrapper\", AdvantageWrapper);\ncustomElements.define(\"advantage-ui-layer\", AdvantageUILayer);\n"],"names":["Logger","__publicField","level","message","optionalParams","logger","collectIframes","node","iframes","element","child","traverseNodes","func","supportsAdoptingStyleSheets","ADVANTAGE","sendMessageAndOpenChannel","retryInterval","maxAttempts","attempts","replyReceived","getTargetWindow","currentWindow","targetWindow","createMessageContext","avic","_a","qemid","_b","targetingMap","_c","origins","backgroundAdURL","resolve","reject","sendMessage","messageWithContext","channel","event","retryIntervalRef","sendMessageAndAwaitResponse","messageChannel","timeout","timeoutID","responseListener","advantageWrapAdSlotElement","target","excludedFormats","allowedFormats","advantageWrapper","formats","slotDiv","AdvantageMessageAction","AdvantageFormatName","setDimensionsUntilAdvantageAdSlot","ad","inclusive","setDimensionsTo100Percent","parent","resetDimensionsUntilAdvantageAdSlot","resetDimensions","createIframe","src","id","className","styles","iframe","DEFAULT_HEIGHT","handleDownArrowClick","height","scrollHeight","topscroll","wrapper","options","config","topscrollCSS","uiContainer","closeBtn","downArrow","topscrollUICSS","midscroll","welcomePage","varsCSS","welcomepageCSS","countdownInterval","autoCloseTimeout","countdownElement","count","countinueElement","welcomepageUICSS","container","handleTransitionEnd","computedStyle","transitionProperty","transitionDuration","d","createMultiMidscroll","name","description","multiplier","validateBackgroundAdURL","allowedOrigins","urlOrigin","error","backgroundURL","background","backgroundIframe","doubleMidscroll","tripleMidscroll","scrollCleanupMap","doubleMidscrollSingle","setupScrollProgressTracking","scrollContainer","cleanup","rafId","updateScrollProgress","rect","viewportHeight","containerHeight","progress","scrolled","totalScrollDistance","sendScrollProgress","handleScroll","defaultFormats","_Advantage","__privateAdd","_customWrappers","index","__privateGet","configUrl","module","f","integration","localFormats","userFormats","mergedArray","formatsMap","item","Advantage","AdvantageAdSlotResponder","_AdvantageAdSlotResponder_instances","_element","_messageValidator","_isWrapper","_messagePort","_formatRequestHandler","_handleMessage","__privateSet","_listenForMessages","__privateMethod","childAdIsAlreadyRegistered_fn","defaultMessageValidator_fn","childAdFinder","iterations","isAdvantageWrapper_fn","_adSlotElement","source","_AdvantageWrapper","_AdvantageWrapper_instances","_styleSheet","_root","_slotAdvantageContent","_slotChangeRegistered","_trackedIframes","_activeFormatIframe","_mutationObserver","_slotChangeHandler","_disconnectTimeout","_detectDOMChanges","mutations","mutation","format","formatConfig","formatId","attrAllowed","allowedList","forbiddenFormats","updateCurrentFormatAttribute_fn","_d","_e","sessionID","slotOverlay","content","projectedContent","_f","callback","CSS","AdvantageWrapper","AdvantageUILayer","_container","_content","AdvantageCreativeMessenger","_messageChannel","_sessionID","_validSession","_broadcastChannel","sessionId","reply","waypoints","observer","entries","entry","waypointId","isIntersecting","waypoint","onWaypointTrigger","listener","actualAdvantageWrapAdSlotElement"],"mappings":"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"}