// source --> https://mysteriusescape.fr/wp-content/plugins/widget-google-reviews/assets/6.9.8/js/public-main.js 
var rpi=rpi||{};
rpi.Time={getFormatTime:function(a,e,c){a=new Date(this._ms(a));var m=c||"en";c=function(p){return 10>p?"0"+p:""+p};var g=a.getHours(),h=((new Intl.DateTimeFormat(m,{day:"numeric",month:"short"})).formatToParts(a).find(function(p){return"month"===p.type})||{}).value;m=(new Intl.DateTimeFormat(m,{day:"numeric",month:"long"})).formatToParts(a).find(function(p){return"month"===p.type}).value;var n=a.getFullYear(),l=String(n).slice(-2),f={yyyy:n,Y:n,yy:l,y:l,MMMM:m,MMM:h,M:h,MM:c(a.getMonth()+1),m:c(a.getMonth()+
1),dd:c(a.getDate()),d:c(a.getDate()),HH:c(g),H:g,hh:c(g%12||12),h:g%12||12,mm:c(a.getMinutes()),i:c(a.getMinutes()),ss:c(a.getSeconds()),s:c(a.getSeconds()),a:12<=g?"pm":"am",A:12<=g?"PM":"AM"};return e.replace(/(MMMM|MMM|yyyy|HH|hh|MM|mm|dd|ss|yy|H|h|M|m|d|Y|y|i|s|a|A)/g,p=>null!=f[p]?f[p]:p)},getTimeAgo:function(a,e){a=(this._ms(a)-Date.now())/1E3;var c=Math.abs(a);e=new Intl.RelativeTimeFormat(e||"en",{numeric:"auto"});return 60>c?e.format(Math.round(a),"second"):3600>c?e.format(Math.round(a/
60),"minute"):86400>c?e.format(Math.round(a/3600),"hour"):2592E3>c?e.format(Math.round(a/86400),"day"):31536E3>c?e.format(Math.round(a/2592E3),"month"):e.format(Math.round(a/31536E3),"year")},_ms:function(a){a=parseInt(a,10);return 1E10>a?1E3*a:a}};rpi=rpi||{};
rpi.Utils={__:function(a,e){return e&&e[a]||a},isVisible:function(a){let e=window.getComputedStyle(a);return!!(a.offsetWidth||a.offsetHeight||a.getClientRects().length)&&"hidden"!==e.visibility&&"none"!==e.display},isInViewport:function(a,e=0){a=a.getBoundingClientRect();return a.top<window.innerHeight*(1+e)&&a.bottom>-window.innerHeight*e&&a.left<window.innerWidth*(1+e)&&a.right>-window.innerWidth*e},isRTL:function(){return"rtl"==(window.getComputedStyle?window.getComputedStyle(document.body,null).getPropertyValue("direction"):
document.body.currentStyle.direction)},getParent:function(a,e="rplg"){e=Array.isArray(e)?e:[e];return a?a.closest("."+e.join(",.")):null},lang:function(){var a=navigator;return(a.language||a.systemLanguage||a.userLanguage||"en").substr(0,2).toLowerCase()},popup:function(a,e,c){var m=document.documentElement;a=window.open(a,"","scrollbars=yes, width="+e+", height="+c+", top="+((window.innerHeight?window.innerHeight:m.clientHeight?m.clientHeight:screen.height)/2-c/2+(void 0!=window.screenTop?window.screenTop:
window.screenY))+", left="+((window.innerWidth?window.innerWidth:m.clientWidth?m.clientWidth:screen.width)/2-e/2+(void 0!=window.screenLeft?window.screenLeft:window.screenX)));window.focus&&a.focus();return a},ajax:function(a,e,c,m){const g=new XMLHttpRequest;g.open(e,a,!0);g.setRequestHeader("Content-Type","application/json");g.onreadystatechange=function(){if((g.readyState===XMLHttpRequest.DONE||g.readyState===g.DONE)&&200===g.status){const h=JSON.parse(g.responseText);"function"===typeof m?m(h):
"function"===typeof c&&c(h)}};g.send(c&&"function"!==typeof c?JSON.stringify(c):null)},anchor:function(a,e,c,m,g){const h=[];c.open_link&&h.push("noopener");c.nofollow_link&&h.push("nofollow");return'<a href="'+a+'"'+(m?' class="'+m+'"':"")+(c.open_link?' target="_blank"':"")+(h.length?' rel="'+h.join(" ")+'"':"")+(g?' aria-label="'+g+'"':"")+">"+e+"</a>"},rm:function(a){a&&a.parentNode&&a.parentNode.removeChild(a)},capit:function(a){return a.charAt(0).toUpperCase()+a.slice(1)},url:function(a){try{return(new URL(a,
window.location.origin)).href}catch(e){return""}},clear:function(){this.rm(document.getElementById("rpi-style"));if(rpi.Instances)for(;rpi.Instances.length;)rpi.Instances.pop().clear()}};rpi=rpi||{};
rpi.Column=function(a,e,c){const m=a.getAttribute("data-id"),g=new RegExp(c.col+"-[xsml]+"),h=new RegExp((m?'\\[data-id="'+m+'"\\]\\s+':"")+"\\."+c.card+"\\{--col:\\d+!important;--gap:\\d+!important\\}"),n=a.getElementsByClassName(c.cnt)[0];var l=null;return l={init:function(f,p){rpi.Utils.isVisible(n)?(f&&f(),l.resize(),window.addEventListener("resize",l.resize),p&&p(),rpi.Instances=rpi.Instances||[],rpi.Instances.push(l)):setTimeout(l.init,300)},resize:function(){let f=l.getSize();n.className=n.className.replace(g,
c.col+"-"+f);if(e.breakpoints){let p=n.offsetWidth,r=e.breakpoints.split(",");r.sort(l.brsort);for(let t=0;t<r.length;t++){let v=r[t].split(":");if(p<parseInt(v[0])){l.setCol(v[1]);break}}}return f},getSize:function(){let f=n.offsetWidth;return 510>f?"xs":750>f?"x":1050>f?"s":1450>f?"m":1800>f?"l":"xl"},setCol:function(f){const p=this.getStyle();f=(m?'[data-id="'+m+'"] ':"")+"."+c.card+"{--col:"+f+"!important;--gap:"+(f-1)+"!important}";h.test(p.innerHTML)?p.innerHTML=p.innerHTML.replace(h,f):p.innerHTML+=
f},getCol:function(){let f=this.getStyle().innerHTML.match(/--col:\s*(\d+)/);return f&&1<f.length?f[1]:!1},getStyle:function(){let f=document.getElementById("rpi-style");f||(f=document.createElement("style"),f.id="rpi-style",document.head.appendChild(f));return f},setBreakpoints:function(f){e.breakpoints=f},brsort:function(f,p){return parseInt(f.split(":")[0])>parseInt(p.split(":")[0])?1:-1},clear:function(){window.removeEventListener("resize",l.resize)}}};rpi=rpi||{};rpi.AVA="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7";
rpi.Common=function(a,e,c){let m=null;const g=rpi.Utils.lang();return m={init(){let h=a.getElementsByClassName(c.time),n=a.getElementsByClassName(c.text);for(const l of h)m.setTime(l);for(const l of n)m.setText(l)},initOnce(h){let n=h.getElementsByClassName(c.time)[0];h=h.getElementsByClassName(c.text)[0];m.setTime(n);m.setText(h)},setText(h){if(h&&h.textContent){var n=m.trimtext(h.textContent);h.textContent=n[0];n[1]&&(h.appendChild(rpi.el({tag:"span",cl:"rpi-s",text:"... "})),h.appendChild(rpi.el({tag:"span",
cl:c.readmore,text:rpi.Utils.__("read more",e.trans),data:{hidden:n[1]}})),h.lastChild.onclick=m.opentext)}},trimtext(h){const n=parseInt(e.text_size,10);if(!h||!n||h.length<=n)return[h||"",""];h=Array.from(h);let l=h.slice(0,n).join("").lastIndexOf(" ");l=-1===l?n:l;return[h.slice(0,l).join("").trimEnd(),h.slice(l).join("")]},opentext(){let h=this.parentNode,n=this.dataset.hidden||"";rpi.Utils.rm(this.previousElementSibling);rpi.Utils.rm(this);h.appendChild(document.createTextNode(n))},setTime(h){h&&
(h.textContent=m.time(h.dataset.time))},time(h){return e.time_format?rpi.Time.getFormatTime(h,e.time_format,g):rpi.Time.getTimeAgo(h,g)}}};
rpi.el=function(a={},...e){const c=document.createElement("string"===typeof a?a:a.tag||"div");"string"!==typeof a&&(a.id&&(c.id=a.id),a.cl&&c.classList.add(...[].concat(a.cl).join(" ").split(/\s+/).filter(Boolean)),null!=a.text&&(c.textContent=a.text),a.data&&Object.assign(c.dataset,Object.fromEntries(Object.entries(a.data).filter(([,m])=>void 0!==m&&null!==m))),a.style&&(c.style.cssText=a.style),a.atts&&Object.keys(a.atts).forEach(m=>{const g=a.atts[m];null!==g&&void 0!==g&&!1!==g&&c.setAttribute(m,
g)}),a.html&&(c.innerHTML=a.html),e=a.children?[].concat(a.children).concat(e):e);e.flat().forEach(m=>{m&&c.appendChild(m instanceof Node?m:document.createTextNode(String(m)))});return c};rpi=rpi||{};
rpi.Media=function(a,e={},{root:c="rpi",card:m="rpi-card"}={}){let g,h=null,n=null;return n={init:function(){h=a.getElementsByClassName("rpi-thumb");for(let l=0;l<h.length;l++)h[l].setAttribute("data-idx",l),function(f,p){f.onclick=function(){n.show(f,p);return!1}}(h[l],l)},thumbs:function(l){if(Array.isArray(l)){var f=[];for(const p of l)l=document.createElement("img"),l.className="rpi-thumb rpi-clickable",l.src=p.thumbnailUrl,l.alt=rpi.Utils.__("Photo from customer review",e.trans),l.loading="lazy",
f.push(l);return f}},clicks:function(l){l=l.getElementsByClassName("rpi-thumb");for(let f=0;f<l.length;f++)(function(p,r){p.onclick=function(){let t=parseInt(p.getAttribute("data-idx"));n.show(h[t],t);return!1}})(l[f],f)},show:function(l,f){if(!(0>f||f>=h.length)){var p=l.src.replace(/=s[0-9]{1,3}/g,"=s500");l=(l=rpi.Utils.getParent(l,[m,"rpi-review"]))?l.outerHTML:"";if(g){let r=g.querySelector(".rpi-lightbox-media img"),t=g.querySelector(".rpi-lightbox-review"),v=g.querySelector(".rpi-lightbox-prev"),
d=g.querySelector(".rpi-lightbox-next");r.src=p;t.innerHTML!==l&&(t.innerHTML=l,n.clicks(t));v.onclick=function(u){n.show(h[f-1],f-1)};d.onclick=function(u){n.show(h[f+1],f+1)}}else g=document.createElement("div"),g.className="rpi-lightbox",g.innerHTML='<div class="rpi-x"></div><div class="rpi-lightbox-inner"><div class="rpi-lightbox-xxx"><div class="rpi-lightbox-content"><div class="rpi-lightbox-media"><div class="rpi-lightbox-btn rpi-lightbox-prev"></div><img src="'+p+'" alt=""><div class="rpi-lightbox-btn rpi-lightbox-next"></div></div><div class="'+
c+' rpi-lightbox-review">'+l+"</div></div></div></div>",p=g.querySelector(".rpi-x"),l=g.querySelector(".rpi-lightbox-prev"),next=g.querySelector(".rpi-lightbox-next"),p.onclick=function(){g.style.display="none"},g.onclick=function(r){g==r.target&&(g.style.display="none")},l.onclick=function(r){n.show(h[f-1],f-1)},next.onclick=function(r){n.show(h[f+1],f+1)},n.clicks(g),document.body.appendChild(g);g.style.display="flex"}}}};rpi=rpi||{};
rpi.Slider=function(a,e,c,m){a.getAttribute("data-id");const g=a.getElementsByClassName(c.cnt)[0],h=a.getElementsByClassName(c.content)[0],n=h?h.getElementsByClassName(c.cards)[0]:null,l=h?h.getElementsByClassName(c.dotsWrap)[0]:null,f=h?h.getElementsByClassName(c.dots)[0]:null,p=n?parseInt(n.getAttribute("data-count")):0,{autoplay:r=!0,speed:t=5,mousestop:v=!0}=e;var d=null,u=h?h.getElementsByClassName(c.card):null,E="",F="",A=null,y=null,x=null,B=null,C=!1,z=!1,D=0,G=0;return d={init:function(b,
k){rpi.Utils.isVisible(g)?(b&&b(),d.resize(),d.actions(),u.length&&d.swipeAutoStart(),k&&k(),rpi.Instances=rpi.Instances||[],rpi.Instances.push(d)):setTimeout(d.init,300)},resize:function(b){let k=m.column.resize(),q=m.column.getCol();b&&n.scrollLeft!=b*d.reviewWidth()&&n.scrollTo(u[b].offsetLeft,0);!u.length||E==k&&F==q||(d.hasDots()&&(d.dotsInit(),d.dotSwipe(b,!0)),E=k,F=q)},actions:function(){v&&d.addMouseEvents();window.addEventListener("resize",d.resizeListener);n&&(n.addEventListener("scroll",
d.scrollListener,!1),e.wheelscroll&&h.addEventListener("wheel",d.wheelListener,!1));var b=g.getElementsByClassName(c.btnPrev)[0];b&&(b.onclick=function(k){k.preventDefault();k.stopPropagation();d.btnClick(-1)});if(b=g.getElementsByClassName(c.btnNext)[0])b.onclick=function(k){k.preventDefault();k.stopPropagation();d.btnClick(1)}},resizeListener:function(){var b=G;clearTimeout(A);A=setTimeout(d.resize,150,b)},scrollListener:function(){clearTimeout(y);clearTimeout(x);x=setTimeout(d.scrollEnd,150)},
wheelListener:function(b){var k=b.target;if((k=-1<k.className.indexOf(c.text)?k:-1<k.parentNode.className.indexOf(c.text)?k.parentNode:null)&&k.scrollHeight>k.clientHeight)return!0;b.preventDefault();D++;clearTimeout(B);B=setTimeout(d.wheelEnd,150,b)},addMouseEvents:function(){g.addEventListener("mouseover",d.mouseOver,!1);g.addEventListener("mouseleave",d.mouseLeave,!1)},delMouseEvents:function(){g.removeEventListener("mouseover",d.mouseOver);g.removeEventListener("mouseleave",d.mouseLeave)},mouseOver:function(){C=
1;d.swipeAutoStop()},mouseLeave:function(){C=0;d.swipeAutoStart()},btnClick:function(b){d.swipeManual(b*d.swipePerBtn())},wheelEnd:function(b){d.swipeManual(Math.sign(b.wheelDelta)*D*d.swipeStep());D=0},scrollEnd:function(){G=d.reviewsIdx();z?z=!1:d.loadNextReviews();(!v||C)&&v||(!e.clickstop||z)&&e.clickstop||d.swipeAutoStart();d.hasDots()&&d.dotSwipe(void 0,!0)},loadNextReviews:function(b){b=b?d.reviewsIdx()+parseInt(b):d.hasDots()?(b=f.getElementsByClassName("active")[0])?parseInt(b.getAttribute("data-index"))*
d.swipePerDot():d.reviewsIdx():d.reviewsIdx();b=d.getAjaxSize(b);0<b&&m.view.loadNextReviews(b)},getAjaxSize:function(b){let k=0;const q=parseInt(n.getAttribute("data-offset")),w=parseInt(e.pagination);if(p>q){let H=b-q;Math.abs(H)<3*d.swipePerDot()?k=w:H&&(k=Math.ceil(b/w)*w-q)}b=q+k-p;return 0<b?k-b:k},dotsInit:function(){if(f){var b=Math.round(p/d.swipePerDot());f.innerHTML="";for(let k=0;k<b;k++){let q=document.createElement("button");q.className=c.dot;q.setAttribute("data-index",k);q.setAttribute("title",
k);q.setAttribute("aria-label","Go to page "+k);q.onclick=d.dotClick;f.appendChild(q)}d.dotsPadding()}},dotClick:function(b){b.preventDefault();b.stopPropagation();b=parseInt(this.getAttribute("data-index"));var k=f.getElementsByClassName("active")[0];k=parseInt(k.getAttribute("data-index"));d.swipeManual(Math.abs(b-k)*d.swipePerDot()*Math.sign(b-k))},dotsPadding:function(){let b=l.getBoundingClientRect().height;g.style.paddingBottom=b+"px"},dotSwipe:function(b,k){b=Math.round((void 0!==b?b:d.reviewsIdx())/
d.swipePerDot());b=0>b?0:b>=f.childNodes.length?f.childNodes.length-1:b;b=f.querySelector("."+c.dot+'[data-index="'+b+'"]');let q=f.getElementsByClassName("active")[0];d.dotActivate(q,b);d.dotScroll(b,k)},dotScroll:function(b,k){let q=Math.round(f.scrollWidth/f.childNodes.length),w=Math.floor(Math.round(f.offsetWidth/q)/2);k?f.scrollTo(b.offsetLeft-w*q,0):f.scrollTo({left:b.offsetLeft-w*q,behavior:"smooth"})},dotActivate:function(b,k){b&&(b.classList.remove("active"),b.classList.remove("s1"),b.previousSibling&&
(b.previousSibling.classList.remove("s2"),b.previousSibling.previousSibling&&b.previousSibling.previousSibling.classList.remove("s3")),b.nextSibling&&(b.nextSibling.classList.remove("s2"),b.nextSibling.nextSibling&&b.nextSibling.nextSibling.classList.remove("s3")));k&&(k.classList.add("active"),k.classList.add("s1"),k.previousSibling&&(k.previousSibling.classList.add("s2"),k.previousSibling.previousSibling&&k.previousSibling.previousSibling.classList.add("s3")),k.nextSibling&&(k.nextSibling.classList.add("s2"),
k.nextSibling.nextSibling&&k.nextSibling.nextSibling.classList.add("s3")))},swipeManual:function(b){z=!0;d.loadNextReviews(b);d.scroll(b);e.clickstop&&(d.swipeAutoStop(),d.delMouseEvents())},swipeAuto:function(){if(rpi.Utils.isInViewport(g))if(d.isScrollEnd())d.scroll(-(p-d.reviewsPerView()));else{let b=d.swipeStep()<d.reviewsAhead()?d.swipeStep():d.reviewsAhead();d.scroll(b)}d.swipeAutoStart()},scroll:function(b){b=d.reviewsIdx()+parseInt(b);let k=rpi.Utils.isRTL()?b+d.reviewsPerView()-1:b;k=0>k?
0:k>=u.length?u.length-1:k;-1<k&&k<u.length&&(n.scrollTo({left:u[k].offsetLeft,behavior:"smooth"}),d.hasDots()&&d.dotSwipe(b))},swipeAutoStart:function(){r&&(y=setTimeout(d.swipeAuto,1E3*parseInt(t)))},swipeAutoStop:function(){clearTimeout(y);x&&setTimeout(function(){clearTimeout(x)},100)},isScrollEnd:function(){var b=n.querySelector("."+c.card+":last-child"),k=b.getBoundingClientRect();b=b.parentNode.getBoundingClientRect();return(2>Math.abs(b.left-k.left)||b.left<=k.left)&&k.left<b.right&&(2>Math.abs(b.right-
k.right)||b.right>=k.right)&&k.right>b.left},swipeStep:function(){return e.swipe_step||d.reviewsPerView()},swipePerBtn:function(){return e.swipe_per_btn||d.reviewsPerView()},swipePerDot:function(){return e.swipe_per_dot||d.reviewsPerView()},reviewWidth:function(){return Math.round(n.scrollWidth/u.length)},reviewHeight:function(){return u[0].offsetHeight},reviewsPerView:function(){return Math.round(n.offsetWidth/d.reviewWidth())},reviewsIdx:function(){let b=rpi.Utils.isRTL()?-n.scrollLeft:n.scrollLeft;
return Math.round(b/d.reviewWidth())},reviewsAhead:function(){return u.length-(d.reviewsIdx()+d.reviewsPerView())},hasDots:function(){return f&&!e.hide_dots&&0<d.swipePerDot()},setBreakpoints:function(b){m.column.setBreakpoints(b);d.resize()},clear:function(){clearTimeout(A);clearTimeout(y);clearTimeout(x);clearTimeout(B);window.removeEventListener("resize",d.resizeListener);n.removeEventListener("scroll",d.scrollListener);h.removeEventListener("wheel",d.wheelListener)}}};
function rplg_badge_init(a,e,c){var m=a.querySelector(".wp-"+e+"-badge"),g=a.querySelector(".wp-"+e+"-form");m&&g&&(a=document.createElement("div"),a.className=c+" wpac",-1<m.className.indexOf("-fixed")&&a.appendChild(m),a.appendChild(g),document.body.appendChild(a),m.onclick=function(){g.style.display="block"})}
function rplg_next_reviews(a,e){var c=this.parentNode,m="."+a+"-review."+a+"-hide";reviews=c.querySelectorAll(m);for(var g=0;g<e&&g<reviews.length;g++)reviews[g]&&(reviews[g].className=reviews[g].className.replace(a+"-hide"," "));reviews=c.querySelectorAll(m);1>reviews.length&&c.removeChild(this);return!1}function rplg_leave_review_window(){rpi.Utils.popup(this.getAttribute("href"),620,500);return!1}
function grw_init(a,e){a=rpi.Utils.getParent(a,"wp-gr");if("true"!=a.getAttribute("data-exec")){a.setAttribute("data-exec","true");var c=JSON.parse(a.getAttribute("data-options"));rpi.Common(a,c,{time:"wp-google-time",text:"wp-google-text",readmore:"wp-more-toggle"}).init();rpi.Media(a,{},{root:"wp-gr",card:"grw-review"}).init();!a.getElementsByClassName("grw-review")[0]||"slider"!=e&&"grid"!=e||(e=a.getElementsByClassName("grw-row")[0],e=JSON.parse(e.getAttribute("data-options")),c=rpi.Column(a,
e,{cnt:"grw-row",col:"grw-row",card:"grw-review"}),rpi.Slider(a,e,{cnt:"grw-row",col:"grw-row",content:"grw-content",cards:"grw-reviews",card:"grw-review",text:"wp-google-text",btnPrev:"grw-prev",btnNext:"grw-next",dotsWrap:"rpi-dots-wrap",dots:"rpi-dots",dot:"rpi-dot"},{column:c}).init())}}function grw_boot(){const a=document.querySelectorAll('.wp-gr[data-exec="false"]');for(let c=0;c<a.length;c++){var e=a[c];grw_init(e,e.getAttribute("data-layout"))}}
document.addEventListener("DOMContentLoaded",grw_boot);
// source --> https://mysteriusescape.fr/wp-content/plugins/translatepress-multilingual/assets/js/trp-frontend-language-switcher.js?ver=3.2.3 
class BaseSwitcher {
    constructor(rootEl) {
        this.root = rootEl;
        this.list = rootEl?.querySelector('.trp-switcher-dropdown-list') || null;
        this.isOpen = false;
        this._pendingFocusOnOpen = false;
        if (!this.root || !this.list) return;

        if (!this.list.id) {
            this.list.id = `trp-list-${Math.random().toString(36).slice(2, 9)}`;
        }

        // Single transitionend handler to drop .is-transitioning and finalize hidden/inert
        this._onTe = (e) => {
            if (e.target !== this.list || e.propertyName !== 'max-height') return;

            this.root.classList.remove('is-transitioning');

            if (!this.isOpen) {
                this.list.hidden = true;
                this.list.setAttribute('inert', '');
            } else if (this._pendingFocusOnOpen) {
                this._pendingFocusOnOpen = false;
                const first = this.list.querySelector(
                    '[role="option"], a, button, [tabindex]:not([tabindex="-1"])'
                );
                first?.focus?.({ preventScroll: true });
            }
        };
        this.list.addEventListener('transitionend', this._onTe);

        this.collapse();
        this.setAutoWidth();
        this.bindKeyboard();
    }

    /**
     * Returns true if the list has a non-zero transition duration (for any property).
     * We use this to decide whether to rely on `transitionend` or fall back to sync behavior.
     */
    _hasAnimatedTransition() {
        if (!this.list) return false;

        const cs = getComputedStyle(this.list);
        const durationsRaw = cs.transitionDuration || '';

        if (!durationsRaw) return false;

        const durations = durationsRaw
            .split(',')
            .map(str => parseFloat(str) || 0);

        return durations.some(d => d > 0);
    }

    collapse() {
        this.list.hidden = true;
        this.list.setAttribute('inert', '');
        this.setExpanded(false);
        this.root.classList.remove('is-transitioning');
    }

    /**
     * If width is set to auto, fix it to the calculated width + 20px
     * We do this in order to avoid width shift on hover
     * */
    setAutoWidth() {
        const bonusWidth = 10;

        const cs = getComputedStyle(this.root);
        const declaredWidth = cs.getPropertyValue('--switcher-width').trim();

        if (declaredWidth === 'auto' && this.root.querySelector('.trp-language-item-name')) { // In case trp-language-item-name is not present, we are in flags only mode - so no auto width sizing is needed
            const initialWidth = this.root.getBoundingClientRect().width;

            this.root.style.setProperty('--switcher-width', (initialWidth + bonusWidth) + 'px');
        }
    }

    setExpanded(open) {
        const trigger = this.root.querySelector('.trp-language-item__current[role="button"]');
        const val = String( !!open );
        trigger?.setAttribute('aria-expanded', val);
        this.root.classList.toggle('is-open', !!open);
    }

    setOpen( open, { source = null } = {} ) {
        if ( !this.root || !this.list || open === this.isOpen ) return;

        const prefersReduced = window.matchMedia?.('(prefers-reduced-motion: reduce)')?.matches;
        const hasTransition  = !prefersReduced && this._hasAnimatedTransition();

        this.isOpen = open;

        // No transitions (0s duration) OR reduced motion: do everything synchronously,
        if ( !hasTransition ) {
            if ( open ) {
                this.list.hidden = false;
                this.list.removeAttribute( 'inert' );
                this.setExpanded( true );

                this._pendingFocusOnOpen = ( source?.type === 'keydown' );
                if ( this._pendingFocusOnOpen ) {
                    this._pendingFocusOnOpen = false;
                    const first = this.list.querySelector(
                        '[role="option"], a, button, [tabindex]:not([tabindex="-1"])'
                    );
                    first?.focus?.({ preventScroll: true });
                }
            } else {
                this.setExpanded( false );
                this.list.hidden = true;
                this.list.setAttribute( 'inert', '' );
                this._pendingFocusOnOpen = false;
            }
            return;
        }

        // Animated path: rely on transitionend to remove .is-transitioning
        if ( open ) {
            // Must be visible for CSS transition to run
            this.list.hidden = false;
            this.list.removeAttribute( 'inert' );

            this._pendingFocusOnOpen = ( source?.type === 'keydown' );

            this.root.classList.add( 'is-transitioning' );
            // Next frame so browser registers pre-open (max-height: 0) state
            requestAnimationFrame( () => this.setExpanded( true ) );
        } else {
            this.root.classList.add( 'is-transitioning' );
            this.setExpanded( false );
        }
    }

    bindKeyboard() {
        const trigger = this.root.querySelector('.trp-language-item__current[role="button"]');
        if ( !trigger ) return;

        trigger.addEventListener('keydown', (e) => {
            const inList = !!e.target.closest?.('.trp-switcher-dropdown-list');

            if ( e.key === 'Enter' || e.key === ' ' ) {
                e.preventDefault();
                this.setOpen(!this.isOpen, { source: e });
                return;
            }

            if ( e.key === 'ArrowDown' && !this.isOpen ) {
                e.preventDefault();
                this.setOpen(true, { source: e });
            }

            if ( e.key === 'Escape' ) {
                this.setOpen(false, { source: e });
                trigger.focus?.();
            }
        });
    }
}

class ShortcodeSwitcher extends BaseSwitcher {
    constructor(wrapper) {
        const overlay =
                  wrapper.querySelector('.trp-language-switcher.trp-shortcode-overlay')
                  || [...wrapper.querySelectorAll('.trp-language-switcher')]
                      .find(el => el.classList.contains('trp-shortcode-overlay'));

        // Overlay must be interactable; ensure no accidental hidden/inert from server
        overlay.hidden = false;
        overlay.removeAttribute('hidden');
        overlay.removeAttribute('inert');
        if ('inert' in overlay) overlay.inert = false;

        super(overlay);

        if (!this.root || !this.list) return;

        const control = this.root.querySelector('.trp-language-item__current[role="button"]');
        if (control && this.list && !control.hasAttribute('aria-controls')) {
            control.setAttribute('aria-controls', this.list.id);
        }

        const isClickMode =
                  this.root.classList.contains('trp-open-on-click') ||
                  wrapper.dataset.openMode === 'click' ||
                  wrapper.classList.contains('trp-open-on-click');

        if (isClickMode) {
            // Click anywhere on overlay EXCEPT inside the list
            this.root.addEventListener('click', (e) => {
                const inList = e.target.closest('.trp-switcher-dropdown-list');
                if (!inList) {
                    e.preventDefault();
                    e.stopPropagation();
                    this.setOpen(!this.isOpen, { source: e });
                }
            }, true);

            // Outside click closes
            this.onDocClick = (evt) => {
                if (!wrapper.contains(evt.target)) this.setOpen(false, { source: evt });
            };
            document.addEventListener('click', this.onDocClick, true);

            // Focus leaving wrapper closes
            wrapper.addEventListener('focusout', () => {
                setTimeout(() => {
                    if (!wrapper.contains(document.activeElement)) {
                        this.setOpen(false, { source: 'keyboard' });
                    }
                }, 0);
            });
        } else {
            // Hover mode on overlay
            this.root.addEventListener('mouseenter', (e) => this.setOpen(true,  { source: e }));
            this.root.addEventListener('mouseleave', (e) => this.setOpen(false, { source: e }));
        }
    }
}

class FloaterSwitcher extends BaseSwitcher {
    constructor(el) {
        super(el);

        el.addEventListener('mouseenter', (e) => this.setOpen(true,  { source: e }));
        el.addEventListener('mouseleave', (e) => this.setOpen(false, { source: e }));

        this.onDocClick = (evt) => { if (!el.contains(evt.target)) this.setOpen(false, { source: evt }); };
        document.addEventListener('click', this.onDocClick, true);
    }
}

document.addEventListener('DOMContentLoaded', () => {
    // Front-end or classic admin
    initLanguageSwitchers(document);

    // If no wrapper and we are in Gutenberg, watch for async SSR insert
    if (
        inGutenberg() &&
        !getEditorDoc().querySelector(WRAPPER)
    ) {
        observeWrapperUntilFound();
    }

    if ( !inGutenberg() )
        observeShortcodeSwitcher();
});

/** For shortcode switcher
 *  Mark the shortcodes that were initialized
 * */
const TRP_BOUND = new WeakSet();
const mark = (el) => TRP_BOUND.add(el);
const isMarked = (el) => TRP_BOUND.has(el);

const WRAPPER = '.trp-shortcode-switcher__wrapper';
const OVERLAY = '.trp-language-switcher:not(.trp-opposite-button)';

// Helpers
function inGutenberg() {
    return document.body?.classList?.contains('block-editor-page')
        || !!(window.wp?.data?.select?.('core/block-editor'));
}

// If editor uses an iframe canvas, work inside it
function getEditorDoc() {
    const ifr = document.querySelector('iframe[name="editor-canvas"], .editor-canvas__iframe');

    return (ifr && ifr.contentDocument) ? ifr.contentDocument : document;
}

function initLanguageSwitchers(root = document) {
    const floater = root.querySelector(
        '.trp-language-switcher.trp-ls-dropdown:not(.trp-shortcode-switcher):not(.trp-opposite-language)'
    );

    if (floater)
        new FloaterSwitcher(floater);

    root.querySelectorAll(WRAPPER)
        .forEach(wrapper => {
            const overlay = wrapper.querySelector('.trp-language-switcher:not(.trp-opposite-button)');

            if (overlay && !isMarked(overlay)) {
                mark(overlay);
                new ShortcodeSwitcher(wrapper);
            }
        });
}

/**
 * Observes the document for dynamically inserted shortcode switchers and initializes them automatically when detected.
 */
function observeShortcodeSwitcher() {
    const initWrapper = ( wrapper ) => {
        if ( !wrapper )
            return;

        const overlay = wrapper.querySelector( OVERLAY );

        if ( !overlay || isMarked( overlay ) )
            return;

        mark( overlay );

        new ShortcodeSwitcher( wrapper );
    }

    const mo = new MutationObserver( ( mutations ) => {
        for ( const m of mutations ) {
            for ( const n of m.addedNodes ) {
                if ( n.nodeType !== 1 )
                    continue;

                if ( n.matches?.( WRAPPER ) )
                    initWrapper( n );

                n.querySelectorAll?.( WRAPPER ).forEach( initWrapper );
            }
        }
    });

    mo.observe( document, { childList: true, subtree: true } );
}

/**
 * Observe Gutenberg for the shortcode wrapper being inserted asynchronously.
 *
 * Supports both Blocks API v2 (no editor iframe; wrapper appears in the outer document)
 * and Blocks API v3 (editor content rendered inside an iframe canvas).
 *
 * Strategy:
 *  1) Check the current editor document for `.trp-shortcode-switcher__wrapper` and init immediately.
 *  2) If an editor canvas iframe exists, watch its document (and reattach on iframe load) for the wrapper.
 *  3) If no iframe yet, watch the outer document for either the iframe (v3) or the wrapper itself (v2).
 *
 * Initialization is performed once per context to avoid duplicate bindings.
 */
function observeWrapperUntilFound() {
    // If wrapper already exists in current editor doc, init
    const edDoc = getEditorDoc();
    const existing = edDoc.querySelector(WRAPPER);

    if ( existing ) {
        initLanguageSwitchers( edDoc );
        return;
    }

    // Helper to locate the editor canvas iframe in the OUTER document
    const findCanvasIframe = () => document.querySelector('iframe[name="editor-canvas"], .editor-canvas__iframe');

    // If iframe is already present in the outer doc, start watching inside it
    const iframeNow = findCanvasIframe();
    if ( iframeNow ) {
        watchIframe( iframeNow );
        return;
    }

    // Otherwise, observe the OUTER document until the iframe appears
    const outerMO = new MutationObserver( ( mutations ) => {
        for ( const m of mutations ) {
            for ( const n of m.addedNodes ) {
                if ( n.nodeType !== 1 ) continue;

                const iframe =
                          n.matches?.('iframe[name="editor-canvas"], .editor-canvas__iframe')
                              ? n
                              : n.querySelector?.('iframe[name="editor-canvas"], .editor-canvas__iframe');

                if ( iframe ) {
                    outerMO.disconnect();
                    watchIframe( iframe );
                    return;
                }

                // Also catch shortcode wrapper added directly to the outer document (API v2, no iframe)
                const wrapper =
                          n.matches?.(WRAPPER)
                              ? n
                              : n.querySelector?.(WRAPPER);

                if ( wrapper ) {
                    outerMO.disconnect();
                    initLanguageSwitchers( document );
                    return;
                }

            }
        }
    } );
    outerMO.observe( document, { childList: true, subtree: true } );

    function watchIframe( iframe ) {
        // Try immediately (some builds inject srcdoc synchronously)
        tryAttachInside();

        // Also on load/navigate (Gutenberg may reload the canvas)
        iframe.addEventListener( 'load', tryAttachInside );

        function tryAttachInside() {
            let doc;
            try {
                doc = iframe.contentDocument || iframe.contentWindow?.document;
            } catch (e) {
                console.warn('Cannot access iframe content due to cross-origin restrictions', e);
                return;
            }
            if ( !doc ) return;

            // If wrapper is already there, init once and stop.
            const hit = doc.querySelector(WRAPPER);
            if ( hit ) {
                initLanguageSwitchers( doc );
                return;
            }

            // Observe INSIDE the iframe until wrapper appears
            const innerMO = new MutationObserver( ( muts ) => {
                for ( const mm of muts ) {
                    for ( const nn of mm.addedNodes ) {
                        if ( nn.nodeType !== 1 ) continue;
                        if (
                            nn.matches?.(WRAPPER) ||
                            nn.querySelector?.(WRAPPER)
                        ) {
                            innerMO.disconnect();
                            initLanguageSwitchers( doc );
                            return;
                        }
                    }
                }
                if ( doc.querySelector(WRAPPER) ) {
                    innerMO.disconnect();
                    initLanguageSwitchers( doc );
                }
            } );

            innerMO.observe( doc, { childList: true, subtree: true } );
        }
    }
};