)]}'
{"version": 3, "sources": ["/website/static/src/interactions/animation.edit.js", "/website/static/src/interactions/carousel.edit.js", "/website/static/src/interactions/carousel/carousel_bootstrap_upgrade_fix.edit.js", "/website/static/src/interactions/carousel/carousel_slider.edit.js", "/website/static/src/interactions/dropdown.edit.js", "/website/static/src/interactions/dropdown/hoverable_dropdown.edit.js", "/website/static/src/interactions/dropdown/mega_menu_dropdown.edit.js", "/website/static/src/interactions/full_screen_height.edit.js", "/website/static/src/interactions/header/base_header.edit.js", "/website/static/src/interactions/image_gallery.edit.js", "/website/static/src/interactions/image_shape_hover_effect.edit.js", "/website/static/src/interactions/popup/no_backdrop_popup.edit.js", "/website/static/src/interactions/popup/shared_popup.edit.js", "/website/static/src/interactions/search_modal.edit.js", "/website/static/src/interactions/social_media.edit.js", "/website/static/src/interactions/video/media_video.edit.js", "/website/static/src/interactions/zoomed_background_shape.edit.js", "/website/static/src/snippets/s_announcement_scroll/announcement_scroll.edit.js", "/website/static/src/snippets/s_chart/chart.edit.js", "/website/static/src/snippets/s_countdown/countdown.edit.js", "/website/static/src/snippets/s_dynamic_snippet/dynamic_snippet.edit.js", "/website/static/src/snippets/s_dynamic_snippet_carousel/dynamic_snippet_carousel.edit.js", "/website/static/src/snippets/s_embed_code/embed_code.edit.js", "/website/static/src/snippets/s_facebook_page/facebook_page.edit.js", "/website/static/src/snippets/s_floating_blocks/floating_blocks.edit.js", "/website/static/src/snippets/s_google_map/google_map.edit.js", "/website/static/src/snippets/s_image_gallery/gallery_slider.edit.js", "/website/static/src/snippets/s_instagram_page/instagram_page.edit.js", "/website/static/src/snippets/s_searchbar/search_bar_btn.edit.js", "/website/static/src/snippets/s_table_of_content/table_of_content.edit.js", "/website/static/src/snippets/s_website_form/form.edit.js", "/website/static/src/core/website_edit_service.js", "/website_payment/static/src/snippets/s_donation/donation_snippet.edit.js", "/website_payment/static/src/snippets/s_supported_payment_methods/supported_payment_methods.edit.js", "/website_profile/static/src/interactions/profile_editor.edit.js"], "mappings": "AAAA;;;;;;;;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;ACnBA;;;;;;;;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;ACxEA;;;;;;;;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;ACnBA;;;;;;;;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;ACzBA;;;;;;;;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;AC9BA;;;;;;;;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;ACxBA;;;;;;;;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;ACjDA;;;;;;;;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;ACfA;;;;;;;;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;ACbA;;;;;;;;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;ACxBA;;;;;;;;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;ACjFA;;;;;;;;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;AC/BA;;;;;;;;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;ACdA;;;;;;;;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;AChBA;;;;;;;;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;ACdA;;;;;;;;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;ACfA;;;;;;;;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;ACfA;;;;;;;;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;AC3BA;;;;;;;;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;ACrBA;;;;;;;;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;ACpBA;;;;;;;;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;AChBA;;;;;;;;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;ACpBA;;;;;;;;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;AChCA;;;;;;;;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;AChBA;;;;;;;;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;ACjDA;;;;;;;;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;AC3FA;;;;;;;;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;ACfA;;;;;;;;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;ACrBA;;;;;;;;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;ACpBA;;;;;;;;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;ACpBA;;;;;;;;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;ACvDA;;;;;;;;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;ACzZA;;;;;;;;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;ACbA;;;;;;;;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;AC/BA;;;;;;;;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA", "sourcesContent": ["import { Animation } from \"./animation\";\nimport { registry } from \"@web/core/registry\";\n\nconst AnimationEdit = (I) =>\n    class extends I {\n        destroy() {\n            // We remove the \"o_animate_preview\" class here because it is added\n            // when an animation is selected in the options, and the \"Animation\"\n            // interaction considers it as part of the initial state. We remove\n            // it here because otherwise it is added back when exiting edit\n            // mode.\n            this.el.classList.remove(\"o_animate_preview\");\n        }\n    };\n\nregistry.category(\"public.interactions.edit\").add(\"website.animation\", {\n    Interaction: Animation,\n    mixin: AnimationEdit,\n});\n", "import { Interaction } from \"@web/public/interaction\";\nimport { registry } from \"@web/core/registry\";\n\nexport class CarouselEdit extends Interaction {\n    static selector = \"section > .carousel\";\n    // Prevent enabling the carousel overlay when clicking on the carousel\n    // controls (indeed we want it to change the carousel slide then enable\n    // the slide overlay) + See \"CarouselItem\" option.\n    dynamicContent = {\n        \".carousel-control-prev, .carousel-control-next, .carousel-indicators\": {\n            \"t-on-click\": this.throttled(this.onControlClick),\n            \"t-att-class\": () => ({ o_we_no_overlay: true }),\n        },\n        \".carousel-control-prev, .carousel-control-next\": {\n            \"t-att-data-bs-slide\": () => undefined,\n        },\n        \".carousel-indicators > *\": {\n            \"t-att-data-bs-slide-to\": () => undefined,\n        },\n    };\n\n    /**\n     * Slides the carousel when clicking on the carousel controls. This handler\n     * allows to put the sliding in the mutex, to avoid race conditions.\n     *\n     * @param {Event} ev\n     */\n    async onControlClick(ev) {\n        // Activate the active slide.\n        this.el.querySelector(\".carousel-item.active\").click();\n\n        // Compute to which slide the carousel will slide.\n        const controlEl = ev.currentTarget;\n        let direction;\n        if (controlEl.classList.contains(\"carousel-control-prev\")) {\n            direction = \"prev\";\n        } else if (controlEl.classList.contains(\"carousel-control-next\")) {\n            direction = \"next\";\n        } else {\n            const indicatorEl = ev.target;\n            if (\n                !indicatorEl.matches(\".carousel-indicators > *\") ||\n                indicatorEl.classList.contains(\"active\")\n            ) {\n                return;\n            }\n            direction = [...controlEl.children].indexOf(indicatorEl);\n        }\n\n        // Slide the carousel\n        const applySpec = { editingElement: this.el, params: { direction: direction } };\n\n        if (this.services[\"website_edit\"].applyAction) {\n            this.services[\"website_edit\"].applyAction(\"slideCarousel\", applySpec);\n        }\n    }\n\n    destroy() {\n        const editTranslations = this.services.website_edit.isEditingTranslations();\n        if (!editTranslations) {\n            // Restore the carousel controls.\n            const indicatorEls = this.el.querySelectorAll(\".carousel-indicators > *\");\n            indicatorEls.forEach((indicatorEl, i) =>\n                indicatorEl.setAttribute(\"data-bs-slide-to\", i)\n            );\n        }\n    }\n}\n\nregistry.category(\"public.interactions.edit\").add(\"website.carousel_edit\", {\n    Interaction: CarouselEdit,\n});\n", "import { CarouselBootstrapUpgradeFix } from \"@website/interactions/carousel/carousel_bootstrap_upgrade_fix\";\nimport { registry } from \"@web/core/registry\";\nimport { withHistory } from \"@website/core/website_edit_service\";\n\nconst CarouselBootstrapUpgradeFixEdit = (I) =>\n    class extends I {\n        // Suspend ride in edit mode.\n        carouselOptions = { ride: false, pause: true, keyboard: false };\n\n        setup() {\n            super.setup();\n            this.dynamicContent = withHistory(this.dynamicContent);\n        }\n    };\n\nregistry.category(\"public.interactions.edit\").add(\"website.carousel_bootstrap_upgrade_fix\", {\n    Interaction: CarouselBootstrapUpgradeFix,\n    mixin: CarouselBootstrapUpgradeFixEdit,\n});\n", "import { CarouselSlider } from \"@website/interactions/carousel/carousel_slider\";\nimport { registry } from \"@web/core/registry\";\n\nconst CarouselSliderEdit = (I) =>\n    class extends I {\n        dynamicContent = {\n            ...this.dynamicContent,\n            _root: {\n                ...this.dynamicContent._root,\n                \"t-on-content_changed\": this.onContentChanged,\n            },\n        };\n        // Pause carousel in edit mode.\n        carouselOptions = { ride: false, pause: true, keyboard: false };\n        showClickableSlideLinks = false;\n\n        onContentChanged() {\n            this.computeMaxHeight();\n        }\n    };\n\nregistry.category(\"public.interactions.edit\").add(\"website.carousel_slider\", {\n    Interaction: CarouselSlider,\n    mixin: CarouselSliderEdit,\n});\n", "import { Interaction } from \"@web/public/interaction\";\nimport { registry } from \"@web/core/registry\";\n\nexport class DropdownEdit extends Interaction {\n    static selector = \"[data-bs-toggle=dropdown]\";\n    dynamicContent = {\n        _root: {\n            // We want dropdown menus not to close when clicking inside them in\n            // edit mode.\n            \"t-att-data-bs-auto-close\": () => \"outside\",\n            \"t-on-hidden.bs.dropdown\": () => {\n                const selection = this.el.ownerDocument.getSelection();\n                if (\n                    this.el.parentElement\n                        ?.querySelector(\".dropdown-menu\")\n                        ?.contains(selection.anchorNode)\n                ) {\n                    // If the selection is in a closed dropdown, we remove it so\n                    // that overlays appearing around the selection go away\n                    // (like toolbar, or link tools)\n                    selection.empty();\n                }\n            },\n        },\n    };\n}\n\nregistry.category(\"public.interactions.edit\").add(\"website.dropdown_edit\", {\n    Interaction: DropdownEdit,\n});\n", "import { HoverableDropdown } from \"@website/interactions/dropdown/hoverable_dropdown\";\nimport { registry } from \"@web/core/registry\";\n\nconst HoverableDropdownEdit = (I) =>\n    class extends I {\n        /**\n         * @param {MouseEvent} ev\n         * @param {HTMLElement} currentTargetEl\n         */\n        onMouseEnter(ev, currentTargetEl) {\n            if (this.el.querySelector(\".dropdown-toggle.show\")) {\n                return;\n            } else {\n                super.onMouseEnter(ev, currentTargetEl);\n            }\n        }\n\n        onMouseLeave() {}\n    };\n\nregistry.category(\"public.interactions.edit\").add(\"website.hoverable_dropdown\", {\n    Interaction: HoverableDropdown,\n    mixin: HoverableDropdownEdit,\n});\n", "import { registry } from \"@web/core/registry\";\nimport { MegaMenuDropdown } from \"./mega_menu_dropdown\";\n\nconst MegaMenuDropdownEdit = (I) =>\n    class extends I {\n        dynamicContent = {\n            ...this.dynamicContent,\n            \".o_mega_menu_toggle\": {\n                ...this.dynamicContent[\".o_mega_menu_toggle\"],\n                \"t-on-click\": (ev) => {\n                    const toggleEl = ev.currentTarget;\n                    const megaMenuEl = toggleEl.parentElement.querySelector(\".o_mega_menu\");\n                    // Activate the mega menu options when shown.\n                    if (!megaMenuEl || !megaMenuEl.classList.contains(\"show\")) {\n                        this.websiteEditService.callShared(\n                            \"builderOptions\",\n                            \"deactivateContainers\"\n                        );\n                    } else {\n                        this.websiteEditService.callShared(\n                            \"builderOptions\",\n                            \"updateContainers\",\n                            megaMenuEl\n                        );\n                    }\n                },\n            },\n        };\n\n        setup() {\n            super.setup();\n            this.websiteEditService = this.services.website_edit;\n\n            // Hide all the open mega menus when destroying the interaction.\n            this.registerCleanup(() => {\n                const megaMenuToggleEls = this.el.querySelectorAll(\".o_mega_menu_toggle.show\");\n                for (const megaMenuToggleEl of megaMenuToggleEls) {\n                    const bsDropdown = window.Dropdown.getOrCreateInstance(megaMenuToggleEl);\n                    bsDropdown.hide();\n                    bsDropdown.dispose();\n                }\n            });\n        }\n    };\n\nregistry.category(\"public.interactions.edit\").add(\"website.mega_menu_dropdown\", {\n    Interaction: MegaMenuDropdown,\n    mixin: MegaMenuDropdownEdit,\n});\n", "import { registry } from \"@web/core/registry\";\nimport { FullScreenHeight } from \"./full_screen_height\";\n\nconst FullScreenHeightEdit = (I) =>\n    class extends I {\n        shouldStop() {\n            // Force restart on refresh.\n            return true;\n        }\n    };\n\nregistry.category(\"public.interactions.edit\").add(\"website.full_screen_height\", {\n    Interaction: FullScreenHeight,\n    mixin: FullScreenHeightEdit,\n});\n", "import { BaseHeader } from \"@website/interactions/header/base_header\";\nimport { registry } from \"@web/core/registry\";\n\nconst BaseHeaderEdit = (I) =>\n    class extends I {\n        adjustPosition() {}\n    };\n\nregistry.category(\"public.interactions.edit\").add(\"website.base_header\", {\n    Interaction: BaseHeader,\n    mixin: BaseHeaderEdit,\n    isAbstract: true,\n});\n", "import { Interaction } from \"@web/public/interaction\";\nimport { registry } from \"@web/core/registry\";\n\nexport class ImageGalleryEdit extends Interaction {\n    static selector = \".s_image_gallery\";\n    static selectorNotHas =\n        \"img, a.o_link_readonly, span.fa.object-fit-cover, div.media_iframe_video\";\n    dynamicContent = {\n        \".o_empty_gallery_alert\": {\n            \"t-on-click\": this.onAddImage.bind(this),\n        },\n    };\n    start() {\n        this.renderAt(\"website.empty_image_gallery_alert\", {}, this.el);\n    }\n    onAddImage() {\n        const applySpec = { editingElement: this.el };\n        this.services[\"website_edit\"].applyAction(\"addImage\", applySpec);\n    }\n}\n\nregistry.category(\"public.interactions.edit\").add(\"website.image_gallery_edit\", {\n    Interaction: ImageGalleryEdit,\n});\n", "import { registry } from \"@web/core/registry\";\nimport { ImageShapeHoverEffect } from \"./image_shape_hover_effect\";\n\nconst ImageShapeHoverEffectEdit = (I) =>\n    class extends I {\n        destroy() {\n            // The originalImgSrc might not yet be updated by sourceObserver\n            // if the interaction stops in the same tick as the mutation\n            // happens. Only restore the src if it still matches the last\n            // hovering src.\n            if (this.el.src === this.hoveringImgSrc) {\n                this.el.src = this.originalImgSrc;\n            }\n            this.disconnectSourceObserver();\n        }\n\n        // Copy of the mouseLeave of the original interaction. The only\n        // difference is that it restores the original image source after the\n        // animation is over, since in edit mode the image source might change\n        // before the end of the animation (for example while previewing shapes\n        // image filters or something else).\n        mouseLeave() {\n            this.lastMouseEvent = this.lastMouseEvent.then(\n                () =>\n                    new Promise((resolve) => {\n                        if (!this.originalImgSrc || !this.svgInEl || !this.el.dataset.hoverEffect) {\n                            resolve();\n                            return;\n                        }\n                        if (!this.svgOutEl) {\n                            // Reverse animations.\n                            this.svgOutEl = this.svgInEl.cloneNode(true);\n                            const animateTransformEls = this.svgOutEl.querySelectorAll(\n                                \"#hoverEffects animateTransform, #hoverEffects animate\"\n                            );\n                            animateTransformEls.forEach((animateTransformEl) => {\n                                let valuesValue = animateTransformEl.getAttribute(\"values\");\n                                valuesValue = valuesValue.split(\";\").reverse().join(\";\");\n                                animateTransformEl.setAttribute(\"values\", valuesValue);\n                            });\n                        }\n                        this.setImgSrc(this.svgOutEl, () => {\n                            // After the animation, restore original src\n                            setTimeout(() => {\n                                if (this.isDestroyed) {\n                                    resolve();\n                                    return;\n                                }\n                                this.disconnectSourceObserver();\n                                this.el.src = this.originalImgSrc;\n                                this.connectSourceObserver();\n                                this.el.onload = () => {\n                                    resolve();\n                                };\n                            }, this.getAnimationMaxDuration(this.svgOutEl));\n                        });\n                    })\n            );\n        }\n\n        // returns the time after which the animation should be over\n        getAnimationMaxDuration(svg) {\n            let maxDuration = 0;\n            const animateEls = svg.querySelectorAll(\n                \"#hoverEffects animateTransform, #hoverEffects animate\"\n            );\n            animateEls.forEach((animateEl) => {\n                const dur = animateEl.getAttribute(\"dur\");\n                if (dur) {\n                    const duration = parseFloat(dur) * (dur.endsWith(\"ms\") ? 1 : 1000);\n                    maxDuration = Math.max(maxDuration, duration);\n                }\n            });\n            return maxDuration;\n        }\n    };\n\nregistry.category(\"public.interactions.edit\").add(\"website.image_shape_hover_effect\", {\n    Interaction: ImageShapeHoverEffect,\n    mixin: ImageShapeHoverEffectEdit,\n});\n", "import { NoBackdropPopup } from \"./no_backdrop_popup\";\nimport { registry } from \"@web/core/registry\";\n\nexport const NoBackdropPopupEdit = (I) =>\n    class extends I {\n        start() {\n            super.start();\n            if (this.el.classList.contains(\"show\")) {\n                // Use case: When the \"Backdrop\" option is disabled in edit\n                // mode. The page scrollbar must be adjusted and events must be\n                // added.\n                this.addModalNoBackdropEvents();\n            }\n        }\n\n        addModalNoBackdropEvents() {\n            // We shouldn't normally go through this 2x without removing the\n            // observers in between, but it happens when opening the editor\n            // (start) and then showing the popup (dynamicContent listener).\n            if (this.resizeObserver) {\n                this.removeResizeListener();\n                this.resizeObserver.disconnect();\n            }\n            super.addModalNoBackdropEvents();\n        }\n    };\n\nregistry.category(\"public.interactions.edit\").add(\"website.no_backdrop_popup\", {\n    Interaction: NoBackdropPopup,\n    mixin: NoBackdropPopupEdit,\n});\n", "import { SharedPopup } from \"./shared_popup\";\nimport { registry } from \"@web/core/registry\";\n\nexport const SharedPopupEdit = (I) =>\n    class extends I {\n        setup() {\n            this.popupShown = true;\n        }\n    };\n\nregistry.category(\"public.interactions.edit\").add(\"website.shared_popup\", {\n    Interaction: SharedPopup,\n    mixin: SharedPopupEdit,\n});\n", "import { SearchModal } from \"./search_modal\";\nimport { registry } from \"@web/core/registry\";\n\nconst SearchModalEdit = (I) =>\n    class extends I {\n        dynamicContent = {\n            _root: {\n                \"t-on-show.bs.modal.prevent\": () => {},\n            },\n        };\n    };\n\nregistry.category(\"public.interactions.edit\").add(\"website.search_modal\", {\n    Interaction: SearchModal,\n    mixin: SearchModalEdit,\n});\n", "import { Interaction } from \"@web/public/interaction\";\nimport { registry } from \"@web/core/registry\";\n\nexport class SocialMediaEdit extends Interaction {\n    static selector = \".s_social_media > :first-child\";\n\n    setup() {\n        this.renderAt(\"website.empty_social_media_alert\", {}, undefined, \"afterend\");\n    }\n}\n\nregistry.category(\"public.interactions.edit\").add(\"website.social_media_edit\", {\n    Interaction: SocialMediaEdit,\n});\n", "import { MediaVideo } from \"./media_video\";\nimport { registry } from \"@web/core/registry\";\n\nexport const MediaVideoEdit = (I) =>\n    class extends I {\n        destroy() {\n            // Destroy video iframes so they are never saved in the DOM.\n            this.el?.replaceChildren();\n        }\n    };\n\nregistry.category(\"public.interactions.edit\").add(\"website.media_video\", {\n    Interaction: MediaVideo,\n    mixin: MediaVideoEdit,\n});\n", "import { ZoomedBackgroundShape } from \"./zoomed_background_shape\";\nimport { registry } from \"@web/core/registry\";\n\nconst ZoomedBackgroundShapeEdit = (I) =>\n    class extends I {\n        shouldStop() {\n            // Force restart.\n            return true;\n        }\n    };\n\nregistry.category(\"public.interactions.edit\").add(\"website.zoomed_background_shape\", {\n    Interaction: ZoomedBackgroundShape,\n    mixin: ZoomedBackgroundShapeEdit,\n});\n", "import { registry } from \"@web/core/registry\";\nimport { AnnouncementScroll } from \"./announcement_scroll\";\n\nexport const AnnouncementScrollEdit = (I) =>\n    class extends I {\n        shouldStop() {\n            // Should always restart, because each option may modify the width of\n            // the element, meaning the interaction needs to recompute.\n            return true;\n        }\n        isImpactedBy(el) {\n            // After an update of the font family or the text content.\n            return (\n                this.el.contains(el) &&\n                el.matches(\n                    `.s_announcement_scroll_marquee_container,\n                    .s_announcement_scroll_marquee_item:first-child,\n                    .s_announcement_scroll_marquee_item:first-child > [data-oe-translation-source-sha]`\n                )\n            );\n        }\n    };\n\nregistry.category(\"public.interactions.edit\").add(\"website.announcement_scroll\", {\n    Interaction: AnnouncementScroll,\n    mixin: AnnouncementScrollEdit,\n});\n", "import { Chart } from \"./chart\";\nimport { registry } from \"@web/core/registry\";\n\nconst ChartEdit = (I) =>\n    class extends I {\n        setup() {\n            super.setup();\n            this.noAnimation = true;\n        }\n\n        start() {\n            super.start();\n            this.websiteEditService = this.services.website_edit;\n            this.websiteEditService.callShared(\"builderOverlay\", \"refreshOverlays\");\n        }\n    };\n\nregistry.category(\"public.interactions.edit\").add(\"website.chart\", {\n    Interaction: Chart,\n    mixin: ChartEdit,\n});\n", "import { Countdown } from \"./countdown\";\nimport { registry } from \"@web/core/registry\";\n\nconst CountdownEdit = (I) =>\n    class extends I {\n        setup() {\n            super.setup();\n            this.websiteEditService = this.services.website_edit;\n            this.websiteEditService.callShared(\"builderOverlay\", \"refreshOverlays\");\n        }\n        get shouldHideCountdown() {\n            return false;\n        }\n        handleEndCountdownAction() {}\n    };\n\nregistry.category(\"public.interactions.edit\").add(\"website.countdown\", {\n    Interaction: Countdown,\n    mixin: CountdownEdit,\n});\n", "import { DynamicSnippet } from \"./dynamic_snippet\";\nimport { registry } from \"@web/core/registry\";\n\nconst DynamicSnippetEdit = (I) =>\n    class extends I {\n        setup() {\n            super.setup();\n            this.withSample = true;\n        }\n        callToAction() {}\n    };\n\nregistry.category(\"public.interactions.edit\").add(\"website.dynamic_snippet\", {\n    Interaction: DynamicSnippet,\n    mixin: DynamicSnippetEdit,\n});\n", "import { DynamicSnippetCarousel } from \"@website/snippets/s_dynamic_snippet_carousel/dynamic_snippet_carousel\";\nimport { registry } from \"@web/core/registry\";\n\nconst DynamicSnippetCarouselEdit = (I) =>\n    class extends I {\n        getConfigurationSnapshot() {\n            let snapshot = super.getConfigurationSnapshot();\n            if (this.el.classList.contains(\"o_carousel_multi_items\")) {\n                snapshot = JSON.parse(snapshot || \"{}\");\n                snapshot.multi_items = true;\n                snapshot = JSON.stringify(snapshot);\n            }\n            return snapshot;\n        }\n    };\n\nregistry.category(\"public.interactions.edit\").add(\"website.dynamic_snippet_carousel\", {\n    Interaction: DynamicSnippetCarousel,\n    mixin: DynamicSnippetCarouselEdit,\n});\n", "import { EmbedCode } from \"./embed_code\";\nimport { registry } from \"@web/core/registry\";\n\nimport { _t } from \"@web/core/l10n/translation\";\n\nconst EmbedCodeEdit = (I) =>\n    class extends I {\n        start() {\n            if (this.embedCodeEl.offsetHeight === 0) {\n                // Shows a placeholder message in edit mode to be able to select\n                // the snippet if it's visually empty.\n                const placeholderEl = document.createElement(\"div\");\n                placeholderEl.classList.add(\n                    \"s_embed_code_placeholder\",\n                    \"alert\",\n                    \"alert-info\",\n                    \"pt16\",\n                    \"pb16\"\n                );\n                placeholderEl.textContent = _t(\n                    \"Your Embed Code snippet doesn't have anything to display. Click on Edit to modify it.\"\n                );\n                this.embedCodeEl.appendChild(placeholderEl);\n            }\n        }\n        destroy() {}\n    };\n\nregistry.category(\"public.interactions.edit\").add(\"website.embed_code\", {\n    Interaction: EmbedCode,\n    mixin: EmbedCodeEdit,\n});\n", "import { FacebookPage } from \"./facebook_page\";\nimport { registry } from \"@web/core/registry\";\n\nconst FacebookPageEdit = (I) =>\n    class extends I {\n        dynamicContent = {\n            iframe: {\n                \"t-att-style\": () => ({ \"pointer-events\": \"none\" }),\n            },\n        };\n    };\n\nregistry.category(\"public.interactions.edit\").add(\"website.facebook_page\", {\n    Interaction: FacebookPage,\n    mixin: FacebookPageEdit,\n});\n", "import { registry } from \"@web/core/registry\";\nimport { FloatingBlocks } from \"./floating_blocks\";\n\nconst FloatingBlocksEdit = (I) =>\n    class extends I {\n        dynamicContent = {\n            ...this.dynamicContent,\n            \".s_floating_blocks_alert_empty\": {\n                \"t-on-click\": this.onAddCard.bind(this),\n            },\n        };\n        isImpactedBy(el) {\n            return (\n                this.el.contains(el) &&\n                el.matches(\".s_floating_blocks_block, .s_floating_blocks_wrapper\")\n            );\n        }\n        shouldStop() {\n            // The interaction is restarted every time that the content of\n            // s_floating_blocks changes. This is needed to provide the correct\n            // visual effect when a block is added, removed or moved. This\n            // approach is simple, but has the drawback of restarting the\n            // interaction also when the content of a block is changed (which is\n            // not needed). A more complex approach would be to assign unique\n            // IDs to the blocks and check if their order has changed.\n            return true;\n        }\n        start() {\n            // The \"No card\" message must be injected *before* the removal of\n            // the last block, otherwise the snippet could be automatically\n            // removed by the editor during edition:\n            // see remove_plugin.isEmptyAndRemovable()\n            this.renderAt(\n                \"website.s_floating_blocks.alert.empty\",\n                {},\n                this.el.querySelector(\".s_floating_blocks_wrapper\")\n            );\n            super.start();\n        }\n        onAddCard() {\n            const applySpec = { editingElement: this.el };\n            this.services[\"website_edit\"].applyAction(\"addFloatingBlockCard\", applySpec);\n        }\n    };\n\nregistry.category(\"public.interactions.edit\").add(\"website.floating_blocks\", {\n    Interaction: FloatingBlocks,\n    mixin: FloatingBlocksEdit,\n});\n", "/* global google */\n\nimport { GoogleMap } from \"./google_map\";\nimport { registry } from \"@web/core/registry\";\n\nconst GoogleMapEdit = (I) =>\n    class extends I {\n        setup() {\n            super.setup();\n            this.canSpecifyKey = true;\n            this.websiteEditService = this.services.website_edit;\n            this.websiteMapService = this.services.website_map;\n        }\n\n        async willStart() {\n            const isLoaded =\n                (typeof google === \"object\" &&\n                    typeof google.maps === \"object\" &&\n                    !this.websiteEditService.callShared(\n                        \"googleMapsOption\",\n                        \"shouldRefetchApiKey\"\n                    )) ||\n                (await this.loadGoogleMaps(false));\n            if (isLoaded) {\n                this.canStart = await this.websiteEditService.callShared(\n                    \"googleMapsOption\",\n                    \"initializeGoogleMaps\",\n                    [this.el, google.maps]\n                );\n            } else {\n                this.websiteEditService.callShared(\n                    \"googleMapsOption\",\n                    \"failedToInitializeGoogleMaps\",\n                    [this.el]\n                );\n            }\n        }\n\n        /**\n         * Get the stored API key if any (or open a dialog to ask the user for one),\n         * load and configure the Google Maps API.\n         *\n         * @param {boolean} [forceReconfigure=false]\n         * @returns {Promise<void>}\n         */\n        async loadGoogleMaps(forceReconfigure = false) {\n            /** @type {string | undefined} */\n            const apiKey = await this.websiteMapService.getGMapAPIKey(true);\n            const apiKeyValidation = await this.websiteMapService.validateGMapApiKey(apiKey);\n            const shouldReconfigure = forceReconfigure || !apiKeyValidation.isValid;\n            let didReconfigure = false;\n            if (shouldReconfigure) {\n                didReconfigure = await this.websiteEditService.callShared(\n                    \"googleMapsOption\",\n                    \"configureGMapsAPI\",\n                    apiKey\n                );\n                if (!didReconfigure) {\n                    this.websiteEditService.callShared(\"remove\", \"removeElement\", this.el);\n                }\n            }\n            if (!shouldReconfigure || didReconfigure) {\n                const shouldRefetch = this.websiteEditService.callShared(\n                    \"googleMapsOption\",\n                    \"shouldRefetchApiKey\"\n                );\n                return !!(await this.loadGoogleMapsAPIFromService(shouldRefetch || didReconfigure));\n            } else {\n                return false;\n            }\n        }\n\n        /**\n         * Load the Google Maps API from the Google Map Service.\n         * This method is set apart so it can be overridden for testing.\n         *\n         * @param {boolean} [shouldRefetch]\n         * @returns {Promise<string|undefined>} A promise that resolves to an API\n         *                                      key if found.\n         */\n        async loadGoogleMapsAPIFromService(shouldRefetch) {\n            const apiKey = await this.websiteMapService.loadGMapAPI(true, shouldRefetch);\n            this.websiteEditService.callShared(\"googleMapsOption\", \"shouldNotRefetchApiKey\");\n            return !!apiKey;\n        }\n    };\n\nregistry.category(\"public.interactions.edit\").add(\"website.google_map\", {\n    Interaction: GoogleMap,\n    mixin: GoogleMapEdit,\n});\n", "import { GallerySlider } from \"./gallery_slider\";\nimport { registry } from \"@web/core/registry\";\n\nconst GallerySliderEdit = (I) =>\n    class extends I {\n        setup() {\n            super.setup();\n            this.hideOnClickIndicator = false;\n        }\n    };\n\nregistry.category(\"public.interactions.edit\").add(\"website.gallery_slider\", {\n    Interaction: GallerySlider,\n    mixin: GallerySliderEdit,\n});\n", "import { registry } from \"@web/core/registry\";\nimport { InstagramPage } from \"./instagram_page\";\n\nconst InstagramPageEdit = (I) =>\n    class extends I {\n        setup() {\n            super.setup();\n            this.dynamicContent[\"iframe\"] = {\n                \"t-att-style\": () => ({ \"pointer-events\": \"none\" }),\n            };\n        }\n\n        getConfigurationSnapshot() {\n            return this.el.dataset.instagramPage;\n        }\n    };\n\nregistry.category(\"public.interactions.edit\").add(\"website.instagram_page\", {\n    Interaction: InstagramPage,\n    mixin: InstagramPageEdit,\n});\n", "import { Interaction } from \"@web/public/interaction\";\nimport { registry } from \"@web/core/registry\";\n\nexport class SearchBarBtnEdit extends Interaction {\n    static selector = \".o_searchbar_form .oe_search_button\";\n\n    dynamicContent = {\n        _root: {\n            \"t-on-click\": this.onClick,\n        },\n    };\n\n    onClick(ev) {\n        ev.preventDefault();\n    }\n}\n\nregistry.category(\"public.interactions.edit\").add(\"website.search_bar_btn\", {\n    Interaction: SearchBarBtnEdit,\n});\n", "import { registry } from \"@web/core/registry\";\nimport { TableOfContent } from \"./table_of_content\";\n\nexport const TableOfContentEdit = (I) =>\n    class extends I {\n        getConfigurationSnapshot() {\n            let snapshot = super.getConfigurationSnapshot();\n            if (this.el.classList.contains(\"s_table_of_content_horizontal_navbar\")) {\n                snapshot = JSON.parse(snapshot || \"{}\");\n                snapshot.horizontalNavbar = true;\n                snapshot = JSON.stringify(snapshot);\n            }\n            return snapshot;\n        }\n    };\n\nregistry.category(\"public.interactions.edit\").add(\"website.table_of_content\", {\n    Interaction: TableOfContent,\n    mixin: TableOfContentEdit,\n});\n", "import { Interaction } from \"@web/public/interaction\";\nimport { registry } from \"@web/core/registry\";\nimport { Form } from \"./form\";\nimport { patch } from \"@web/core/utils/patch\";\nimport { formatDate, formatDateTime } from \"@web/core/l10n/dates\";\n\nconst { DateTime } = luxon;\n\nexport class FormEdit extends Interaction {\n    static selector = \".s_website_form form, form.s_website_form\"; // !compatibility\n    start() {\n        // We do not initialize the datetime picker in edit mode but want the dates to be formatted.\n        for (const el of this.el.querySelectorAll(\".s_website_form_input.datetimepicker-input\")) {\n            const value = el.getAttribute(\"value\");\n            if (value) {\n                const format =\n                    el.closest(\".s_website_form_field\").dataset.type === \"date\"\n                        ? formatDate\n                        : formatDateTime;\n                el.value = format(DateTime.fromSeconds(parseInt(value)));\n            }\n        }\n    }\n\n    // Todo: remove in master\n    _getDataForFields() {\n        if (!this.dataForValues) {\n            return [];\n        }\n        return Object.keys(this.dataForValues)\n            .map((name) => this.el.querySelector(`[name=\"${CSS.escape(name)}\"]`))\n            .filter(\n                (dataForValuesFieldEl) =>\n                    dataForValuesFieldEl && dataForValuesFieldEl.name !== \"email_to\"\n            );\n    }\n}\n\nregistry.category(\"public.interactions.edit\").add(\"website.form\", {\n    Interaction: FormEdit,\n});\n\n// Translation mode.\npatch(Form.prototype, {\n    setup() {\n        super.setup();\n        this.editTranslations = this.services.website_edit.isEditingTranslations();\n    },\n    prefillValues() {\n        if (this.editTranslations) {\n            return;\n        }\n        super.prefillValues();\n    },\n});\n", "import { registry } from \"@web/core/registry\";\nimport { PublicRoot } from \"@web/legacy/js/public/public_root\";\nimport { Colibri } from \"@web/public/colibri\";\nimport { Interaction } from \"@web/public/interaction\";\nimport { patch } from \"@web/core/utils/patch\";\nimport { setupIgnoreDOMMutations } from \"@website/js/content/auto_hide_menu\";\nimport { omit } from \"@web/core/utils/objects\";\n\nexport function buildEditableInteractions(builders) {\n    const result = [];\n\n    const mixinPerInteraction = new Map();\n    for (const makeEditable of builders) {\n        mixinPerInteraction.set(makeEditable.Interaction, makeEditable.mixin || ((C) => C));\n    }\n    for (const makeEditable of builders) {\n        if (makeEditable.isAbstract) {\n            continue;\n        }\n        let I = makeEditable.Interaction;\n        // Collect mixins to up to Interaction class in reverse order.\n        const mixins = [];\n        while (I.name !== \"Interaction\") {\n            const mixin = mixinPerInteraction.get(I);\n            if (mixin) {\n                mixins.push(mixin);\n            } else {\n                console.log(`No mixin defined for: ${I.name}`);\n            }\n            I = I.__proto__;\n        }\n        // Apply mixins from top-most class.\n        let EI = makeEditable.Interaction;\n        while (mixins.length) {\n            EI = mixins.pop()(EI);\n        }\n        if (!EI.name) {\n            // if we get here, this is most likely because we have an anonymous\n            // class. To make it easier to work with, we can add the name property\n            // by doing a little hack\n            const name = makeEditable.Interaction.name + \"__mixin\";\n            EI = { [name]: class extends EI {} }[name];\n        }\n        result.push(EI);\n    }\n    return result;\n}\n\nexport const websiteEditService = {\n    dependencies: [\"public.interactions\"],\n    start(env, { [\"public.interactions\"]: publicInteractions }) {\n        let editableInteractions = null;\n        let previewInteractions = null;\n        const patches = [];\n        const historyCallbacks = {};\n        const shared = {};\n\n        const update = (target, mode) => {\n            // editMode = true;\n            // const currentEditMode = this.website_edit.mode === \"edit\";\n\n            // interactions are already started. we only restart them if the\n            // public root is not just starting.\n            stopDisconnectedInteractions();\n            publicInteractions.stopInteractions(target);\n            if (mode === \"edit\") {\n                if (!editableInteractions) {\n                    const builders = registry.category(\"public.interactions.edit\").getAll();\n                    editableInteractions = buildEditableInteractions(builders);\n                }\n                publicInteractions.editMode = true;\n                publicInteractions.activate(editableInteractions);\n            } else if (mode === \"preview\") {\n                if (!previewInteractions) {\n                    const builders = registry.category(\"public.interactions.preview\").getAll();\n                    previewInteractions = buildEditableInteractions(builders);\n                }\n                publicInteractions.activate(previewInteractions, target);\n            } else {\n                publicInteractions.startInteractions(target);\n            }\n        };\n\n        const refresh = (target) => {\n            publicInteractions.isRefreshing = true;\n            try {\n                update(target, \"edit\");\n            } finally {\n                publicInteractions.isRefreshing = false;\n            }\n        };\n\n        const stop = (target) => {\n            publicInteractions.stopInteractions(target);\n        };\n\n        const stopInteraction = (name) => {\n            publicInteractions.stopInteractionByName(name);\n        };\n\n        const stopDisconnectedInteractions = () => {\n            for (const interaction of publicInteractions.interactions) {\n                if (!interaction.el.isConnected) {\n                    stop(interaction.el);\n                }\n            }\n        };\n\n        const isEditingTranslations = () =>\n            !!publicInteractions.el.closest(\"html\").dataset.edit_translations;\n\n        const installPatches = () => {\n            if (patches.length) {\n                return;\n            }\n\n            // Patch Colibri.\n\n            patches.push(\n                patch(Colibri.prototype, {\n                    setupInteraction() {\n                        historyCallbacks.ignoreDOMMutations(() => {\n                            super.setupInteraction();\n                        });\n                        this.interaction.setupConfigurationSnapshot();\n                    },\n                    destroyInteraction() {\n                        historyCallbacks.ignoreDOMMutations(() => {\n                            super.destroyInteraction();\n                        });\n                    },\n                    protectSyncAfterAsync(interaction, name, fn) {\n                        fn = super.protectSyncAfterAsync(interaction, name, fn);\n                        return (...args) => historyCallbacks.ignoreDOMMutations(() => fn(...args));\n                    },\n                    addListener(target, event, fn, options) {\n                        const boundFn = fn.bind(this.interaction);\n                        if (event.startsWith(\"slide.bs.carousel\")) {\n                            // Never allow cancelling this event in edit mode.\n                            fn = (...args) => {\n                                const ev = args[0];\n                                ev.preventDefault = () => {};\n                                ev.stopPropagation = () => {};\n                                return boundFn(...args);\n                            };\n                        } else {\n                            fn = boundFn;\n                        }\n                        let stealth = true;\n                        const parts = event.split(\".\");\n                        if (parts.includes(\"keepInHistory\") || options?.keepInHistory) {\n                            stealth = false;\n                            event = parts.filter((part) => part !== \"keepInHistory\").join(\".\");\n                            delete options?.keepInHistory;\n                        }\n                        let stealthFn = fn;\n                        if (historyCallbacks.ignoreDOMMutations && !fn.isHandler && stealth) {\n                            stealthFn = (...args) =>\n                                historyCallbacks.ignoreDOMMutations(() => fn(...args));\n                        }\n                        return super.addListener(target, event, stealthFn, options);\n                    },\n                    applyAttr(...args) {\n                        historyCallbacks.ignoreDOMMutations(() => super.applyAttr(...args));\n                    },\n                    applyTOut(...args) {\n                        historyCallbacks.ignoreDOMMutations(() => super.applyTOut(...args));\n                    },\n                    startInteraction(...args) {\n                        historyCallbacks.ignoreDOMMutations(() => super.startInteraction(...args));\n                    },\n                }),\n                patch(Interaction.prototype, {\n                    setupConfigurationSnapshot() {\n                        // Track configuration values.\n                        this.configurationSnapshot = this.getConfigurationSnapshot();\n                    },\n                    getConfigurationSnapshot() {\n                        // Naive generalise implementation of a snapshot that\n                        // would impact the behavior of an interaction.\n                        // To be overloaded by edit-mode interactions that need\n                        // something more specific.\n                        // TODO Sort keys to improve comparison.\n                        const dataset = omit(this.el.dataset, \"visibility\");\n                        const style = {};\n                        for (const property of this.el.style) {\n                            if (property.startsWith(\"animation\")) {\n                                if (property === \"animation-play-state\") {\n                                    continue;\n                                }\n                                style[property] = this.el.style[property];\n                            }\n                        }\n                        if (Object.keys(dataset).length || style.length) {\n                            return JSON.stringify({ dataset, style });\n                        }\n                        return NaN; // So that it is different from itself\n                    },\n                    shouldStop() {\n                        if (!this.el.isConnected) {\n                            return true;\n                        }\n                        // Selector does not match anymore ?\n                        const I = this.constructor;\n                        let isMatch = this.el.matches(I.selector);\n                        if (I.selectorHas) {\n                            isMatch &&= !!this.el.querySelector(I.selectorHas);\n                        }\n                        if (I.selectorNotHas) {\n                            isMatch &&= !this.el.querySelector(I.selectorNotHas);\n                        }\n                        if (!isMatch) {\n                            return true;\n                        }\n                        // Configuration changed ?\n                        const snapshot = this.getConfigurationSnapshot();\n                        if (snapshot === this.configurationSnapshot) {\n                            return false;\n                        }\n                        this.configurationSnapshot = snapshot;\n                        return true;\n                    },\n                    isImpactedBy(el) {\n                        return false;\n                    },\n                    insert(...args) {\n                        const el = args[0];\n                        super.insert(...args);\n                        el.setAttribute(\"contenteditable\", \"false\");\n                    },\n                }),\n                patch(publicInteractions.constructor.prototype, {\n                    shouldStop(el, interaction) {\n                        if (this.isRefreshing) {\n                            const mustBeRefreshed =\n                                super.shouldStop(el, interaction) ||\n                                interaction.interaction.isImpactedBy(el);\n                            return mustBeRefreshed && interaction.interaction.shouldStop();\n                        }\n                        return super.shouldStop(el, interaction);\n                    },\n\n                    stopInteractionByName(name) {\n                        const IToStop = registry.category(\"public.interactions\").get(name);\n                        const interactions = [];\n                        for (const interaction of this.interactions) {\n                            if (interaction.interaction.constructor === IToStop) {\n                                interaction.destroy();\n                                this.activeInteractions.delete(interaction.el, IToStop);\n                            } else {\n                                interactions.push(interaction);\n                            }\n                        }\n                        this.interactions = interactions;\n                    },\n                })\n            );\n        };\n        const uninstallPatches = () => {\n            for (const removePatch of patches) {\n                removePatch();\n            }\n            patches.length = 0;\n            setupIgnoreDOMMutations(null);\n        };\n        const applyAction = (actionId, spec) => {\n            shared.builderActions.applyAction(actionId, spec);\n        };\n        const callShared = (pluginName, methodName, args = []) => {\n            if (!Array.isArray(args)) {\n                args = [args];\n            }\n            if (shared[pluginName]) {\n                if (shared[pluginName][methodName]) {\n                    return shared[pluginName][methodName](...args);\n                } else {\n                    console.error(`Method \"${methodName}\" not found on plugin \"${pluginName}\".`);\n                }\n            } else {\n                console.error(`Plugin \"${pluginName}\" not found.`);\n            }\n        };\n\n        const websiteEditService = {\n            isEditingTranslations,\n            update,\n            refresh,\n            stop,\n            stopInteraction,\n            installPatches,\n            uninstallPatches,\n            applyAction,\n            callShared,\n        };\n\n        window.parent.document.addEventListener(\"edit_page\", (ev) => {\n            stop(ev.detail.iframeDocument);\n        });\n\n        // Transfer the iframe website_edit service to the EditInteractionPlugin\n        window.parent.document.addEventListener(\"edit_interaction_plugin_loaded\", (ev) => {\n            ev.currentTarget.dispatchEvent(\n                new CustomEvent(\"transfer_website_edit_service\", {\n                    detail: {\n                        websiteEditService,\n                    },\n                })\n            );\n            Object.assign(shared, ev.shared);\n            historyCallbacks.ignoreDOMMutations = shared.history.ignoreDOMMutations;\n            setupIgnoreDOMMutations(shared.history.ignoreDOMMutations);\n        });\n\n        return websiteEditService;\n    },\n};\nregistry.category(\"services\").add(\"website_edit\", websiteEditService);\n\n// Patch PublicRoot.\n\nPublicRoot.include({\n    // This file is lazy loaded, init will not be called when entering edit.\n    /**\n     * @override\n     */\n    _restartInteractions(targetEl, options) {\n        const websiteEdit = this.bindService(\"website_edit\");\n        const mode = options?.editableMode ? \"edit\" : \"normal\";\n        websiteEdit.update(targetEl, mode);\n    },\n});\n\n// Patch Colibri.\n\npatch(Colibri.prototype, {\n    protectSyncAfterAsync(interaction, name, fn) {\n        fn = super.protectSyncAfterAsync(interaction, name, fn);\n        const fullName = `${interaction.constructor.name}/${name}`;\n        return (...args) => {\n            // TODO No jQuery ?\n            const wysiwyg = window.$?.(\"#wrapwrap\").data(\"wysiwyg\");\n            wysiwyg?.odooEditor.observerUnactive(fullName);\n            const result = fn(...args);\n            wysiwyg?.odooEditor.observerActive(fullName);\n            return result;\n        };\n    },\n    addListener(target, event, fn, options) {\n        const boundFn = fn.bind(this.interaction);\n        if (event.startsWith(\"slide.bs.carousel\")) {\n            // Never allow cancelling this event in edit mode.\n            fn = (...args) => {\n                const ev = args[0];\n                ev.preventDefault = () => {};\n                ev.stopPropagation = () => {};\n                return boundFn(...args);\n            };\n        } else {\n            fn = boundFn;\n        }\n        let stealth = true;\n        const parts = event.split(\".\");\n        if (parts.includes(\"keepInHistory\") || options?.keepInHistory) {\n            stealth = false;\n            event = parts.filter((part) => part !== \"keepInHistory\").join(\".\");\n            delete options?.keepInHistory;\n        }\n        // TODO No jQuery ?\n        const wysiwyg = window.$?.(\"#wrapwrap\").data(\"wysiwyg\");\n        let stealthFn = fn;\n        if (wysiwyg?.odooEditor && !fn.isHandler && stealth) {\n            const name = `${this.interaction.constructor.name}/${event}`;\n            stealthFn = (...args) => {\n                wysiwyg.odooEditor.observerUnactive(name);\n                const result = fn(...args);\n                wysiwyg.odooEditor.observerActive(name);\n                return result;\n            };\n        }\n        return super.addListener(target, event, stealthFn, options);\n    },\n    applyAttr(el, attr, value) {\n        // TODO No jQuery ?\n        const wysiwyg = window.$?.(\"#wrapwrap\").data(\"wysiwyg\");\n        const name = `${this.interaction.constructor.name}/${attr}`;\n        wysiwyg?.odooEditor.observerUnactive(name);\n        super.applyAttr(...arguments);\n        wysiwyg?.odooEditor.observerActive(name);\n    },\n    applyTOut(el, value) {\n        // TODO No jQuery ?\n        const wysiwyg = window.$?.(\"#wrapwrap\").data(\"wysiwyg\");\n        const name = `${this.interaction.constructor.name}/t-out`;\n        wysiwyg?.odooEditor.observerUnactive(name);\n        super.applyTOut(...arguments);\n        wysiwyg?.odooEditor.observerActive(name);\n    },\n});\n\nexport function withHistory(dynamicContent) {\n    const result = {};\n    for (const [selector, content] of Object.entries(dynamicContent)) {\n        result[selector] = {};\n        for (const [key, value] of Object.entries(content)) {\n            result[selector][key.startsWith(\"t-on-\") ? `${key}.keepInHistory` : key] = value;\n        }\n    }\n    return result;\n}\n", "import { DonationSnippet } from \"./donation_snippet\";\nimport { registry } from \"@web/core/registry\";\n\nconst DonationSnippetEdit = I => class extends I {\n    onDonateClick() { }\n};\n\nregistry\n    .category(\"public.interactions.edit\")\n    .add(\"website_payment.donation_snippet\", {\n        Interaction: DonationSnippet,\n        mixin: DonationSnippetEdit,\n    });\n", "import { SupportedPaymentMethods } from './supported_payment_methods';\nimport { registry } from '@web/core/registry';\nimport { browser } from '@web/core/browser/browser';\n\n\nconst SupportedPaymentMethodsEdit = I => class extends I {\n    dynamicContent = {\n        // Bypass the ctrl-click required to open a link in edit mode.\n        '.o_wpay_view_providers_btn': { 't-on-click': this.onClickViewProviders.bind(this) },\n    };\n\n    /**\n     * @override To display an alert when no payment methods could be found.\n     */\n    setup() {\n        super.setup();\n        this.templateKey = 'website_payment.s_supported_payment_methods.no_payment_methods_alert';\n    }\n\n    async onClickViewProviders() {\n        // Open the view in a separate tab such that any edits are kept.\n        browser.open('/odoo/action-payment.action_payment_provider', '_blank');\n    }\n};\n\nregistry\n    .category('public.interactions.edit')\n    .add('website.supported_payment_methods', {\n        Interaction: SupportedPaymentMethods,\n        mixin: SupportedPaymentMethodsEdit,\n    });\n", "import { ProfileEditor } from \"./profile_editor\";\nimport { registry } from \"@web/core/registry\";\n\nconst ProfileEditorEdit = I => class extends I {\n    setup() { }\n    async willStart() { }\n};\n\nregistry\n    .category(\"public.interactions.edit\")\n    .add(\"website_profile.website_profile_editor\", {\n        Interaction: ProfileEditor,\n        mixin: ProfileEditorEdit,\n    });\n"], "file": "/web/assets/1/d651ec2/website.assets_inside_builder_iframe.js", "sourceRoot": "../../../../"}