{"id":7796,"date":"2025-12-09T18:54:17","date_gmt":"2025-12-09T17:54:17","guid":{"rendered":"https:\/\/serenitywellnessandspa.com\/?post_type=product&#038;p=7796"},"modified":"2026-05-23T16:42:20","modified_gmt":"2026-05-23T14:42:20","slug":"buoni-regalo-serenita","status":"publish","type":"product","link":"https:\/\/serenitywellnessandspa.com\/it\/product\/serenity-gift-vouchers\/","title":{"rendered":"Buoni regalo Serenity"},"content":{"rendered":"<p><pre id=\"code-snippet-source-10\" class=\"code-snippet-source\"><code class=\"language-php\">&lt;?php\n\nadd_action(&#039;wp_footer&#039;, function () {\n?&gt;\n&lt;script&gt;\ndocument.addEventListener(&quot;DOMContentLoaded&quot;, function () {\n\n    const lang = (document.documentElement.lang || &#039;&#039;).toLowerCase();\n    const allowedPrefixes = [&#039;fr&#039;,&#039;de&#039;,&#039;en&#039;,&#039;it&#039;];\n\n    if (!allowedPrefixes.some(l =&gt; lang.startsWith(l))) return;\n\n    function moveGiftCardUp() {\n\n        \/\/ MAIN WORKING FIX\n        const siteContent = document.querySelector(&#039;.site-content&#039;);\n        if (siteContent) {\n            siteContent.style.marginTop = &#039;-50px&#039;;\n            siteContent.style.position = &#039;relative&#039;;\n        }\n\n        \/\/ optional secondary container\n        const astContainer = document.querySelector(&#039;.site-content .ast-container&#039;);\n        if (astContainer) {\n            astContainer.style.marginTop = &#039;0px&#039;;\n        }\n\n        \/\/ keep wrapper clean\n        const gift = document.querySelector(&#039;.wt_gc_gift_card_product_page_wrapper&#039;);\n        if (gift) {\n            gift.style.marginTop = &#039;0px&#039;;\n            gift.style.position = &#039;relative&#039;;\n        }\n    }\n\n    function disableStickyCart() {\n        const el = document.querySelector(&#039;.ast-sticky-add-to-cart&#039;);\n        if (!el) return;\n\n        el.style.display = &#039;none&#039;;\n        el.style.visibility = &#039;hidden&#039;;\n        el.style.opacity = &#039;0&#039;;\n        el.style.pointerEvents = &#039;none&#039;;\n        el.classList.remove(&#039;is-active&#039;);\n    }\n\n    function runAll() {\n        moveGiftCardUp();\n        disableStickyCart();\n    }\n\n    runAll();\n\n    const observer = new MutationObserver(runAll);\n    observer.observe(document.body, {\n        childList: true,\n        subtree: true\n    });\n\n    window.addEventListener(&#039;resize&#039;, runAll);\n    window.addEventListener(&#039;scroll&#039;, runAll);\n\n});\n&lt;\/script&gt;\n&lt;?php\n});<\/code><\/pre><pre id=\"code-snippet-source-11\" class=\"code-snippet-source\"><code class=\"language-php\">&lt;?php\n\nadd_action(&#039;wp_footer&#039;, function () {\n?&gt;\n&lt;script&gt;\n(function () {\n\n    let selectedEmployeeId   = 0;\n    let selectedEmployeeName = &#039;&#039;;\n    let lastKey              = &#039;&#039;;\n    let slotTimer            = null;\n    let observerLocked       = false;\n    let ameliaReadyDone      = false;\n\n    \/* ---------------------------------------------------------------\n       Vuex store\n    --------------------------------------------------------------- *\/\n    function getStore() {\n        const app = document.querySelector(&#039;[data-v-app]&#039;);\n        return app?.__vue_app__?.config?.globalProperties?.$store || null;\n    }\n\n    function getServiceId() {\n        const store = getStore();\n        return store?.state?.booking?.appointment?.serviceId || 0;\n    }\n\t\n\t\/* ---------------------------------------------------------------\n\t   Clear selected therapist completely\n\t--------------------------------------------------------------- *\/\n\tfunction clearSelectedEmployee() {\n\n\t\tconst store = getStore();\n\n\t\tselectedEmployeeId = 0;\n\t\tselectedEmployeeName = &#039;&#039;;\n\n\t\tsessionStorage.removeItem(&#039;amelia_emp_id&#039;);\n\t\tsessionStorage.removeItem(&#039;amelia_emp_name&#039;);\n\n\t\tif (!store) return;\n\n\t\ttry {\n\t\t\tstore.commit(&#039;booking\/setEmployeeId&#039;, null);\n\t\t} catch(e){}\n\n\t\ttry {\n\n\t\t\tconst appointment = store.state.booking?.appointment;\n\n\t\t\tif (appointment) {\n\t\t\t\tappointment.providerId = null;\n\t\t\t\tappointment.employeeId = null;\n\t\t\t}\n\n\t\t\tconst appointments = store.state.booking?.appointments;\n\n\t\t\tif (Array.isArray(appointments)) {\n\n\t\t\t\tappointments.forEach(a=&gt;{\n\n\t\t\t\t\ta.providerId = null;\n\t\t\t\t\ta.employeeId = null;\n\n\t\t\t\t\tif (a.provider) {\n\t\t\t\t\t\ta.provider.id = null;\n\t\t\t\t\t}\n\n\t\t\t\t\tif (Array.isArray(a.bookings)) {\n\n\t\t\t\t\t\ta.bookings.forEach(b=&gt;{\n\n\t\t\t\t\t\t\tb.providerId = null;\n\t\t\t\t\t\t\tb.employeeId = null;\n\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t}\n\n\t\t} catch(e){}\n\n\t\tconsole.log(&#039;[Amelia] Employee reset&#039;);\n\t}\n\n    \/* ---------------------------------------------------------------\n       On load: wait for Vuex, then clear Amelia&#039;s default preselect\n    --------------------------------------------------------------- *\/\n    function waitForStoreAndReset() {\n        const interval = setInterval(() =&gt; {\n            const store = getStore();\n            if (!store) return;\n            clearInterval(interval);\n            setTimeout(() =&gt; {\n                if (ameliaReadyDone) return;\n                ameliaReadyDone = true;\n                try {\n                    store.commit(&#039;booking\/setEmployeeId&#039;, null);\n                    console.log(&#039;[Amelia] Cleared preselected employee via mutation&#039;);\n                } catch (e) {\n                    console.warn(&#039;[Amelia] Could not clear via mutation:&#039;, e);\n                }\n                sessionStorage.removeItem(&#039;amelia_emp_id&#039;);\n                sessionStorage.removeItem(&#039;amelia_emp_name&#039;);\n                selectedEmployeeId   = 0;\n                selectedEmployeeName = &#039;&#039;;\n            }, 600);\n        }, 100);\n    }\n\n    waitForStoreAndReset();\n\n    \/* ---------------------------------------------------------------\n       Normalize time to 24h HH:MM format for Vuex slot key matching\n    --------------------------------------------------------------- *\/\n    function normalizeTo24h(raw) {\n        if (!raw) return null;\n        const clean = raw.trim();\n\n        \/\/ Match 12-hour format: &quot;11:00 PM&quot;, &quot;9:00 AM&quot;, etc.\n        const match12 = clean.match(\/^(\\d{1,2}):(\\d{2})\\s*(AM|PM)$\/i);\n        if (match12) {\n            let h      = parseInt(match12[1]);\n            const m    = match12[2];\n            const ampm = match12[3].toUpperCase();\n            if (ampm === &#039;PM&#039; &amp;&amp; h !== 12) h += 12;\n            if (ampm === &#039;AM&#039; &amp;&amp; h === 12) h = 0;\n            return `${String(h).padStart(2, &#039;0&#039;)}:${m}`;\n        }\n\n        \/\/ Already 24h format like &quot;23:00&quot; or &quot;09:00&quot;\n        const match24 = clean.match(\/^(\\d{1,2}):(\\d{2})$\/);\n        if (match24) {\n            return `${String(parseInt(match24[1])).padStart(2, &#039;0&#039;)}:${match24[2]}`;\n        }\n\n        return clean;\n    }\n\n    \/* ---------------------------------------------------------------\n       Get available employeeIds for a date + time slot\n    --------------------------------------------------------------- *\/\n    function getAvailableEmployeeIdsForSlot(date, time) {\n        const store     = getStore();\n        const serviceId = getServiceId();\n        if (!store || !serviceId) return null;\n\n        try {\n            const slots = store.state.booking\n                ?.appointments?.[0]\n                ?.services?.[serviceId]\n                ?.slots;\n\n            if (!slots) return null;\n\n            const entries = slots[date]?.[time]\n                         || slots[date]?.[time + &#039;:00&#039;];\n\n            if (!entries || !entries.length) return null;\n\n            return entries.map(s =&gt; s.e).filter(Boolean);\n        } catch (e) {\n            return null;\n        }\n    }\n\n    \/* ---------------------------------------------------------------\n       Get employees filtered by service + slot availability\n    --------------------------------------------------------------- *\/\n\tfunction getEmployeesForSlot(date,time){\n\n\t\tconst store = getStore();\n\t\tconst serviceId = getServiceId();\n\n\t\tif(!store || !serviceId) return [];\n\n\t\tconst employees =\n\t\t\tstore.state.entities?.employees || [];\n\n\t\tconst slots =\n\t\t\tstore.state.booking\n\t\t\t?.appointments?.[0]\n\t\t\t?.services?.[serviceId]\n\t\t\t?.slots || {};\n\n\t\tlet employeeIds = new Set();\n\n\t\tif(slots[date]){\n\n\t\t\tObject.entries(slots[date]).forEach(([slotTime,slotData])=&gt;{\n\n\t\t\t\tif(!Array.isArray(slotData)) return;\n\n\t\t\t\tslotData.forEach(slot=&gt;{\n\n\t\t\t\t\tif(slot.e){\n\t\t\t\t\t\temployeeIds.add(slot.e);\n\t\t\t\t\t}\n\n\t\t\t\t});\n\n\t\t\t});\n\t\t}\n\n\t\treturn employees.filter(emp=&gt;{\n\n\t\t\tif(emp.status !== &#039;visible&#039;) return false;\n\n\t\t\tconst onService =\n\t\t\t\temp.serviceList?.some(\n\t\t\t\t\ts=&gt;s.id===serviceId\n\t\t\t\t);\n\n\t\t\tif(!onService) return false;\n\n\t\t\treturn employeeIds.has(emp.id);\n\n\t\t});\n\n\t}\n\n    \/* ---------------------------------------------------------------\n       Patch store ONLY at submission time\n    --------------------------------------------------------------- *\/\n    function patchStoreForSubmit(empId) {\n        const store = getStore();\n        if (!store || !empId) return;\n\n        try { store.commit(&#039;booking\/setEmployeeId&#039;, empId); } catch (e) {}\n\n        try {\n            const appt = store.state.booking?.appointment;\n            if (appt) { appt.providerId = empId; appt.employeeId = empId; }\n\n            const appointments = store.state.booking?.appointments;\n            if (Array.isArray(appointments)) {\n                appointments.forEach(a =&gt; {\n                    if (!a) return;\n                    a.providerId = empId;\n                    a.employeeId = empId;\n                    if (a.provider) a.provider.id = empId;\n                    if (Array.isArray(a.bookings)) {\n                        a.bookings.forEach(b =&gt; {\n                            if (!b) return;\n                            b.providerId = empId;\n                            b.employeeId = empId;\n                        });\n                    }\n                    if (a.services) {\n                        Object.values(a.services).forEach(svc =&gt; {\n                            if (!svc) return;\n                            svc.providerId = empId;\n                            if (Array.isArray(svc.list)) {\n                                svc.list.forEach(item =&gt; {\n                                    if (!item) return;\n                                    item.providerId = empId;\n                                    item.employeeId = empId;\n                                });\n                            }\n                        });\n                    }\n                });\n            }\n        } catch (e) {\n            console.warn(&#039;[Amelia] patchStoreForSubmit error:&#039;, e);\n        }\n\n        console.log(&#039;[Amelia] Store patched for submit with employee:&#039;, empId);\n    }\n\n    \/* ---------------------------------------------------------------\n       Fetch interceptor\n    --------------------------------------------------------------- *\/\n    function injectEmployeeIntoPayload(obj) {\n        if (!obj || typeof obj !== &#039;object&#039;) return;\n        for (const key in obj) {\n            if (key === &#039;providerId&#039; || key === &#039;employeeId&#039;) {\n                obj[key] = selectedEmployeeId || null;\n            } else if (typeof obj[key] === &#039;object&#039;) {\n                injectEmployeeIntoPayload(obj[key]);\n            }\n        }\n    }\n\n    const _fetch = window.fetch;\n    window.fetch = async function (input, init = {}) {\n        const url = typeof input === &#039;string&#039; ? input : (input?.url || &#039;&#039;);\n        if (url.includes(&#039;wpamelia_api&#039;) &amp;&amp; selectedEmployeeId) {\n            try {\n                if (init.body &amp;&amp; typeof init.body === &#039;string&#039;) {\n                    const body = JSON.parse(init.body);\n                    injectEmployeeIntoPayload(body);\n                    init.body = JSON.stringify(body);\n                    console.log(&#039;[Amelia] Patched fetch payload:&#039;, body);\n                }\n                if (init.body instanceof FormData) {\n                    init.body.set(&#039;providerId&#039;, selectedEmployeeId);\n                    init.body.set(&#039;employeeId&#039;, selectedEmployeeId);\n                }\n            } catch (e) {\n                console.warn(&#039;[Amelia] Fetch inject error:&#039;, e);\n            }\n        }\n        return _fetch.call(this, input, init);\n    };\n\n    \/* ---------------------------------------------------------------\n       XHR fallback\n    --------------------------------------------------------------- *\/\n    const _xhrOpen = XMLHttpRequest.prototype.open;\n    const _xhrSend = XMLHttpRequest.prototype.send;\n\n    XMLHttpRequest.prototype.open = function (method, url) {\n        this._ameliaUrl = url;\n        return _xhrOpen.apply(this, arguments);\n    };\n\n    XMLHttpRequest.prototype.send = function (body) {\n        if (selectedEmployeeId &amp;&amp; body &amp;&amp; typeof body === &#039;string&#039;) {\n            try {\n                const parsed = JSON.parse(body);\n                injectEmployeeIntoPayload(parsed);\n                console.log(&#039;[Amelia] Patched XHR payload:&#039;, parsed);\n                body = JSON.stringify(parsed);\n            } catch (e) {}\n        }\n        return _xhrSend.call(this, body);\n    };\n\n    \/* ---------------------------------------------------------------\n       Cart display patch\n    --------------------------------------------------------------- *\/\n    function patchCartDisplay() {\n        if (!selectedEmployeeId || !selectedEmployeeName) return;\n\n        document.querySelectorAll(&#039;.am-fs__main-content .am-cart__item-info&#039;).forEach(row =&gt; {\n            const label = row.querySelector(&#039;span:first-child, p:first-child&#039;);\n            const value = row.querySelector(&#039;span:last-child, p:last-child&#039;);\n            if (!label || !value) return;\n            const text = (label.innerText || &#039;&#039;).toLowerCase();\n            if (\n                text.includes(&#039;employee&#039;)  ||\n                text.includes(&#039;therapist&#039;) ||\n                text.includes(&#039;provider&#039;)  ||\n                text.includes(&#039;th\u00e9rapeute&#039;)\n            ) {\n                value.innerText = selectedEmployeeName;\n            }\n        });\n    }\n\n    \/* ---------------------------------------------------------------\n       DOM helpers\n    --------------------------------------------------------------- *\/\n    function getSelectedDate() {\n        const el = document.querySelector(&#039;.am-advsc__dayGridMonth-selected[data-date]&#039;);\n        return el ? el.getAttribute(&#039;data-date&#039;) : null;\n    }\n\n    function getSelectedTime() {\n        const el = document.querySelector(&#039;.am-advsc__slots-item__selected .am-advsc__slots-item__inner&#039;);\n        if (!el) return null;\n\n        \/\/ Extract the start time \u2014 &quot;11:00 AM - 12:00 PM&quot; \u2192 &quot;11:00 AM&quot;\n        const raw = el.innerText.trim().split(&#039;-&#039;)[0].trim();\n        return normalizeTo24h(raw);\n    }\n\n    \/* ---------------------------------------------------------------\n       Employee dropdown UI \u2014 with retry for async slot loading\n    --------------------------------------------------------------- *\/\n    function injectEmployeeUI(date, time, retries) {\n        if (retries === undefined) retries = 6;\n\n        const container = document.querySelector(&#039;.am-fs__main-content&#039;);\n        if (!container) return;\n\n        const employees = getEmployeesForSlot(date, time);\n\n        \/\/ Slots not populated yet \u2014 retry up to 6 times (~2.4s total)\n        if (employees.length === 0 &amp;&amp; retries &gt; 0) {\n            setTimeout(() =&gt; injectEmployeeUI(date, time, retries - 1), 400);\n            return;\n        }\n\n        document.getElementById(&#039;custom-employee-box&#039;)?.remove();\n\n        console.log(&#039;[Amelia] Employees for slot&#039;, date, time, employees.map(e =&gt; `${e.id}:${e.firstName}`));\n\n        const box = document.createElement(&#039;div&#039;);\n        box.id = &#039;custom-employee-box&#039;;\n        box.style.cssText = &#039;padding:15px;margin:15px 0;border:1px solid #ddd;border-radius:8px;background:#fff;&#039;;\n        box.innerHTML = `\n            &lt;label style=&quot;display:block;margin-bottom:8px;font-weight:600;&quot;&gt;Select Preferred Therapist&lt;\/label&gt;\n            &lt;select id=&quot;customEmployee&quot; style=&quot;width:100%;padding:10px;&quot;&gt;&lt;\/select&gt;\n            &lt;small id=&quot;custom-employee-status&quot; style=&quot;display:block;margin-top:6px;color:#888;&quot;&gt;&lt;\/small&gt;\n        `;\n        container.appendChild(box);\n\n        const select = document.getElementById(&#039;customEmployee&#039;);\n        select.innerHTML = &#039;&lt;option value=&quot;&quot;&gt;-- No Preference --&lt;\/option&gt;&#039;;\n\n        employees.forEach(emp =&gt; {\n            const opt       = document.createElement(&#039;option&#039;);\n            opt.value       = emp.id;\n            opt.textContent = `${emp.firstName} ${emp.lastName}`;\n            select.appendChild(opt);\n        });\n\n        \/\/ Restore previous selection if still valid for this slot\n        if (selectedEmployeeId) {\n            const stillValid = [...select.options].some(o =&gt; parseInt(o.value) === selectedEmployeeId);\n            if (stillValid) {\n                select.value = String(selectedEmployeeId);\n            } else {\n                selectedEmployeeId   = 0;\n                selectedEmployeeName = &#039;&#039;;\n                sessionStorage.removeItem(&#039;amelia_emp_id&#039;);\n                sessionStorage.removeItem(&#039;amelia_emp_name&#039;);\n            }\n        }\n\n        select.addEventListener(&#039;change&#039;, function () {\n            const newId   = parseInt(this.value) || 0;\n            const newName = newId ? this.options[this.selectedIndex].text : &#039;&#039;;\n\n            selectedEmployeeId   = newId;\n            selectedEmployeeName = newName;\n\n            if (newId) {\n                sessionStorage.setItem(&#039;amelia_emp_id&#039;,   newId);\n                sessionStorage.setItem(&#039;amelia_emp_name&#039;, newName);\n            } else {\n                sessionStorage.removeItem(&#039;amelia_emp_id&#039;);\n                sessionStorage.removeItem(&#039;amelia_emp_name&#039;);\n            }\n\n            document.getElementById(&#039;custom-employee-status&#039;).innerText =\n                newId ? `Selected: ${newName}` : &#039;&#039;;\n\t\t\t\n\t\t\tif(newId){\n\n\t\t\t\tconsole.log(\n\t\t\t\t\t&#039;[Amelia] Selected therapist:&#039;,\n\t\t\t\t\tnewName\n\t\t\t\t);\n\n\t\t\t}else{\n\n\t\t\t\tclearSelectedEmployee();\n\n\t\t\t}\n        });\n    }\n\n    \/* ---------------------------------------------------------------\n       Main state check\n    --------------------------------------------------------------- *\/\n\tfunction checkAmeliaState(){\n\n\t\tconst date = getSelectedDate();\n\t\tconst time = getSelectedTime();\n\n\t\t\/* User went back to Date\/Time page *\/\n\t\tif(!time){\n\n\t\t\tdocument\n\t\t\t\t.getElementById(\n\t\t\t\t\t&#039;custom-employee-box&#039;\n\t\t\t\t)\n\t\t\t\t?.remove();\n\n\t\t\tclearSelectedEmployee();\n\n\t\t\tlastKey=&#039;&#039;;\n\n\t\t\treturn;\n\t\t}\n\n\t\tif(!date) return;\n\n\t\tconst key = date;\n\n\t\tif(key===lastKey){\n\n\t\t\tpatchCartDisplay();\n\t\t\treturn;\n\t\t}\n\n\t\tlastKey=key;\n\n\t\tinjectEmployeeUI(\n\t\t\tdate,\n\t\t\ttime\n\t\t);\n\n\t}\n\n    \/* ---------------------------------------------------------------\n       Debounced observer\n    --------------------------------------------------------------- *\/\n    function triggerCheck() {\n        if (observerLocked) return;\n        observerLocked = true;\n        clearTimeout(slotTimer);\n        slotTimer = setTimeout(() =&gt; {\n            checkAmeliaState();\n            observerLocked = false;\n        }, 300);\n    }\n\n    const observer = new MutationObserver(() =&gt; triggerCheck());\n    observer.observe(document.body, { childList: true, subtree: true });\n\n    \/* ---------------------------------------------------------------\n       Amelia action hooks\n    --------------------------------------------------------------- *\/\n    window.ameliaActions = window.ameliaActions || {};\n    window.ameliaActions.SelectService  = () =&gt; setTimeout(triggerCheck, 800);\n    window.ameliaActions.SelectEmployee = () =&gt; setTimeout(triggerCheck, 800);\n    window.ameliaActions.SelectLocation = () =&gt; setTimeout(triggerCheck, 800);\n\n    \/* ---------------------------------------------------------------\n       Continue \/ cart button \u2014 patch store only at submission\n    --------------------------------------------------------------- *\/\n    document.addEventListener(&#039;click&#039;, function (e) {\n        const btn  = e.target.closest(&#039;button&#039;);\n        if (!btn) return;\n        const text = (btn.innerText || &#039;&#039;).toLowerCase();\n        if (\n            text.includes(&#039;continue&#039;) ||\n            text.includes(&#039;cart&#039;)     ||\n            text.includes(&#039;continuer&#039;)\n        ) {\n            if (selectedEmployeeId) {\n                patchStoreForSubmit(selectedEmployeeId);\n            }\n        }\n    }, true);\n\n    console.log(&#039;[Amelia] Employee injector v11 initialized&#039;);\n\n})();\n&lt;\/script&gt;\n&lt;?php\n});<\/code><\/pre><\/p>\n","protected":false},"excerpt":{"rendered":"","protected":false},"featured_media":0,"comment_status":"open","ping_status":"closed","template":"","meta":{"site-sidebar-layout":"default","site-content-layout":"","ast-site-content-layout":"default","site-content-style":"default","site-sidebar-style":"default","ast-global-header-display":"","ast-banner-title-visibility":"","ast-main-header-display":"","ast-hfb-above-header-display":"","ast-hfb-below-header-display":"","ast-hfb-mobile-header-display":"","site-post-title":"","ast-breadcrumbs-content":"","ast-featured-img":"","footer-sml-layout":"","ast-disable-related-posts":"","theme-transparent-header-meta":"default","adv-header-id-meta":"","stick-header-meta":"","header-above-stick-meta":"","header-main-stick-meta":"","header-below-stick-meta":"","astra-migrate-meta-layouts":"set","ast-page-background-enabled":"default","ast-page-background-meta":{"desktop":{"background-color":"var(--ast-global-color-4)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"tablet":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"mobile":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""}},"ast-content-background-meta":{"desktop":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"tablet":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"mobile":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""}}},"product_brand":[],"product_cat":[20],"product_tag":[47,48,49,50,46],"class_list":{"0":"post-7796","1":"product","2":"type-product","3":"status-publish","5":"product_cat-uncategorized","6":"product_tag-bon-cadeaux","7":"product_tag-cadeaux-de-noel","8":"product_tag-christmas-gift","9":"product_tag-gift-ideas","10":"product_tag-gift-voucher","11":"desktop-align-center","12":"tablet-align-left","13":"mobile-align-left","15":"first","16":"instock","17":"virtual","18":"purchasable","19":"product-type-simple"},"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v26.4 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Serenity Gift Vouchers -<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/serenitywellnessandspa.com\/it\/product\/buoni-regalo-serenita\/\" \/>\n<meta property=\"og:locale\" content=\"it_IT\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Serenity Gift Vouchers -\" \/>\n<meta property=\"og:url\" content=\"https:\/\/serenitywellnessandspa.com\/it\/product\/buoni-regalo-serenita\/\" \/>\n<meta property=\"article:modified_time\" content=\"2026-05-23T14:42:20+00:00\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Tempo di lettura stimato\" \/>\n\t<meta name=\"twitter:data1\" content=\"1 minuto\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"https:\/\/serenitywellnessandspa.com\/product\/serenity-gift-vouchers\/\",\"url\":\"https:\/\/serenitywellnessandspa.com\/product\/serenity-gift-vouchers\/\",\"name\":\"Serenity Gift Vouchers -\",\"isPartOf\":{\"@id\":\"https:\/\/serenitywellnessandspa.com\/#website\"},\"datePublished\":\"2025-12-09T17:54:17+00:00\",\"dateModified\":\"2026-05-23T14:42:20+00:00\",\"breadcrumb\":{\"@id\":\"https:\/\/serenitywellnessandspa.com\/product\/serenity-gift-vouchers\/#breadcrumb\"},\"inLanguage\":\"it-IT\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/serenitywellnessandspa.com\/product\/serenity-gift-vouchers\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/serenitywellnessandspa.com\/product\/serenity-gift-vouchers\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/serenitywellnessandspa.com\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Products\",\"item\":\"https:\/\/serenitywellnessandspa.com\/shop\/\"},{\"@type\":\"ListItem\",\"position\":3,\"name\":\"Serenity Gift Vouchers\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/serenitywellnessandspa.com\/#website\",\"url\":\"https:\/\/serenitywellnessandspa.com\/\",\"name\":\"\",\"description\":\"\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/serenitywellnessandspa.com\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"it-IT\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Buoni regalo Serenity -","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/serenitywellnessandspa.com\/it\/product\/buoni-regalo-serenita\/","og_locale":"it_IT","og_type":"article","og_title":"Serenity Gift Vouchers -","og_url":"https:\/\/serenitywellnessandspa.com\/it\/product\/buoni-regalo-serenita\/","article_modified_time":"2026-05-23T14:42:20+00:00","twitter_card":"summary_large_image","twitter_misc":{"Tempo di lettura stimato":"1 minuto"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/serenitywellnessandspa.com\/product\/serenity-gift-vouchers\/","url":"https:\/\/serenitywellnessandspa.com\/product\/serenity-gift-vouchers\/","name":"Buoni regalo Serenity -","isPartOf":{"@id":"https:\/\/serenitywellnessandspa.com\/#website"},"datePublished":"2025-12-09T17:54:17+00:00","dateModified":"2026-05-23T14:42:20+00:00","breadcrumb":{"@id":"https:\/\/serenitywellnessandspa.com\/product\/serenity-gift-vouchers\/#breadcrumb"},"inLanguage":"it-IT","potentialAction":[{"@type":"ReadAction","target":["https:\/\/serenitywellnessandspa.com\/product\/serenity-gift-vouchers\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/serenitywellnessandspa.com\/product\/serenity-gift-vouchers\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/serenitywellnessandspa.com\/"},{"@type":"ListItem","position":2,"name":"Products","item":"https:\/\/serenitywellnessandspa.com\/shop\/"},{"@type":"ListItem","position":3,"name":"Serenity Gift Vouchers"}]},{"@type":"WebSite","@id":"https:\/\/serenitywellnessandspa.com\/#website","url":"https:\/\/serenitywellnessandspa.com\/","name":"","description":"","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/serenitywellnessandspa.com\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"it-IT"}]}},"_links":{"self":[{"href":"https:\/\/serenitywellnessandspa.com\/it\/wp-json\/wp\/v2\/product\/7796","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/serenitywellnessandspa.com\/it\/wp-json\/wp\/v2\/product"}],"about":[{"href":"https:\/\/serenitywellnessandspa.com\/it\/wp-json\/wp\/v2\/types\/product"}],"replies":[{"embeddable":true,"href":"https:\/\/serenitywellnessandspa.com\/it\/wp-json\/wp\/v2\/comments?post=7796"}],"wp:attachment":[{"href":"https:\/\/serenitywellnessandspa.com\/it\/wp-json\/wp\/v2\/media?parent=7796"}],"wp:term":[{"taxonomy":"product_brand","embeddable":true,"href":"https:\/\/serenitywellnessandspa.com\/it\/wp-json\/wp\/v2\/product_brand?post=7796"},{"taxonomy":"product_cat","embeddable":true,"href":"https:\/\/serenitywellnessandspa.com\/it\/wp-json\/wp\/v2\/product_cat?post=7796"},{"taxonomy":"product_tag","embeddable":true,"href":"https:\/\/serenitywellnessandspa.com\/it\/wp-json\/wp\/v2\/product_tag?post=7796"}],"curies":[{"name":"parola chiave","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}