@abtasty/widget-quality 0.4.22 → 0.4.23

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/dist/form.js +2222 -1
  2. package/dist/main.js +2699 -1
  3. package/package.json +3 -4
package/dist/main.js CHANGED
@@ -1 +1,2699 @@
1
- !function(){"use strict";const e=()=>Object.prototype.hasOwnProperty.call(top,"ABTastyEditor"),t=()=>{const e=!!document.getElementById("ABTastyPreviewBar"),t=location.href.includes("ab_project=preview");return e||t},n=e=>new Function(`try {\n\t\t${e}\n\t} catch (error) {\n\t\treturn null;\n\t}`)(),i=()=>encodeURIComponent(DATA.spNoTrim?window.location.href.replace(window.location.origin,""):`${window.location.pathname}`),s=()=>!e()&&(t()||!!window.ABTasty.getTestsOnPage()[TEST_ID]),r=()=>window.ABTasty&&!0===window.ABTasty.consentReady,o=()=>{const{type:e}=DATA;return`${PACKAGE.replace("@abtasty/","")}${e?`_${e}`:""}`},a=()=>{const e=o();return`${e.charAt(0).toUpperCase()}${e.slice(1)}`.split("-").join(" ")},c=()=>`${PLUGIN_ID.split("-")[0]}_${TEST_ID}`,l=n=>{const i=(()=>{if(e()||t())return!1;const n=ABTasty.getTestsOnPage()[TEST_ID];return!!n&&Object.keys(n.targetings.qaParameters).length>0})(),s=window.document.cookie.includes("abTastyDebug=")||!0===window.abTastyDebug;if(i||s){const e=a();window.console.log(`%c${e} - ${i?"QA":"Debug"} Mode for campaign ${TEST_ID} %c ${n}`,"background-color: #D6FF01; color: #3100be; padding: 3px 0 3px 10px; border-radius: 5px 0 0 5px; font-weight: bold;","background-color: #3100be; color: white; padding: 3px 10px 3px 0; border-radius: 0 5px 5px 0;")}},h=e=>{const t={promise:null,resolve:null,reject:null,name:e};return t.promise=new Promise((e,n)=>{t.resolve=e,t.reject=n}),t},d=(e,t)=>{const n=t?[]:null;if("string"!=typeof e||!e.trim().length)return n;const[i,s,r]=e.split("[]").map(e=>e.trim()),o=Boolean(r)?r:e,a=s?document.querySelector(i)?.[s]:document;return a?t?[...a.querySelectorAll(o)]:a.querySelector(o):n},u=e=>d(e,!1),g=e=>d(e,!0),m=(e,t)=>{const n={childList:!0,subtree:!0,attributes:!0},i=()=>s.disconnect(),s=new MutationObserver(()=>{const n=u(t);return n&&!i()&&e(n)});return{clear:i,observe:e=>{const t=document.querySelector("body")||document.documentElement,i=e??t;s.observe(i,n)}}},p=()=>{},v=(t,n)=>{const i=u(t),s={selector:t,clear:p,observe:p};if(i)return setTimeout(()=>n(i),0),s;if(e())return setTimeout(()=>v(t,n),1e3),s;if(t.includes("[]"))return((e,t)=>{const[n,i]=t.split("[]").map(e=>e.trim()),s=u(n),r=s?.[i],{clear:o,observe:a}=m(e,t),c=()=>{const n=u(t);return n&&!l()&&e(n)},l=()=>{o(),s?.removeEventListener("load",c)},h=()=>{a(r),"iframe"===s?.localName&&s.addEventListener("load",c)};return h(),{selector:t,clear:l,observe:h}})(n,t);const{clear:r,observe:o}=m(n,t);return o(),{selector:t,clear:r,observe:o}};function f(e,t){const n=e.parentElement||e.getRootNode().host;return t(e)||!n?e:f(n,t)}const y=t=>{e()||(t.preventDefault(),t.stopPropagation(),t.stopImmediatePropagation())},b=(e,t)=>[...g(t)].some(n=>{const[i,,s]=t.split("[]"),r=s??i;return n===e||!!e.closest(r)});let w=!1;class T{constructor(){this.targets=[],this.existingTargets=[],this.inViewportTargets=[],this.visibilityObserver=null,this.mutationObserver=null,this.mouseOverEvent=null,this.scrollEvent=null,this.onTransitionEnd=null,this.onIframeLoad=null}transitionOverHandler(e){const t=[e,"transitionend",this.checkElements.bind(this),!0];return this.getEvents(...t)}intersectionHandler(e){e.forEach(e=>{e.isIntersecting?(this.existingTargets.forEach(t=>{t.element.isSameNode(e.target)&&(this.inViewportTargets.push(t),this.mouseOverEvent.start(),this.scrollEvent.start(),this.onTransitionEnd.start())}),this.checkElements()):this.inViewportTargets=this.inViewportTargets.filter(t=>!t.element.isSameNode(e.target)||(this.mouseOverEvent.clear(),this.scrollEvent.clear(),this.onTransitionEnd.clear(),!1))})}startVisibilityObserver(e){const t={root:e,rootMargin:"0px",threshold:.01};return this.visibilityObserver??=new IntersectionObserver(this.intersectionHandler.bind(this),t),this.visibilityObserver}startMutationObserver(e){return this.mutationObserver??=new MutationObserver(this.checkElements.bind(this)),this.mutationObserver.observe(e,{attributes:!0,childList:!0,subtree:!0}),this.mutationObserver}onMouseOver({target:e,path:t}){const n=this.inViewportTargets.find(({element:n,selector:i})=>{if(n.isSameNode(e))return!0;const[s,,r]=i.split("[]"),o=r??s,a=[...e.querySelectorAll(o)];if(a.length&&a.includes(n))return!0;if(t.includes(n))return!0;if(!e.parentElement?.children?.length)return;const c=[...e.parentElement.children],l=c.findIndex(t=>t.isSameNode(e)),h=c.filter((e,t)=>t>l);if(h.length){if(h.includes(n))return!0;if(h.some(e=>[...e.querySelectorAll(o)].includes(n)))return!0}return!1});if(n&&this.isElementVisible(n.element)){const{selector:e,element:t,uniqueId:i}=n,s=this.targets.find(t=>t.selector===e&&t.uniqueId===i);s&&s.resolve(t),this.clear(e,i)}}getEvents(e,...t){return{start:()=>e?.addEventListener(...t),clear:()=>e?.removeEventListener(...t)}}mouseOverHandler(e){const t=[e,"ontouchstart"in window||navigator.maxTouchPoints>0||navigator.msMaxTouchPoints>0?"touchmove":"mouseover",e=>{const t=e.composedPath(),{target:n}=e;setTimeout(()=>this.onMouseOver({target:n,path:t}),50)},!0];return this.getEvents(...t)}scrollEventHandler(e){const t=[e,"scroll",(n=this.checkElements.bind(this),()=>{w||(w=!0,setTimeout(()=>{n(),w=!1},100))}),{passive:!0}];var n;return this.getEvents(...t)}isElementVisible(e){return this.isElementOpaque(e)&&this.isElementTopmost(e)}isElementOpaque(e){return"HTML"===f(e,e=>"0"===window.getComputedStyle(e).opacity).nodeName}isElementTopmost(e){const t=e.getBoundingClientRect(),n=[[t.left,t.top],[t.right,t.top],[t.left,t.bottom],[t.right,t.bottom],[t.left+t.width/2,t.top],[t.left+t.width/2,t.bottom],[t.left,t.height/2],[t.right,t.height/2],[t.left+t.left/2,t.height/2]];let i=!1,s=0;for(;!i&&s<n.length;){const t=e.getRootNode()?.elementFromPoint(...n[s]);i=e===t||t?.contains(e)||e.contains(t),s+=1}return i}checkElements(){this.targets.forEach(({selector:e,uniqueId:t})=>{const n=u(e),[i,,s]=e.split("[]"),r=s??i;n&&!this.existingTargets.find(e=>e.element.matches(r)&&e.uniqueId===t)&&(this.existingTargets.push({element:n,selector:e,uniqueId:t}),this.visibilityObserver.observe(n))}),this.existingTargets=this.existingTargets.filter(({selector:e,element:t})=>!(!u(e)||!t.isConnected)||(t&&this.visibilityObserver.unobserve(t),!1)),this.inViewportTargets=this.inViewportTargets.filter(({selector:e,element:t,uniqueId:n})=>{const[i,,s]=e.split("[]"),r=s??i;if(t.matches(r)&&this.isElementVisible(t)){const i=this.targets.find(t=>t.selector===e&&t.uniqueId===n);return i&&i.resolve(t),this.clear(e,n),!1}return!0})}onLoadIframe(e){const t=[e.defaultView.frameElement,"load",()=>this.watch(selector,resolve,uniqueId).bind(this),{passive:!0}];return this.getEvents(...t)}watch(e,t,n){this.targets.push({selector:e,resolve:t,uniqueId:n});const{clear:i}=v(e,e=>{i();const t=e.getRootNode({composed:!0}),n="body"in t?t.body:document;this.mouseOverEvent=this.mouseOverHandler(t),this.scrollEvent=this.scrollEventHandler(t),this.onTransitionEnd=this.transitionOverHandler(t),t.defaultView?.frameElement&&(this.onIframeLoad=this.onLoadIframe(t),this.onIframeLoad.start()),this.startVisibilityObserver(t),this.startMutationObserver(n),this.checkElements()})}clear(e,t){[this.targets,this.existingTargets,this.inViewportTargets]=[this.targets,this.existingTargets,this.inViewportTargets].map(n=>n.filter(({selector:n,uniqueId:i})=>n!==e&&i!==t));const n=u(e);n&&this.visibilityObserver?.unobserve(n),0===this.targets.length&&(this.mutationObserver?.disconnect(),this.onIframeLoad?.clear()),0===this.inViewportTargets.length&&(this.mouseOverEvent?.clear(),this.scrollEvent?.clear(),this.onTransitionEnd?.clear())}}const E="remove",C="rebuild",S="update",A="ABTastyData";class x{constructor({triggerEvent:e,triggerSelector:t,triggerDelay:n,triggerTarget:i}){this.event=e,this.selector=Boolean(t)?t:"body",this.target="string"==typeof i?u(t):i,this.delay=1e3*n,this.triggerElements=[],this.eventsListeners=[],this.timeouts=[],this.intervals=[],this.promises=[],this.visibilityObservers=[],this.socialProofStore={},this.elementWaiters=[]}async onElementVisible({promise:e,resolve:t}){const n=h(`${this.event}DomReady`);this.promises.push(n);const{clear:i}=v(this.selector,()=>{const e=new T;this.visibilityObservers.push(e),e.watch(this.selector,t,c())});return this.elementWaiters.push(i),e}onPageLoad({promise:e,resolve:t}){const n=()=>"complete"===document.readyState;if(!n()){const i=["readystatechange",()=>n()&&t(!0),{passive:!0}];return this.eventsListeners.push([document,...i]),document.addEventListener(...i),e}return t(!0),e}onClick({promise:e,resolve:t}){const n=({isTrusted:e,target:n})=>{if(e)return(n.isEqualNode(this.target)||b(n,this.selector))&&t(!0)},{clear:i}=v(this.selector,e=>{i();const t=document.createElement("style");t.id=`Click_${c()}`;const[s,,r]=this.selector.split("[]"),o=r??s;t.innerHTML=`${o} {\n\t\t\t\tcursor: pointer !important;\n\t\t\t\tpointer-events: all !important;\n\t\t\t}`;const a=e.getRootNode();("head"in a?a.head:a).appendChild(t),this.triggerElements.push(t);const l=["click",n,{passive:!0,capture:!0}];this.eventsListeners.push([a,...l]),a.addEventListener(...l)});return this.elementWaiters.push(i),e}onHover({promise:e,resolve:t}){const n=({isTrusted:e,target:n})=>{if(e)return(this.target?n.isEqualNode(this.target):b(n,this.selector))&&t(!0)},{clear:i}=v(this.selector,e=>{const t=e.getRootNode(),i="body"in t?t.body:[...t.childNodes].find(t=>t.contains(e)),s=["mouseenter",n,{passive:!0,capture:!0}];this.eventsListeners.push([i,...s]),i.addEventListener(...s)});return this.elementWaiters.push(i),e}onExitIntent({promise:e,resolve:t}){const n=["mouseleave",({isTrusted:e,clientY:n})=>{e&&n<=0&&t(!0)},{passive:!0}],{clear:i}=v("html",e=>{i(),this.eventsListeners.push([e,...n]),e.addEventListener(...n)});return e}onReengage({promise:e,resolve:t}){const n=this.delay;let i=n;const s=[...document.querySelectorAll("*:empty")].map(e=>e.contentDocument||e.shadowRoot).filter(e=>e),r=[({isTrusted:e})=>{e&&(i=n)},{passive:!0}];["click","mousemove","scroll","keypress"].forEach(e=>{[document,...s].forEach(t=>{this.eventsListeners.push([t,e,...r]),t.addEventListener(e,...r)})});const o=setInterval(()=>{i<=0?t(!0):i-=100},100);return this.intervals.push(o),e}onCustomTrigger({promise:e,resolve:t}){const{triggerEventCustomScript:n}=DATA,i="undefined"!=typeof DATA_JS&&DATA_JS?.triggerEventCustomScript,s="function"==typeof i?()=>new Promise(e=>i(e)):new Function(`return new Promise(async resolve => {${n}})`);return s().then(e=>e&&t(!0)),e}onScrollUp({promise:e,resolve:t}){let n=0;const i=["scroll",({isTrusted:e})=>{e&&(window.scrollY<n?t(!0):n=window.scrollY)},{passive:!0,capture:!0}];return this.eventsListeners.push([document,...i]),document.addEventListener(...i),e}onScrollPercentReached({promise:e,resolve:t}){const{triggerEventScrollPercent:n}=DATA,i=["scroll",({isTrusted:e})=>{if(!e)return;const i=(()=>{const{documentElement:e,body:t}=document,n=e.scrollTop||t.scrollTop,i=e.scrollHeight||t.scrollHeight;return Math.trunc(n/(i-e.clientHeight)*100,10)})();n<i&&t(!0)},{passive:!0,capture:!0}];return this.eventsListeners.push([document,...i]),document.addEventListener(...i),e}checkSocialProofConditions(e,t,n,i){const s=(()=>{let e;return window.ABTasty||window.ABTASTY_S?(window.ABTASTY_S?.USER?.accountIdentifier?.length?e=window.ABTASTY_S.USER.accountIdentifier:"function"==typeof window.ABTasty?.getAccountSettings?e=window.ABTasty.getAccountSettings().identifier:window.ABTasty?.accountSettings&&(e=window.ABTasty.accountSettings.identifier),e):e})(),{viewInterval:r,spNoTrim:o}=DATA;if(this.socialProofStore.hasOwnProperty(e))n(this.socialProofStore[e])?i(`${this.socialProofStore[e][r]}`):i(!1);else if(e&&s){const a=t=>(this.socialProofStore[e]=t,i(!!n(t)&&`${t[r]}`));fetch(`https://api-social-proof.abtasty.com/clients/${s}/metrics/${t}?key=${e}${o?"&noTrim=true":""}`).then(e=>e.ok&&e.json()).then(a).catch(()=>l("Failed to fetch datas from server."))}else i(!1)}getSocialProofDatas({promise:e,resolve:t},s,r=!1){const{productKey:o,keyType:a}=(()=>{const{socialProofContentType:e,productKeyProvider:t,pathToProductKey:s,customJSProductKey:r,productSKU:o}=DATA,{pathToProductKey:a,customJSProductKey:c}="undefined"!=typeof DATA_JS?DATA_JS:{};if(2===e)return{productKey:i(),keyType:"url"};{let l=null,h="sku";switch(t){case"ABTastyProductKey":l=window.ABTastyProductKey;break;case"pathToProductKey":l="function"==typeof a?a():n(`return ${s};`);break;case"customJSProductKey":l="function"==typeof c?c():n(r);break;case"productSKU":l=o}return l||3!==e||(l=i(),h="url"),{productKey:l,keyType:h}}})(),{viewInterval:c,triggerSocialProofMinVisitors:h,triggerSocialProofMinPurchases:d,triggerSocialProofMinPageViews:u}=DATA,g={pv:u,i:d,"v-pv":h}[s];return[typeof c,typeof g].includes("undefined")&&t(!1),r&&!o&&(l("Not able to find ABTastyProductKey, impossible to call the API, read documentation for more informations:\n\t\t\t\thttps://support.abtasty.com/hc/en-us/articles/4710919241628-Widgets-List#h_84c04344-c655-4e5e-b9ab-d26a798ad9b0"),t(!1)),this.checkSocialProofConditions(o,"v-pv"===s&&"sku"===a?"v-i":s,e=>{const t=void 0!==e[c]&&e[c]>=g;return t||l(`Widget will not be shown, Social Proof API returned ${e[c]} while ${g} are required`),t},t),e}onConsent({promise:e,resolve:t}){if(!r()){const n=["abtasty_consentValid",()=>t(!0)];return this.eventsListeners.push(n),window.addEventListener(...n),e}return t(!0),e}onTrackingSent({promise:e,resolve:t}){const{triggerEventTrackingSent:n}=DATA;let i=localStorage.getItem(A);const s=()=>JSON.parse(i)?.ActionTracking?.some(({name:e})=>e===n),r=["storage",({key:e,newValue:n})=>{e===A&&(i=n,s()&&t(!0))},{passive:!0,capture:!0}];return i&&s()?t(!0):(()=>{this.eventsListeners.push([window,...r]),window.addEventListener(...r)})(),e}onMinPagesViewed({promise:e,resolve:t}){const{triggerEventMinPagesViewed:n}=DATA;let i=localStorage.getItem(A);const s=()=>n<=(i?JSON.parse(i)?.VisitedPages?.length:0),r=["storage",({key:e,newValue:n})=>{e===A&&(i=n,s()&&t(!0))},{passive:!0,capture:!0}];return i&&s()?t(!0):(()=>{this.eventsListeners.push([window,...r]),window.addEventListener(...r)})(),e}onRageClick({promise:e,resolve:t}){const{triggerEventRageClickQuantity:n,triggerEventRageClickDelay:i}=DATA;let s=0,r=!1;const o=["click",({isTrusted:e})=>{if(e&&(s+=1,s>=n&&t(!0),!r)){r=!0;const e=setTimeout(()=>{s=0,r=!1},i);this.timeouts.push(e)}},{passive:!0,capture:!0}],a=e=>{this.eventsListeners.push([e,...o]),e.addEventListener(...o)},{clear:c}=v("iframe []contentDocument[] body > *",()=>{const e=document.getElementsByTagName("iframe");for(const t of e){"contentDocument"in t&&"body"in t.contentDocument&&a(t.contentDocument);const e=()=>a(t.contentDocument);t.addEventListener("load",e),this.eventsListeners.push([t,"onIframeLoad",e])}});return this.elementWaiters.push(c),a(document),e}clear(){this.triggerElements=this.triggerElements.filter(e=>(e.remove(),!1)),this.eventsListeners=this.eventsListeners.filter(e=>{const[t,...n]=e;return t&&n.length>1&&t.removeEventListener(...n),!1}),this.timeouts=this.timeouts.filter(e=>(clearTimeout(e),!1)),this.intervals=this.intervals.filter(e=>(clearInterval(e),!1));const e=c();return this.visibilityObservers=this.visibilityObservers.filter(t=>(t.clear(this.selector,e),!1)),this.promises=this.promises.filter(e=>(e.resolve(!1),!1)),this.elementWaiters=this.elementWaiters.filter(e=>(e(),!1)),this}async isTriggered(){this.clear();const e=h(this.event);this.promises.push(e);const t={consent:()=>this.onConsent(e),direct:()=>!0,pageLoad:()=>this.onPageLoad(e),click:()=>this.onClick(e),exitIntent:()=>this.onExitIntent(e),reengage:()=>this.onReengage(e),elementVisible:()=>this.onElementVisible(e),script:()=>this.onCustomTrigger(e),hover:()=>this.onHover(e),scrollUp:()=>this.onScrollUp(e),scrollPercent:()=>this.onScrollPercentReached(e),rageClick:()=>this.onRageClick(e),minPagesViewed:()=>this.onMinPagesViewed(e),trackingSent:()=>this.onTrackingSent(e),socialProofPurchases:()=>this.getSocialProofDatas(e,"i",!0),socialProofPageViews:()=>this.getSocialProofDatas(e,"pv"),socialProofVisitors:()=>this.getSocialProofDatas(e,"v-pv")},n=!Object.prototype.hasOwnProperty.call(t,this.event)||await t[this.event]();return n&&this.clear(),"reengage"!==this.event&&this.delay?n&&await(async()=>{const e=h(`${this.event}Delay`);this.promises.push(e);const t=setTimeout(()=>{e.resolve(!0),this.clear()},this.delay);return this.timeouts.push(t),e.promise})():n}}const k="display",P="closing",I="validation",N="ABTastyWidgets",L=`${N}Temporary`;class R{constructor({displayRecurrence:e,closingRecurrence:t,validationRecurrence:n},i){this.displayRecurrence=parseFloat(e),this.closingRecurrence=parseFloat(t),this.validationRecurrence=parseFloat(n),this.onSetCallback=i,this.widgetName=o(),this.uniqueId=c(),this.recurrenceKey=`${this.widgetName}_${this.uniqueId}`,this.isListeningStorageEvent=this.listenStorageEvent(),this.pendingRecurrence=!1,this.pendingRecurrenceValue={}}onStorage({key:e}){const t=localStorage.getItem(L),n=sessionStorage.getItem(N);"ABTastyData"===e&&!t&&n&&localStorage.setItem(L,n)}listenStorageEvent(){return this.isListeningStorageEvent||window.addEventListener("storage",this.onStorage.bind(this)),!0}getGivenRecurrenceStorageParsed(e){try{const t=e.getItem(N);return JSON.parse(t)}catch(t){return e.removeItem(N),!1}}getSessionRecurrenceStorageParsed(){return this.getGivenRecurrenceStorageParsed(window.sessionStorage)}getLocalRecurrenceStorageParsed(){return this.getGivenRecurrenceStorageParsed(window.localStorage)}removeGivenStorage(e,t){const{[this.recurrenceKey]:n,...i}=t;return Object.entries(i).length?(e.setItem(N,JSON.stringify(i)),i):(e.removeItem(N),!1)}removeSessionRecurrenceStorage(){const e=this.getSessionRecurrenceStorageParsed();return!!e&&this.removeGivenStorage(window.sessionStorage,e)}removeLocalRecurrenceStorage(){const e=this.getLocalRecurrenceStorageParsed();return!!e&&this.removeGivenStorage(window.localStorage,e)}getSessionRecurrence(){const e=this.getSessionRecurrenceStorageParsed();return!!e&&e[this.recurrenceKey]}getLocalRecurrence(){const e=this.getLocalRecurrenceStorageParsed();return!!e&&e[this.recurrenceKey]}getCurrentRecurrence(){if(this.pendingRecurrence)return this.pendingRecurrenceValue;const e=this.getSessionRecurrence(),t=this.getLocalRecurrence();return e||t||{type:!1}}isOver(){const e=localStorage.getItem(L),t=!(!e||!e.includes(this.recurrenceKey))||this.getSessionRecurrence();e&&(sessionStorage.setItem(N,e),localStorage.removeItem(L));const n=this.getLocalRecurrence(),i=(n?parseFloat(n.stamp):0)<(new Date).getTime();return i&&this.removeLocalRecurrenceStorage(),!this.pendingRecurrence&&i&&!this.getLocalRecurrence()&&!t}setRecurrence(e,n){0!==e&&(window.removeEventListener("storage",this.onStorage.bind(this)),this.isListeningStorageEvent=!1);const i=this.getTypeOfStorage(e);if(t()||!i&&"object"!=typeof i)return!1;const{storageString:s,storageMethod:o}=i,a=this.getStamp(e),c={type:n,stamp:a},{type:l}=this.getCurrentRecurrence(),h=async()=>{if(!r()){this.pendingRecurrence=!0,this.pendingRecurrenceValue=c;const e=new x({triggerEvent:"consent"});await e.isTriggered(),this.pendingRecurrence=!1,this.pendingRecurrenceValue={}}const e=this.getSessionRecurrence(),t=this.getLocalRecurrence();let n;"session"===s?e?n=this.removeSessionRecurrenceStorage():(this.removeLocalRecurrenceStorage(),n=this.getSessionRecurrenceStorageParsed()):"local"===s&&(t?n=this.removeLocalRecurrenceStorage():(this.removeSessionRecurrenceStorage(),n=this.getLocalRecurrenceStorageParsed()));const i=n?{[this.recurrenceKey]:c,...n}:{[this.recurrenceKey]:c};o.setItem(N,JSON.stringify(i)),this.onSetCallback&&"function"==typeof this.onSetCallback&&this.onSetCallback()};if(!o)return!1;if(l&&n!==I)if(n===P&&l!==I)h();else{if(n!==k||l===I||l===P)return!1;h()}else h();return a}setDisplayRecurrence(){const e=k;this.setRecurrence(this.displayRecurrence,e)}setClosingRecurrence(){const e=P;this.setRecurrence(this.closingRecurrence,e)}setValidationRecurrence(){const e=I;this.setRecurrence(this.validationRecurrence,e)}getStamp(e){return(new Date).getTime()+864e5*e}getTypeOfStorage(e){return!(isNaN(e)||e<0||0!==e&&!e)&&(e>0?{storageString:"local",storageMethod:window.localStorage}:0===e&&{storageString:"session",storageMethod:window.sessionStorage})}}class D{constructor(e,t,n){this.isWidgetApplied=e,this.callback=t,this.shouldUpdate=n,this.triggerIframeTarget=null,this.observer=new MutationObserver(this.observerHandler.bind(this)),this.tagRollbackEventParams=["abtasty_resetActionTracking",this.onTagRollback.bind(this)],this.onCampaignLaunchedEventParams=["abtasty_executedCampaign",this.onCampaignLaunched.bind(this)]}decisionHandler(e){const t=!e&&this.isWidgetApplied(),n=t?this.shouldUpdate&&S:C;return n?(this.clearWatcher(),this.callback(n,!e,t),this.watch(),this):this}onCampaignLaunched({detail:{campaignId:e}}){e===TEST_ID&&(this.callback(C,!1),this.watch())}onTagRollback({target:e}){return this.clearWatcher(e),this.callback(E,!1,!0),window.addEventListener(...this.onCampaignLaunchedEventParams),this}observerHandler(e){return s()?e.some(e=>["removedNodes","addedNodes"].some(t=>e[t]&&e[t].length))?this.decisionHandler():this:this.callback(E,!1)}watch(t,n){if(e())return this;if(this.clearWatcher(t),window.removeEventListener(...this.onCampaignLaunchedEventParams),document.addEventListener(...this.tagRollbackEventParams),n?.includes("[]contentDocument[]")){const e=n.split("[]")[0].trim(),{clear:t}=v(e,e=>{t(),this.triggerIframeTarget=e,e.addEventListener("load",this.decisionHandler.bind(this))})}const i=t?.defaultView?.frameElement;i&&this.triggerIframeTarget!==i&&i.addEventListener("load",this.decisionHandler.bind(this));const{clear:s}=v("body",e=>{s();const n=t?.body||t||e;this.observer.observe(n,{childList:!0,subtree:!0})});return this}clearTriggerElementWatcher(){this.triggerIframeTarget?.removeEventListener("load",this.decisionHandler.bind(this))}clearWatcher(e){return document.removeEventListener(...this.tagRollbackEventParams),this.observer.disconnect(),this.clearTriggerElementWatcher(),e?.defaultView?.frameElement?.removeEventListener("load",this.decisionHandler.bind(this)),this}}const B=/.+\/([^.]+)\.(otf|ttf)$/,O=["socialProofPurchases","socialProofPageViews","socialProofVisitors"];class _{constructor(t,n){this.children=void 0,this.uniqueId=`${c()}${n?`_${n}`:""}`,this.widgetName=o(),this.prettyName=a(),this.recurrenceParams=(()=>{const{displayRecurrence:t,closingRecurrence:n,validationRecurrence:i}=DATA,s=!t&&!n&&!i;if(e()||s)return!1;const r={everytime:()=>-1,session:()=>0,once:()=>395,day:e=>DATA[`${e}_day`],week:e=>7*DATA[`${e}_week`],month:e=>30.5*DATA[`${e}_month`]},o={};return t&&(o.displayRecurrence=r[t]("displayRecurrence")),n&&(o.closingRecurrence=r[n]("closingRecurrence")),i&&(o.validationRecurrence=r[i]("validationRecurrence")),o})(),this.triggerParams=(t=>{let{triggerEvent:n}=DATA;const{triggerEventClick:i,triggerEventHover:s,triggerEventReengageDelay:r,socialProofContentType:o,triggerEventElementVisible:a,triggerEventDelay:c}=DATA;if(e()||!n&&!o)return!1;const l={click:()=>i,hover:()=>s,elementVisible:()=>a},h=Object.prototype.hasOwnProperty.call(l,n)?l[n]():"body",d="reengage"===n?r:c;return o&&(n=[,"socialProofPurchases","socialProofPageViews","socialProofVisitors"][o]),{triggerEvent:n,triggerSelector:h,triggerDelay:d,triggerTarget:t}})(t),this.recurrence=!!this.recurrenceParams&&new R(this.recurrenceParams,this.clearGivenClearables.bind(this)),this.trigger=!!this.triggerParams&&new x(this.triggerParams),this.shouldUpdate=!!this.triggerParams&&O.includes(this.triggerParams.triggerEvent),this.pageWatcher=new D(this.isWidgetApplied.bind(this),this.onPageChange.bind(this)),this.hasOncePerPageTrigger=(()=>{const{isOncePerPageTrigger:e,triggerEvent:t}=DATA;return!t||!["click","hover","scrollUp","script"].includes(t)||e})(),this.basicClassName=`ab_widget_container_${this.widgetName}`,this.widgetContainerId=`${this.basicClassName}_${this.uniqueId}`,this.contentClassName=`${this.basicClassName}_content`,this.overlayClassName=`${this.basicClassName}_overlay`,this.closeButtonClassName=`${this.basicClassName}_close_button`,this.hideClassName=`ab_hide_${this.uniqueId}`,this.rootElement=null,this.domElement=this.getDom(),this.hasBeenShown=!1,this.closedByUser=!1,this.websiteFocusedElement=null,this.elementsWaiters=[]}clearGivenClearables(){for(const e of this.elementsWaiters)e.clear();this.elementsWaiters=[]}isWidgetApplied(){return this.domElement?.isConnected&&this.domElement.ownerDocument?.defaultView}removeOldDomElement(){const e=this.rootElement?.getElementById(this.widgetContainerId);return e?.remove(),this}async insert(){if(this.isWidgetApplied())return!1;const e=["free"];"drawer"===DATA.layout&&DATA.customTarget&&e.push("drawer");const t=e.includes(DATA.layout);return new Promise(e=>{const{elementReferrer:n="body",referrerInsertType:i="beforeend"}=t?DATA:{},s=v(n,t=>{this.elementsWaiters=this.elementsWaiters.filter(e=>e.selector!==n),this.rootElement=t.getRootNode(),this.removeOldDomElement(),this.domElement.appendChild(this.styleElement),e(t.insertAdjacentElement(i,this.domElement))});this.elementsWaiters.push(s)}).then(()=>this)}remove(){this.trigger&&this.trigger.clear(),this.pageWatcher.clearWatcher(this.rootElement);for(const e of this.elementsWaiters)[DATA.elementReferrer,"body"].includes(e.selector)&&e.clear();return this.domElement?.isConnected&&this.domElement.remove(),this.hasOncePerPageTrigger?this.pageWatcher.watch(this.rootElement):e()||this.init().then(({response:e})=>e?this.show():this),this}show(){const{layout:t,overlay:n=!0}=DATA;return e()||this.hasBeenShown&&this.hasOncePerPageTrigger||window.ABTastyEvent(`${this.prettyName} displayed`,null,TEST_ID),this.closedByUser=!1,this.websiteFocusedElement=document.activeElement,setTimeout(()=>{this.domElement.classList.remove(this.hideClassName),e()||"popin"!==t||!0!==n||this.domElement.querySelector('input[type="text"], textarea, a, button')?.focus()},50),this.recurrence&&this.recurrence.setDisplayRecurrence(),this.hasBeenShown=!0,this.pageWatcher.watch(this.rootElement),this}hide(t=!0){return!e()&&this.hasBeenShown&&t&&window.ABTastyEvent(`${this.prettyName} closed`,null,TEST_ID),t&&(this.pageWatcher.clearWatcher(this.rootElement),this.closedByUser=!0),this.domElement.classList.add(this.hideClassName),!e()&&this.websiteFocusedElement?.isConnected&&this.websiteFocusedElement.focus(),this}async init(t){const n=e(),i=s(),r=this.trigger?.promises?.length,o=!this.recurrence||this.recurrence.isOver();if(!n&&!i||r||!o)return{container:this,response:!1};this.pageWatcher.watch(this.rootElement||document,this.triggerParams.triggerSelector);const a=n||!this.trigger||this.trigger&&await this.trigger.isTriggered();this.pageWatcher.clearTriggerElementWatcher();const c={container:this,response:a};return a?(await this.insert(),this.addCloseEvent(),n||t||this.hasBeenShown||void 0===this.children||"function"!=typeof this.children.refreshContent||this.children.refreshContent(a),c):c}onPageChange(e,t,n){const i=()=>this.init().then(({response:e})=>{e?this.show():this.hide(!1)});t||(this.hasBeenShown=!1,n&&this.domElement.remove(),this.trigger&&this.trigger.clear());const s={[E]:()=>n?this.remove():this.pageWatcher.watch(this.rootElement),[C]:()=>{this.hasBeenShown?this.closedByUser?this.pageWatcher.watch(this.rootElement):n||this.insert().then(e=>e.show()).catch(this.pageWatcher.watch):i()},[S]:()=>{this.hasBeenShown?this.pageWatcher.watch():i()}};"function"==typeof s[e]&&s[e]()}addCloseEvent(...t){const{closeButton:n,overlay:i,overlayClickable:s,layout:r,animationDuration:o=1e3}=DATA,a=[];if(void 0!==i&&!0!==i||!0!==s||"popin"!==r||a.push(`.${this.overlayClassName}`),void 0!==n&&n&&a.push(`.${this.closeButtonClassName}`),!a.length)return this;const c=this.domElement.querySelectorAll(a.join(", "));if(!c.length)return this;const l=e=>{const t="click"===e.type,n="keyup"===e.type&&"Escape"===e.code&&e.isTrusted;(t||n)&&(y(e),this.recurrence&&this.recurrence.setClosingRecurrence(),this.hide(!0),setTimeout(()=>this.remove(),1.05*o))},h=["click",l,{once:!0,capture:!0}];t.push(...c);for(const n of t)e()&&(n.dataset.abtastyActionnable="true"),n.removeEventListener(...h),n.addEventListener(...h);return window.removeEventListener("keyup",l,{once:!0}),window.addEventListener("keyup",l,{once:!0}),this}getDom(){const{closeButton:e,layout:t,overlayClickable:n,overlay:i=!0}=DATA,s=document.createElement("div");return s.className=`${this.basicClassName} ${this.hideClassName}`,s.id=this.widgetContainerId,["popin","bannerTop","bannerBottom"].includes(t)&&(s.role="dialog","popin"===t&&!0===i&&(s.ariaModal="true")),s.innerHTML=`\n\t\t\t${"popin"===t&&!0===i?`<div ${n?'aria-label="Close dialog"':""} class="${this.overlayClassName}"></div>`:""}\n\t\t\t<div class="${this.contentClassName}">\n\t\t\t${e?`<button class="${this.closeButtonClassName}" aria-label="Close dialog"><svg viewBox="0 0 16 16">\n\t<defs><path id="prefix__a" d="M12 4.991L11.009 4 8 7.009 4.991 4 4 4.991 7.009 8 4 11.009 4.991 12 8 8.991 11.009 12 12 11.009 8.991 8z"></path></defs>\n\t<g><use xlink:href="#prefix__a"></use></g>\n</svg></button>`:""}\n\t\t\t</div>`,s}loadFont(e,t){if(!e||"inherit"===e||!/otf|ttf/g.test(t))return;const n=document.createElement("style"),i=t.match(B)?t.match(B)[1]:"";n.innerHTML=`@font-face { font-family: '${e}_${i}'; src: url('${t}'); font-display: swap; }`;const s=this.rootElement?.head||document.head;s?.appendChild(n)}getStyleTag(t="",n=DATA){const{noStyles:i,layout:s}=n,{backgroundColor:r,isBackgroundImage:o,backgroundImage:a,backgroundSize:c,backgroundPosition:l,backgroundRepeat:h,borderColor:d,borderRadius:u,borderWidth:g,textColor:m,textAlign:p,fontName:v,fontStyle:f,fontSize:y,isTitle:b,titleTextAlign:w,titleTextColor:T,titleFontName:E,titleFontStyle:C,titleFontSize:S,overlay:A,overlayColor:x,dropShadow:k,dropShadowColor:P,dropShadowBlur:I,containerMargin:N,containerPadding:L,closeButton:R,closeButtonPosition:D,closeButtonSize:O,closeButtonBorderRadius:_,closeButtonBorderWidth:V,closeButtonBorderColor:W,closeButtonColor:j,closeButtonBackgroundColor:H,buttonsAlign:q,buttonsBorderWidth:M,buttonsBorderColor:F,buttonsBorderRadius:z,buttonsBackgroundColor:K,buttonsTextColor:U,buttonsFontName:J,buttonsFontStyle:G,buttonsFontSize:Y,secondLink:Q,secondLinkBorderWidth:X,secondLinkBorderColor:Z,secondLinkBorderRadius:ee,secondLinkBackgroundColor:te,secondLinkTextColor:ne,secondLinkFontName:ie,secondLinkFontStyle:se,secondLinkFontSize:re,animation:oe,animationDuration:ae,animationBehaviour:ce,animationSlideDirection:le}=i?{}:n,he=document.createElement("style");e()&&he.setAttribute("abtasty-script-added","true"),this.loadFont(v,f),this.loadFont(E,C),this.loadFont(J,G),this.loadFont(ie,se);const de=`background: ${["string"==typeof r?r:"rgba(255, 255, 255, 1)",o&&"string"==typeof a&&a.length?`url(${a})`:"",o&&"string"==typeof l&&"100% 100%"!==c?l:"0 0",o&&"string"==typeof c?`/ ${c}`:"/ auto",o&&h&&!["cover","100% 100%"].includes(c)?"repeat":"no-repeat"].join(" ").trim()};`,ue="number"==typeof g&&g>0,ge=`border: ${[ue?`${g}px`:"unset",ue?"solid":"",ue&&"string"==typeof d&&d.length?d:""].join(" ").trim()};`,me=void 0!==u?`border-radius: ${u}px;`:"",pe=void 0!==m?`color: ${m}; fill: ${m}; -webkit-text-fill-color: ${m};`:"",ve=void 0!==p?`text-align: ${p};`:"",fe=v&&"inherit"!==v?`font-family:${v}_${f.match(B)?f.match(B)[1]:""};`:f||"",ye=y?`font-size: ${y}px;`:"",be=void 0!==k&&k?`box-shadow: 0 5px ${I}px 0 ${P};`:"",we=N instanceof Array&&1===N.length&&N[0],$e=we?`margin: ${we.top}px ${we.right}px ${we.bottom}px ${we.left}px;`:"",Te=we?`margin: calc(${we.top}px * 0.5) calc(${we.right}px * 0.5) calc(${we.bottom}px * 0.5) calc(${we.left}px * 0.5);`:"",Ee=L instanceof Array&&1===L.length&&L[0],Ce=Ee?`padding: ${Ee.top}px ${Ee.right}px ${Ee.bottom}px ${Ee.left}px;`:"",Se=Ee?`padding: calc(${Ee.top}px * 0.5) calc(${Ee.right}px * 0.5) calc(${Ee.bottom}px * 0.5) calc(${Ee.left}px * 0.5);`:"",Ae=void 0!==M&&M?`border-width: ${M}px; border-style: solid;`:"",xe=[F,M].every(e=>void 0!==e)&&M?`border-color: ${F};`:"",ke=void 0!==z?`border-radius: ${z}px;`:"",Pe=void 0!==K?`background-color: ${K};`:"",Ie=void 0!==U?`color: ${U}; fill: ${U}; -webkit-text-fill-color: ${U};`:"",Ne=J&&"inherit"!==J?`font-family:${J}_${G.match(B)?G.match(B)[1]:""};`:G||"",Le=Y?`font-size: ${Y}px;`:"",Re="number"==typeof X?`border-width: ${X}px; border-style: solid;`:"",De=[Z,X].every(e=>void 0!==e)&&X?`border-color: ${Z};`:"",Be=void 0!==ee?`border-radius: ${ee}px;`:"",Oe=void 0!==te?`background-color: ${te};`:"",_e=void 0!==ne?`color: ${ne}; fill: ${ne}; -webkit-text-fill-color: ${ne};`:"",Ve=ie&&"inherit"!==ie?`font-family:${ie}_${se.match(B)?se.match(B)[1]:""};`:se||"",We=re?`font-size: ${re}px;`:"",je="popin"!==s||void 0!==A&&!0!==A?"":[`#${this.widgetContainerId} .${this.overlayClassName} {`,`background-color: ${void 0!==x?x:"rgba(0, 0, 0, 0.6)"};`,"}"].join(""),He="number"==typeof O?O:16,qe=He/2,Me=i||void 0!==R&&R?[`#${this.widgetContainerId} .${this.contentClassName} .${this.closeButtonClassName} {`,"position: absolute;",("out"===D?`bottom: calc(100% + ${qe}px)`:`top: ${qe}px`)+";",`right: ${qe}px;`,"width: auto;","height: auto;","background: none;","border: none;","cursor: pointer;","padding: 0;","margin: 0;","line-height: 0;","z-index: 9;","number"==typeof _?`border-radius: ${_}px;`:"","number"==typeof V&&V>0?`border: ${V}px solid ${void 0!==W?W:"rgba(57, 57, 57, 1)"};`:"","string"==typeof H?`background-color: ${H};`:"","}",`#${this.widgetContainerId} .${this.contentClassName} .${this.closeButtonClassName} svg {`,"pointer-events: none;",`width: ${He}px;`,`height: ${He}px;`,"string"==typeof j?`fill: ${j};`:"","}"].join(""):"",Fe=b&&"string"==typeof T?[`#${this.widgetContainerId} .${this.contentClassName} > * h1, `,`#${this.widgetContainerId} .${this.contentClassName} > * h2, `,`#${this.widgetContainerId} .${this.contentClassName} > * h3, `,`#${this.widgetContainerId} .${this.contentClassName} > * h4, `,`#${this.widgetContainerId} .${this.contentClassName} > * h5, `,`#${this.widgetContainerId} .${this.contentClassName} > * h6 {`,`color: ${T}; fill: ${T}; -webkit-text-fill-color: ${T};`,void 0!==w?`text-align: ${w};`:"",E&&"inherit"!==E?`font-family:${E}_${C.match(B)?C.match(B)[1]:""};`:C||"",S?`font-size: ${S}px;`:"","}"].join(""):"";let ze="";if("string"==typeof oe){const t=(ae/1e3).toFixed(2),n=["top","bottom"].includes(le),i=Number(n),s=[(["top","left"].includes(le)?"-":"")+"100vmax",this.translateValues?this.translateValues[i]:"0"];n&&s.reverse(),ze={none:[`.${this.hideClassName} {`,"opacity: 0 !important;","}"],fade:[`.${this.hideClassName} {`,"opacity: 0 !important;","}",`#${this.widgetContainerId} {`,`transition: opacity ${t}s ${ce};`,"}","@media (prefers-reduced-motion: reduce) {",`#${this.widgetContainerId} {`,"transition: unset;","}","}"],slide:[`.${this.hideClassName} .${this.overlayClassName} {`,"opacity: 0 !important;","}",`#${this.widgetContainerId} .${this.overlayClassName} {`,`transition: opacity ${t}s ${ce};`,"}",`.${this.hideClassName} .${this.contentClassName} {`,`transform: translate(${s.join(", ")}) !important;`,"}",`#${this.widgetContainerId} .${this.contentClassName} {`,`transition: transform ${t}s ${ce};`,"}","@media (prefers-reduced-motion: reduce) {",`#${this.widgetContainerId} .${this.overlayClassName},`,`.${this.hideClassName} .${this.contentClassName},`,`#${this.widgetContainerId} .${this.contentClassName} {`,"transition: unset;","}","}"]}[e()&&!ABTASTY_S.WIDGETS.animationChanged?"none":oe].join("")}const Ke=[`#${this.widgetContainerId} .${this.contentClassName} .buttons_container .second_link {`,`margin-${"fill"===q?"top":"left"}: 8px;`,Re,De,Be,Oe,_e,Ve,We,"}",`#${this.widgetContainerId} .${this.contentClassName} .buttons_container .second_link {`,_e,Ve,We,"}"];return he.textContent=[`#${this.widgetContainerId} style { display: none; }`,`.${this.hideClassName} {`,"pointer-events: none;","}",`#${this.widgetContainerId} {`,"opacity: 1;","}",`#${this.widgetContainerId} .${this.contentClassName} {`,de,me,ge,pe,ve,be,$e,fe,ye,"}",`#${this.widgetContainerId} .${this.contentClassName} p {`,pe,ve,fe,ye,"}",`#${this.widgetContainerId} .${this.contentClassName} > * {`,"display: block;","line-height: 1;","text-indent: unset;",Ce,fe,ye,"}",`#${this.widgetContainerId} .${this.contentClassName} a {`,"text-decoration: underline;","}",`#${this.widgetContainerId} .${this.contentClassName} div.buttons_container a, `,`#${this.widgetContainerId} .${this.contentClassName} button {`,"text-decoration: none;","box-sizing: border-box;","display: inline-block;",Ae,xe,ke,Pe,Ie,Ne,Le,"}",`#${this.widgetContainerId} .${this.contentClassName} div.buttons_container a *:not(.second_link span), `,`#${this.widgetContainerId} .${this.contentClassName} button:not([class*="close_button"], [class*="csatEmojiButton"]) * {`,Ie,Ne,Le,"}",...Q?Ke:[],"@media screen and (max-width: 579px) {",`#${this.widgetContainerId} .${this.contentClassName} {`,Te,"}",`#${this.widgetContainerId} .${this.contentClassName} > * {`,Se,"}","}",je,Me,Fe,ze,`${t}`].join(""),he}}const V=["top: 0;","top: 50%;","bottom: 0;"],W=["left: 0;","left: 50%;","right: 0;"],j=e=>1===e?"-50%":0,H=()=>{if(Array.isArray(DATA.popinPosition)){const{popinPosition:[{x:e,y:t}]}=DATA,n=`translate(${j(t)}, ${j(e)});`;return`${V[e]}${W[t]}transform: ${n}`}return"left: 50%;top: 50%;transform: translate(-50%, -50%);"},q=()=>"autoWidth"in DATA&&!0===DATA.autoWidth,M=()=>{if(q())return"width: auto; height: auto; min-width: fit-content;";const{popinPercentWidth:e,popinPixelsWidth:t,widthUnit:n,autoHeight:i,popinPercentHeight:s,popinPixelsHeight:r,heightUnit:o}=DATA;return`width: ${"px"===n?t:e}${n};height: ${i?"auto":`${"px"===o?r:s}${o}`};`};class F extends _{constructor(){super(),this.translateValues=Object.values(DATA.popinPosition[0]).map(e=>j(e)),this.stringStyles=this.getStyles(),this.styleElement=this.getStyleTag(this.stringStyles)}getStyles(){const{zindex:e,zindexCustom:t,widthUnit:n}=DATA,i="string"!=typeof DATA.overlay&&DATA.overlay;return[`#${this.widgetContainerId} {`,"position: fixed;","top: 0;","left: 0;","width: 100%;","height: 100%;",`z-index: ${"custom"===e?t:e};`,"background: none;","pointer-events: "+(i?"all":"none"),"}",`#${this.widgetContainerId} .${this.overlayClassName} {`,"position: absolute;","z-index: -1;","top: 0;","left: 0;","width: 100%;","height: 100%;","}",`#${this.widgetContainerId} .${this.contentClassName} {`,"position: absolute;",H(),M(),"pointer-events: all","}",`${q()?"":[`#${this.widgetContainerId} .${this.contentClassName} > div {`,"height: 100%;","overflow: auto;","box-sizing: border-box;","}"].join("")}`,`${!q()&&["px","em"].includes(n)?["@media screen and (max-width: 579px) {",`#${this.widgetContainerId} .${this.contentClassName} {`,"max-width: 94vw;","}","}"].join(""):""}`].join("")}}class z extends _{constructor(){super(),this.position="string"==typeof DATA.layout&&"bannerTop"===DATA.layout?"top":"bottom",this.stringStyles=this.getStyles(),this.styleElement=this.getStyleTag(this.stringStyles)}getStyles(){const{zindex:e,zindexCustom:t}=DATA;return[`#${this.widgetContainerId} {`,"position: fixed;",`${this.position}: 0;`,"left: 0;","width: 100%;","height: auto;",`z-index: ${"custom"===e?t:e};`,"background: none;","}",`#${this.widgetContainerId} .${this.contentClassName} {`,"position: relative;","}"].join("")}}class K extends _{constructor(e,t){super(e,t),this.stringStyles=this.getStyles(),this.styleElement=this.getStyleTag(this.stringStyles)}getStyles(){return[`#${this.widgetContainerId} {`,"width: auto;","height: auto;","margin: 0;","padding: 0;","background: none;","}",`#${this.widgetContainerId} .${this.contentClassName} {`,"position: relative;","}"].join("")}}function U(e){return U="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},U(e)}function J(e,t){for(var n=0;n<t.length;n++){var i=t[n];i.enumerable=i.enumerable||!1,i.configurable=!0,"value"in i&&(i.writable=!0),Object.defineProperty(e,G(i.key),i)}}function G(e){var t=function(e){if("object"!=U(e)||!e)return e;var t=e[Symbol.toPrimitive];if(void 0!==t){var n=t.call(e,"string");if("object"!=U(n))return n;throw new TypeError("@@toPrimitive must return a primitive value.")}return String(e)}(e);return"symbol"==U(t)?t:t+""}var Y=function(){function t(e){var n=e.parentContainer;!function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,t),this.parentContainer=n,this.baseClassName="qualitywidget_container",this.className="".concat(this.baseClassName,"_").concat(n.uniqueId),this.contentElement=this.getContentElement()}return n=t,s=[{key:"getVariableText",value:function(){var e=DATA,t=e.textVariables,n=e.date,i=e.time,s=e.datetime,r=e.datetimeTimezone,o=new Date(n),a=new Date(s),c="".concat(o.getDate()),l="".concat(o.getMonth()+1),h="".concat(o.getFullYear()),d="".concat(a.getHours()),u="".concat(a.getMinutes()),g="".concat(a.getDate()),m="".concat(a.getMonth()+1),p="".concat(a.getFullYear()),v="".concat(c.length<2?"0".concat(c):c,"/").concat(l.length<2?"0".concat(l):l,"/").concat(h),f="".concat(d.length<2?"0".concat(d):d,":").concat(u.length<2?"0".concat(u):u),y="".concat(g.length<2?"0".concat(g):g,"/").concat(m.length<2?"0".concat(m):m,"/").concat(p),b=r.raw,w=b.followTheSun,T=b.timezone,E=b.previewTimezone,C=b.timedef,S=C.minute,A=C.hour,x=C.day,k=C.month,P=C.year,I="".concat("".concat(A).length<2?"0".concat(A):A,":").concat("".concat(S).length<2?"0".concat(S):S),N="".concat("".concat(x).length<2?"0".concat(x):x,"/").concat("".concat(k).length<2?"0".concat(k):k,"/").concat(P);return t.replace("!time!",'<code class="time">'.concat(JSON.stringify(i,null,0),"</code>")).replace("!date!",'<span class="date">'.concat(v,"</span>")).replace("!timedate!",'<span class="timedate">'.concat(f,"</span>")).replace("!datetime!",'<span class="datetime">'.concat(y,"</span>")).replace("!timeTimezone!",'<span class="timeTimezone">'.concat(I,"</span>")).replace("!dateTimezone!",'<span class="dateTimezone">'.concat(N,"</span>")).replace("!timezone!",'<span class="timezone">'.concat(w?E:T,"</span>"))}}],(i=[{key:"insertIn",value:function(e,t){return this.setStyles(),e.insertAdjacentElement(t,this.contentElement),this}},{key:"addCloseEvent",value:function(t){var n=this;t&&t.addEventListener("click",function(t){y(t),e()||n.parentContainer.recurrence.setClosingRecurrence(),n.parentContainer.hide(),setTimeout(function(){return n.parentContainer.remove()},1e3)},{capture:!0,passive:!1})}},{key:"addRedirectionEvent",value:function(t){var n=this;!e()&&t&&t.addEventListener("click",function(){var t=DATA,i=t.autoHide,s=t.timeHide;i&&setTimeout(function(){return n.parentContainer.hide()},1e3*s),e()||n.parentContainer.recurrence.setValidationRecurrence()},{capture:!0,passive:!0})}},{key:"getButton",value:function(){var e=DATA,t=e.linkType,n=e.buttonText,i=e.redirectionUrl,s=e.openInNewTab,r=document.createElement("a");return r.ariaLabel=n,r.className="popin_link",r.innerHTML="<span>".concat(n,"</span>"),"button"===t?(r.href=i,r.target=s?"_blank":"_self",this.addRedirectionEvent(r)):(r.href="#",r.dataset.abtastyActionnable="true",this.addCloseEvent(r)),r}},{key:"getContentElement",value:function(){var e=DATA,n=e.isTitle,i=e.isText,s=e.linkType,r=e.buttonText,o=e.iconPicker,a="string"==typeof s&&s.includes("widget")?"a":"div",c=document.createElement(a);if(c.className=this.className,""!==(null==o?void 0:o.src)){var l=document.createElement("img");l.setAttribute("src",o.src),l.setAttribute("alt",o.alt),l.classList.add("iconPicker"),c.appendChild(l)}if("widget"===s){var h=DATA,d=h.redirectionUrl,u=h.openInNewTab;c.href=d,c.target=u?"_blank":"_self",this.addRedirectionEvent(c)}else"widgetClose"===s&&(c.href="#",c.dataset.abtastyActionnable="true",this.addCloseEvent(c));if(n){var g=DATA.title,m=document.createElement("h4");m.textContent=g,c.appendChild(m)}if(i){var p=DATA,v=p.text,f=p.includeVariables,y=document.createElement("p"),b=f?t.getVariableText():v;y.innerHTML=b,c.appendChild(y)}if([s,r].every(function(e){return"string"==typeof e})&&s.includes("button")&&r.length){var w=this.getButton(),T=document.createElement("div");T.className="buttons_container",T.appendChild(w),c.appendChild(T)}return c}},{key:"setStyles",value:function(){var e=this.parentContainer,t=e.styleElement,n=e.widgetContainerId,i=DATA,s=i.textColor,r=i.textAlign,o=i.buttonsAlign,a="#".concat(n," .").concat(this.className),c=void 0!==s?"color: ".concat(s,";"):"",l=void 0!==r?"text-align: ".concat(r,";"):"",h=void 0!==o&&"fill"!==o?"text-align: ".concat(o,";"):"",d=["".concat(a," > * {"),"display: inline-block;","vertical-align: middle;","}","".concat(a," .iconPicker {"),"width: 26px;","height: 26px;","}","".concat(a," h4 {"),"margin-bottom: 24px;","display: inline-block;","width: 100%","}","".concat(a," p {"),"width: 100%;","margin: 0;","white-space: pre-line;",c,l,"}","".concat(a," .buttons_container {"),"display: inline-block;","width: 100%;",h,"}","".concat(a," a {"),"margin-top: 24px;","padding: 6px 16px;","width: ".concat("fill"===o?"100%":"auto",";"),"}","@media screen and (min-width: 1024px) {","}","@media screen and (max-width: 1023px) {","}"].join("");return t.insertAdjacentText("beforeend",d),t}}])&&J(n.prototype,i),s&&J(n,s),Object.defineProperty(n,"prototype",{writable:!1}),n;var n,i,s}();!function(){l("Widget launch");var e=(()=>{const{layout:e}=DATA;let t;switch(e){case"popin":t=new F;break;case"bannerTop":case"bannerBottom":t=new z;break;case"free":t=new K;break;default:t=new _}return t})(),t=e.domElement.querySelector(".".concat(e.contentClassName)),n=new Y({parentContainer:e});e.children=n,n.insertIn(t,"beforeend"),e.init(!0).then(function(t){t.response&&e.show()})}()}();
1
+ (function () {
2
+ 'use strict';
3
+
4
+ const getAccountIdentifier = () => {
5
+ let identifier;
6
+ if (!window.ABTasty && !window.ABTASTY_S) return identifier;
7
+
8
+ if (
9
+ window.ABTASTY_S?.USER?.accountIdentifier?.length
10
+ ) {
11
+ identifier = window.ABTASTY_S.USER.accountIdentifier;
12
+ } else if (
13
+ typeof window.ABTasty?.getAccountSettings === 'function'
14
+ ) {
15
+ identifier = window.ABTasty.getAccountSettings().identifier;
16
+ } else if (window.ABTasty?.accountSettings) {
17
+ identifier = window.ABTasty.accountSettings.identifier;
18
+ }
19
+ return identifier;
20
+ };
21
+
22
+ const isOnEditor = () => Object.prototype.hasOwnProperty.call(top, 'ABTastyEditor');
23
+
24
+ const isOnPreview = () => {
25
+ const previewBarExist = !!document.getElementById('ABTastyPreviewBar');
26
+ const urlContainsPreview = location.href.includes('ab_project=preview');
27
+ return previewBarExist || urlContainsPreview;
28
+ };
29
+
30
+ const getCustomSKU = (code) => {
31
+ return new Function(`try {
32
+ ${code}
33
+ } catch (error) {
34
+ return null;
35
+ }`)();
36
+ };
37
+
38
+ const getSKUWithPath = (path) => getCustomSKU(`return ${path};`);
39
+
40
+ const getSKUWithCustomJS = (code) => getCustomSKU(code);
41
+
42
+ const getEncodedUrl = () => encodeURIComponent(
43
+ DATA.spNoTrim
44
+ ? window.location.href.replace(window.location.origin, "")
45
+ : `${window.location.pathname}`
46
+ );
47
+
48
+ const getProductKey = () => {
49
+ const {
50
+ socialProofContentType,
51
+ productKeyProvider,
52
+ pathToProductKey,
53
+ customJSProductKey,
54
+ productSKU,
55
+ } = DATA;
56
+
57
+ const {
58
+ pathToProductKey: pathToProductKeyFunction,
59
+ customJSProductKey: customJSProductKeyFunction,
60
+ } = typeof DATA_JS !== 'undefined' ? DATA_JS : {};
61
+
62
+ if (socialProofContentType === 2) {
63
+ return {
64
+ productKey: getEncodedUrl(),
65
+ keyType: 'url',
66
+ };
67
+ } else {
68
+ let productKey = null;
69
+ let keyType = 'sku';
70
+ switch (productKeyProvider) {
71
+ case "ABTastyProductKey":
72
+ productKey = window.ABTastyProductKey;
73
+ break;
74
+ case "pathToProductKey":
75
+ productKey = typeof pathToProductKeyFunction === 'function'
76
+ ? pathToProductKeyFunction()
77
+ : getSKUWithPath(pathToProductKey);
78
+ break;
79
+ case "customJSProductKey":
80
+ productKey =
81
+ typeof customJSProductKeyFunction === 'function'
82
+ ? customJSProductKeyFunction()
83
+ : getSKUWithCustomJS(customJSProductKey);
84
+ break;
85
+ case "productSKU":
86
+ productKey = productSKU;
87
+ break;
88
+ }
89
+ if (!productKey && socialProofContentType === 3) {
90
+ productKey = getEncodedUrl();
91
+ keyType = 'url';
92
+ }
93
+ return { productKey, keyType };
94
+ }
95
+ };
96
+
97
+ const isAffected = () => !isOnEditor() && (isOnPreview() || !!window.ABTasty.getTestsOnPage()[TEST_ID]);
98
+
99
+ const isInQaMode = () => {
100
+ if (isOnEditor() || isOnPreview()) return false;
101
+ const campaign = ABTasty.getTestsOnPage()[TEST_ID];
102
+ if (campaign) return Object.keys(campaign.targetings.qaParameters).length > 0;
103
+ return false;
104
+ };
105
+
106
+ const isConsentReady = () => window.ABTasty && window.ABTasty.consentReady === true;
107
+
108
+ const getWidgetName = () => {
109
+ const { type } = DATA;
110
+ return `${PACKAGE.replace('@abtasty/', '')}${type ? `_${type}` : ''}`;
111
+ };
112
+
113
+ const getPrettyWidgetName = () => {
114
+ const name = getWidgetName();
115
+ const prettyName = `${name.charAt(0).toUpperCase()}${name.slice(1)}`;
116
+ return prettyName.split('-').join(' ');
117
+ };
118
+
119
+ const getUniqueId = () => `${PLUGIN_ID.split('-')[0]}_${TEST_ID}`;
120
+
121
+ const getRecurrenceParams = () => {
122
+ const { displayRecurrence, closingRecurrence, validationRecurrence } = DATA;
123
+ const noRecurrence = !displayRecurrence && !closingRecurrence && !validationRecurrence;
124
+
125
+ if (isOnEditor() || noRecurrence) return false;
126
+
127
+ const recurrenceGetters = {
128
+ everytime: () => -1,
129
+ session: () => 0,
130
+ once: () => 395,
131
+ day: (key) => DATA[`${key}_day`],
132
+ week: (key) => (DATA[`${key}_week`] * 7),
133
+ month: (key) => (DATA[`${key}_month`] * 30.5),
134
+ };
135
+
136
+ const recurrenceParams = {};
137
+
138
+ if (displayRecurrence) recurrenceParams.displayRecurrence = recurrenceGetters[displayRecurrence]('displayRecurrence');
139
+
140
+ if (closingRecurrence) recurrenceParams.closingRecurrence = recurrenceGetters[closingRecurrence]('closingRecurrence');
141
+
142
+ if (validationRecurrence) recurrenceParams.validationRecurrence = recurrenceGetters[validationRecurrence]('validationRecurrence');
143
+
144
+ return recurrenceParams;
145
+ };
146
+
147
+ const getTriggerParams = (target) => {
148
+ let { triggerEvent } = DATA;
149
+
150
+ const {
151
+ triggerEventClick,
152
+ triggerEventHover,
153
+ triggerEventReengageDelay,
154
+ socialProofContentType,
155
+ triggerEventElementVisible,
156
+ triggerEventDelay,
157
+ } = DATA;
158
+
159
+ if (isOnEditor() || (!triggerEvent && !socialProofContentType)) return false;
160
+
161
+ const triggerSelectorGetters = {
162
+ click: () => triggerEventClick,
163
+ hover: () => triggerEventHover,
164
+ elementVisible: () => triggerEventElementVisible,
165
+ };
166
+
167
+ const triggerSelector = Object.prototype.hasOwnProperty.call(triggerSelectorGetters, triggerEvent)
168
+ ? triggerSelectorGetters[triggerEvent]()
169
+ : 'body';
170
+
171
+ const triggerDelay = triggerEvent === 'reengage' ? triggerEventReengageDelay : triggerEventDelay;
172
+
173
+ if (socialProofContentType) {
174
+ triggerEvent = [, 'socialProofPurchases', 'socialProofPageViews', 'socialProofVisitors'][socialProofContentType];
175
+ }
176
+
177
+ const triggerParams = { triggerEvent, triggerSelector, triggerDelay, triggerTarget: target };
178
+ return triggerParams;
179
+ };
180
+
181
+ const isTriggerOncePerPage = () => {
182
+ const { isOncePerPageTrigger, triggerEvent } = DATA;
183
+
184
+ if (!triggerEvent) return true;
185
+
186
+ const canBeTriggeredMoreThanOnce = ['click', 'hover', 'scrollUp', 'script'].includes(triggerEvent);
187
+ return canBeTriggeredMoreThanOnce ? isOncePerPageTrigger : true;
188
+ };
189
+
190
+ const isInDebugMode = () => window.document.cookie.includes('abTastyDebug=') || window.abTastyDebug === true;
191
+
192
+ const widgetLog = message => {
193
+ const inQaMode = isInQaMode();
194
+ const inDebugMode = isInDebugMode();
195
+ if (inQaMode || inDebugMode) {
196
+ const widgetName = getPrettyWidgetName();
197
+ window.console.log(
198
+ `%c${widgetName} - ${inQaMode ? 'QA' : 'Debug'} Mode for campaign ${TEST_ID} %c ${message}`,
199
+ `background-color: #D6FF01; color: #3100be; padding: 3px 0 3px 10px; border-radius: 5px 0 0 5px; font-weight: bold;`,
200
+ `background-color: #3100be; color: white; padding: 3px 10px 3px 0; border-radius: 0 5px 5px 0;`
201
+ );
202
+ }
203
+ };
204
+
205
+ const promiseDeferrer = name => {
206
+ const deferred = {
207
+ promise: null,
208
+ resolve: null,
209
+ reject: null,
210
+ name
211
+ };
212
+
213
+ deferred.promise = new Promise((resolve, reject) => {
214
+ deferred.resolve = resolve;
215
+ deferred.reject = reject;
216
+ });
217
+
218
+ return deferred;
219
+ };
220
+
221
+ /**
222
+ *
223
+ * @param {string} selector
224
+ * @param {boolean} all
225
+ * @returns {null | Element | NodeListOf<Element> | Element[]}
226
+ */
227
+ const getElementBySelector = (selector, all) => {
228
+ const defaultReturn = all ? [] : null;
229
+ if (typeof selector !== 'string' || !selector.trim().length)
230
+ return defaultReturn;
231
+
232
+ const [outerSelector, accessMethod, innerSelector] = selector.split('[]').map(s => s.trim());
233
+ const contextSelector = Boolean(innerSelector) ? innerSelector : selector;
234
+
235
+ const rootElement = accessMethod
236
+ ? document.querySelector(outerSelector)?.[accessMethod]
237
+ : document;
238
+
239
+ if (!rootElement) return defaultReturn;
240
+
241
+ return all
242
+ ? [...rootElement.querySelectorAll(contextSelector)]
243
+ : rootElement.querySelector(contextSelector);
244
+ };
245
+
246
+ /**
247
+ *
248
+ * @param {string} selector
249
+ * @returns {Element | null}
250
+ */
251
+ const getElement = (selector) => getElementBySelector(selector, false);
252
+ /**
253
+ *
254
+ * @param {string} selector
255
+ * @returns {Element[]}
256
+ */
257
+ const getElements = (selector) => getElementBySelector(selector, true);
258
+
259
+ const observers = {};
260
+
261
+ const setObserver = (callback, selector) => {
262
+ const observerParams = {
263
+ childList: true,
264
+ subtree: true,
265
+ attributes: true,
266
+ };
267
+
268
+ const clear = () => observer.disconnect();
269
+ const observe = (target) => {
270
+ const defaultObserverTarget = document.querySelector('body') || document.documentElement;
271
+ const currentTarget = target ?? defaultObserverTarget;
272
+ observer.observe(currentTarget, observerParams);
273
+ };
274
+ const observerCallback = () => {
275
+ const element = getElement(selector);
276
+ return element && !clear() && callback(element);
277
+ };
278
+ const observer = observers[selector] ?? new MutationObserver(observerCallback);
279
+ observers[selector] ??= observer;
280
+ return { clear, observe };
281
+ };
282
+
283
+ const fakeReturn = () => {};
284
+
285
+ const watchForNestedElement = (callback, selector) => {
286
+ const [outerSelector, accessMethod] = selector.split('[]').map((s) => s.trim());
287
+ const outerElement = getElement(outerSelector);
288
+ const rootElement = outerElement?.[accessMethod];
289
+
290
+ const { clear: clearObserver, observe: launchObserver } = setObserver(callback, selector);
291
+
292
+ const onIframeLoad = () => {
293
+ const element = getElement(selector);
294
+ return element && !clear() && callback(element);
295
+ };
296
+
297
+ const clear = () => {
298
+ clearObserver();
299
+ outerElement?.removeEventListener('load', onIframeLoad);
300
+ };
301
+
302
+ const observe = () => {
303
+ launchObserver(rootElement);
304
+ if (outerElement?.localName === 'iframe') {
305
+ outerElement.addEventListener('load', onIframeLoad);
306
+ }
307
+ };
308
+
309
+ observe();
310
+ return { selector, clear, observe };
311
+ };
312
+
313
+ const waitForElement = (selector, callback) => {
314
+ const element = getElement(selector);
315
+
316
+ const defaultReturn = {
317
+ selector,
318
+ clear: fakeReturn,
319
+ observe: fakeReturn,
320
+ };
321
+
322
+ if (element) {
323
+ setTimeout(() => callback(element), 0);
324
+ return defaultReturn;
325
+ }
326
+
327
+ if (isOnEditor()) {
328
+ setTimeout(() => waitForElement(selector, callback), 1000);
329
+ return defaultReturn;
330
+ }
331
+
332
+ const isNestedRootTarget = selector.includes('[]');
333
+ if (isNestedRootTarget) return watchForNestedElement(callback, selector);
334
+
335
+ const { clear, observe } = setObserver(callback, selector);
336
+ observe();
337
+ return { selector, clear, observe };
338
+ };
339
+
340
+ function findParent(element, cb) {
341
+ const parentElement = element.parentElement || element.getRootNode().host;
342
+ if (cb(element) || !parentElement) {
343
+ return element;
344
+ }
345
+ return findParent(parentElement, cb);
346
+ }
347
+
348
+ const avoidEventDetection = event => {
349
+ if (isOnEditor()) return;
350
+ event.preventDefault();
351
+ event.stopPropagation();
352
+ event.stopImmediatePropagation();
353
+ };
354
+
355
+ const isTargetValid = (eventTarget, selector) => {
356
+ const userTargets = [...getElements(selector)];
357
+ return userTargets.some(element => {
358
+ const [outerSelector, , innerSelector] = selector.split('[]');
359
+ const closestSelector = innerSelector ?? outerSelector;
360
+ const isTarget = element === eventTarget || !!eventTarget.closest(closestSelector);
361
+ return isTarget;
362
+ });
363
+ };
364
+
365
+ let throttleInProgress = false;
366
+ const throttle = (fn, delay) => {
367
+ return () => {
368
+ if (throttleInProgress) return;
369
+ throttleInProgress = true;
370
+ setTimeout(() => {
371
+ fn();
372
+ throttleInProgress = false;
373
+ }, delay);
374
+ }
375
+ };
376
+
377
+ // VisibilityTrigger
378
+
379
+
380
+ class VisibilityObserver {
381
+ constructor() {
382
+ // step 1. targets we want to watch:
383
+ this.targets = [];
384
+ // step 2. targets that exist in the DOM:
385
+ this.existingTargets = [];
386
+ // step 3. targets that are in the viewport:
387
+ this.inViewportTargets = [];
388
+
389
+ this.visibilityObserver = null;
390
+ this.mutationObserver = null;
391
+ this.mouseOverEvent = null;
392
+ this.scrollEvent = null;
393
+ this.onTransitionEnd = null;
394
+ this.onIframeLoad = null;
395
+ }
396
+
397
+ transitionOverHandler(root) {
398
+ const listenerParams = [
399
+ root,
400
+ 'transitionend',
401
+ this.checkElements.bind(this),
402
+ true
403
+ ];
404
+ return this.getEvents(...listenerParams);
405
+ }
406
+
407
+ intersectionHandler(entries) {
408
+ entries.forEach(entry => {
409
+ if (entry.isIntersecting) {
410
+ this.existingTargets.forEach(target => {
411
+ if (target.element.isSameNode(entry.target)) {
412
+ this.inViewportTargets.push(target);
413
+ this.mouseOverEvent.start();
414
+ this.scrollEvent.start();
415
+ this.onTransitionEnd.start();
416
+ }
417
+ });
418
+ this.checkElements();
419
+ } else {
420
+ this.inViewportTargets = this.inViewportTargets.filter(target => {
421
+ if (target.element.isSameNode(entry.target)) {
422
+ this.mouseOverEvent.clear();
423
+ this.scrollEvent.clear();
424
+ this.onTransitionEnd.clear();
425
+ return false;
426
+ }
427
+ return true;
428
+ });
429
+ }
430
+ });
431
+ }
432
+
433
+ startVisibilityObserver(rootElement) {
434
+ const options = {
435
+ root: rootElement,
436
+ rootMargin: '0px',
437
+ threshold: 0.01
438
+ };
439
+ this.visibilityObserver ??= new IntersectionObserver(this.intersectionHandler.bind(this), options);
440
+ return this.visibilityObserver;
441
+ }
442
+
443
+ startMutationObserver(rootElement) {
444
+ this.mutationObserver ??= new MutationObserver(this.checkElements.bind(this));
445
+ this.mutationObserver.observe(rootElement, {
446
+ attributes: true,
447
+ childList: true,
448
+ subtree: true,
449
+ });
450
+ return this.mutationObserver;
451
+ }
452
+
453
+ onMouseOver({ target: eventTarget, path }) {
454
+ const inViewportEventTarget = this.inViewportTargets.find(({ element, selector }) => {
455
+ if (element.isSameNode(eventTarget)) {
456
+ // Check if the target is the viewport element we're looking for (cover case for css "eventTarget:hover")
457
+ return true;
458
+ }
459
+
460
+ const [outerSelector, , innerSelector] = selector.split('[]');
461
+ const toTestSelector = innerSelector ?? outerSelector;
462
+
463
+ // Find matching children of event target (cover case for css "eventTarget:hover *")
464
+ const eventTargetMatchingChildren = [...eventTarget.querySelectorAll(toTestSelector)];
465
+ if (eventTargetMatchingChildren.length) {
466
+ // Check if one matching children of event target is the viewport element we're looking for
467
+ const visibleTargetElementIsChild = eventTargetMatchingChildren.includes(element);
468
+ if (visibleTargetElementIsChild) return true;
469
+ }
470
+
471
+ if (path.includes(element)) {
472
+ // (cover case for css "eventTarget:hover *")
473
+ // Check if one parent of event target is the viewport element we're looking for
474
+ return true;
475
+ }
476
+
477
+ // (cover case for css "eventTarget:hover ~ *")
478
+ if (!eventTarget.parentElement?.children?.length) return;
479
+
480
+ const eventTargetParentChildren = [...eventTarget.parentElement.children];
481
+ const eventTargetIndex = eventTargetParentChildren.findIndex(child =>
482
+ child.isSameNode(eventTarget)
483
+ );
484
+ const eventTargetNextBrothers = eventTargetParentChildren.filter(
485
+ (children, index) => index > eventTargetIndex
486
+ );
487
+
488
+ if (eventTargetNextBrothers.length) {
489
+ // Check if one of the following event target brother is the viewport element we're looking for
490
+ const visibleTargetElementIsBrother = eventTargetNextBrothers.includes(element);
491
+ if (visibleTargetElementIsBrother) return true;
492
+ // Check if one of the following event target brother children is the viewport element we're looking for
493
+ const visibleTargetElementIsBrotherChildren = eventTargetNextBrothers.some(brother =>
494
+ [...brother.querySelectorAll(toTestSelector)].includes(element)
495
+ );
496
+ if (visibleTargetElementIsBrotherChildren) return true;
497
+ }
498
+
499
+ return false;
500
+ });
501
+
502
+ if (inViewportEventTarget && this.isElementVisible(inViewportEventTarget.element)) {
503
+ const { selector, element, uniqueId } = inViewportEventTarget;
504
+ const currentTarget = this.targets.find(
505
+ target => target.selector === selector && target.uniqueId === uniqueId
506
+ );
507
+ if (currentTarget) currentTarget.resolve(element);
508
+ this.clear(selector, uniqueId);
509
+ }
510
+ }
511
+
512
+ getEvents(root, ...listenerParams) {
513
+ const start = () => root?.addEventListener(...listenerParams);
514
+ const clear = () => root?.removeEventListener(...listenerParams);
515
+ return { start, clear };
516
+ }
517
+
518
+ mouseOverHandler(root) {
519
+ const isTouchDevice = 'ontouchstart' in window || navigator.maxTouchPoints > 0 || navigator.msMaxTouchPoints > 0;
520
+ const eventType = isTouchDevice ? 'touchmove' : 'mouseover';
521
+
522
+ const listenerParams = [
523
+ root,
524
+ eventType,
525
+ event => {
526
+ const path = event.composedPath();
527
+ const { target } = event;
528
+ setTimeout(() => this.onMouseOver({ target, path }), 50);
529
+ },
530
+ true
531
+ ];
532
+ return this.getEvents(...listenerParams);
533
+ }
534
+
535
+ scrollEventHandler(root) {
536
+ const listenerParams = [
537
+ root,
538
+ 'scroll',
539
+ throttle(this.checkElements.bind(this), 100),
540
+ { passive: true },
541
+ ];
542
+ return this.getEvents(...listenerParams);
543
+ }
544
+
545
+ isElementVisible(element) {
546
+ return this.isElementOpaque(element) && this.isElementTopmost(element);
547
+ }
548
+
549
+ isElementOpaque(element) {
550
+ const transparencyRoot = findParent(
551
+ element,
552
+ elem => window.getComputedStyle(elem).opacity === '0'
553
+ );
554
+ return transparencyRoot.nodeName === 'HTML';
555
+ }
556
+
557
+ isElementTopmost(element) {
558
+ const elementCorners = element.getBoundingClientRect();
559
+ const corners = [
560
+ [elementCorners.left, elementCorners.top],
561
+ [elementCorners.right, elementCorners.top],
562
+ [elementCorners.left, elementCorners.bottom],
563
+ [elementCorners.right, elementCorners.bottom],
564
+ [elementCorners.left + elementCorners.width / 2, elementCorners.top],
565
+ [elementCorners.left + elementCorners.width / 2, elementCorners.bottom],
566
+ [elementCorners.left, elementCorners.height / 2],
567
+ [elementCorners.right, elementCorners.height / 2],
568
+ [elementCorners.left + elementCorners.left / 2, elementCorners.height / 2]
569
+ ];
570
+ let istopmost = false;
571
+ let i = 0;
572
+ while (!istopmost && i < corners.length) {
573
+ const topmostelem = element.getRootNode()?.elementFromPoint(...corners[i]);
574
+ istopmost =
575
+ element === topmostelem ||
576
+ topmostelem?.contains(element) ||
577
+ element.contains(topmostelem);
578
+ i += 1;
579
+ }
580
+ return istopmost;
581
+ }
582
+
583
+ checkElements() {
584
+ this.targets.forEach(({ selector, uniqueId }) => {
585
+ const element = getElement(selector);
586
+
587
+ const [outerSelector, , innerSelector] = selector.split('[]');
588
+ const toMatchSelector = innerSelector ?? outerSelector;
589
+
590
+ if (
591
+ element &&
592
+ !this.existingTargets.find(
593
+ existingTarget =>
594
+ existingTarget.element.matches(toMatchSelector) && existingTarget.uniqueId === uniqueId
595
+ )
596
+ ) {
597
+ this.existingTargets.push({ element, selector, uniqueId });
598
+ this.visibilityObserver.observe(element);
599
+ }
600
+ });
601
+
602
+ this.existingTargets = this.existingTargets.filter(({ selector, element }) => {
603
+ if (getElement(selector) && element.isConnected) return true;
604
+
605
+ if (element) this.visibilityObserver.unobserve(element);
606
+ return false;
607
+ });
608
+
609
+ this.inViewportTargets = this.inViewportTargets.filter(({ selector, element, uniqueId }) => {
610
+ const [outerSelector, , innerSelector] = selector.split('[]');
611
+ const toMatchSelector = innerSelector ?? outerSelector;
612
+ const elementMatchesSelector = element.matches(toMatchSelector);
613
+ const elementIsVisible = elementMatchesSelector && this.isElementVisible(element);
614
+ if (elementIsVisible) {
615
+ const currentTarget = this.targets.find(
616
+ target => target.selector === selector && target.uniqueId === uniqueId
617
+ );
618
+ if (currentTarget) currentTarget.resolve(element);
619
+ this.clear(selector, uniqueId);
620
+ return false;
621
+ }
622
+ return true;
623
+ });
624
+ }
625
+
626
+ onLoadIframe(root) {
627
+ const listenerParams = [
628
+ root.defaultView.frameElement,
629
+ 'load',
630
+ () => this.watch(selector, resolve, uniqueId).bind(this),
631
+ { passive: true },
632
+ ];
633
+ return this.getEvents(...listenerParams);
634
+ }
635
+
636
+ watch(selector, resolve, uniqueId) {
637
+ this.targets.push({ selector, resolve, uniqueId });
638
+ const { clear } = waitForElement(selector, (target) => {
639
+ clear();
640
+ const rootNode = target.getRootNode({ composed: true });
641
+ const rootElement = 'body' in rootNode ? rootNode.body : document;
642
+
643
+ this.mouseOverEvent = this.mouseOverHandler(rootNode);
644
+ this.scrollEvent = this.scrollEventHandler(rootNode);
645
+ this.onTransitionEnd = this.transitionOverHandler(rootNode);
646
+
647
+ if (rootNode.defaultView?.frameElement) {
648
+ this.onIframeLoad = this.onLoadIframe(rootNode);
649
+ this.onIframeLoad.start();
650
+ }
651
+
652
+ this.startVisibilityObserver(rootNode);
653
+ this.startMutationObserver(rootElement);
654
+ this.checkElements();
655
+ });
656
+ }
657
+
658
+ clear(toClearSelector, id) {
659
+ [this.targets, this.existingTargets, this.inViewportTargets] = [
660
+ this.targets,
661
+ this.existingTargets,
662
+ this.inViewportTargets
663
+ ].map(targetsList =>
664
+ targetsList.filter(
665
+ ({ selector, uniqueId }) => selector !== toClearSelector && uniqueId !== id
666
+ )
667
+ );
668
+
669
+ const clearElement = getElement(toClearSelector);
670
+
671
+ if (clearElement) this.visibilityObserver?.unobserve(clearElement);
672
+
673
+ if (this.targets.length === 0) {
674
+ this.mutationObserver?.disconnect();
675
+ this.onIframeLoad?.clear();
676
+ }
677
+ if (this.inViewportTargets.length === 0) {
678
+ this.mouseOverEvent?.clear();
679
+ this.scrollEvent?.clear();
680
+ this.onTransitionEnd?.clear();
681
+ }
682
+ }
683
+ }
684
+
685
+ // Categories
686
+ const TAG_RESET_EVENT = 'abtasty_resetActionTracking';
687
+ const TAG_CAMPAIGN_LAUNCHED_EVENT = 'abtasty_executedCampaign';
688
+
689
+ // PAGE WATCHER ACTIONS
690
+ const REMOVE_WIDGET = 'remove';
691
+ const REBUILD_WIDGET = 'rebuild';
692
+ const UPDATE_WIDGET = 'update';
693
+
694
+ // COLORS
695
+ const WHITE = 'rgba(255, 255, 255, 1)'; // #FFF
696
+ const DARK_GRAY = 'rgba(57, 57, 57, 1)'; // #393939
697
+
698
+ const SOCIAL_PROOF_API_BASE = 'https://api-social-proof.abtasty.com/clients/';
699
+
700
+ const abtastyDataStorageName = 'ABTastyData';
701
+
702
+ class Trigger {
703
+ constructor({ triggerEvent, triggerSelector, triggerDelay, triggerTarget }) {
704
+ this.event = triggerEvent;
705
+ this.selector = Boolean(triggerSelector) ? triggerSelector : 'body';
706
+ this.target = typeof triggerTarget === 'string' ? getElement(triggerSelector) : triggerTarget;
707
+ this.delay = triggerDelay * 1000;
708
+ this.triggerElements = []; // [Element, Element]
709
+ this.eventsListeners =
710
+ []; /* [['event1', callback, params], [element, 'event2', callback, params]]
711
+ It can have 3 or 4 items depending on target is document or not
712
+ No given element means target is document */
713
+ this.timeouts = []; // [timeout1, timeout2]
714
+ this.intervals = []; // [interval1, interval2]
715
+ this.promises = []; // [promise1, promise2]
716
+ this.visibilityObservers = []; // [visibilityObserver1, visibilityObserver2]
717
+ this.socialProofStore = {};
718
+ this.elementWaiters = [];
719
+ }
720
+
721
+ async onElementVisible({ promise, resolve }) {
722
+ const defferedPromise = promiseDeferrer(`${this.event}DomReady`);
723
+ this.promises.push(defferedPromise);
724
+
725
+ const { clear } = waitForElement(this.selector, () => {
726
+ const visibilityObserver = new VisibilityObserver();
727
+ this.visibilityObservers.push(visibilityObserver);
728
+ visibilityObserver.watch(this.selector, resolve, getUniqueId());
729
+ });
730
+
731
+ this.elementWaiters.push(clear);
732
+ return promise;
733
+ }
734
+
735
+ onPageLoad({ promise, resolve }) {
736
+ const isDomLoadComplete = () => document.readyState === 'complete';
737
+
738
+ if (!isDomLoadComplete()) {
739
+ const onDomStateChange = () => isDomLoadComplete() && resolve(true);
740
+ const listenerParams = ['readystatechange', onDomStateChange, { passive: true }];
741
+
742
+ this.eventsListeners.push([document, ...listenerParams]);
743
+ document.addEventListener(...listenerParams);
744
+ return promise;
745
+ }
746
+
747
+ resolve(true);
748
+ return promise;
749
+ }
750
+
751
+ onClick({ promise, resolve }) {
752
+ const onClickTarget = ({ isTrusted, target }) => {
753
+ if (!isTrusted) return;
754
+ const targetValid = target.isEqualNode(this.target) || isTargetValid(target, this.selector);
755
+ return targetValid && resolve(true);
756
+ };
757
+
758
+ const { clear } = waitForElement(this.selector, (target) => {
759
+ clear();
760
+ const styleElement = document.createElement('style');
761
+ styleElement.id = `Click_${getUniqueId()}`;
762
+ const [outerSelector, , innerSelector] = this.selector.split('[]');
763
+ const modificationSelector = innerSelector ?? outerSelector;
764
+ styleElement.innerHTML = `${modificationSelector} {
765
+ cursor: pointer !important;
766
+ pointer-events: all !important;
767
+ }`;
768
+
769
+ const rootElement = target.getRootNode();
770
+ const stylesTarget = 'head' in rootElement ? rootElement.head : rootElement;
771
+
772
+ stylesTarget.appendChild(styleElement);
773
+ this.triggerElements.push(styleElement);
774
+
775
+ const listenerParams = ['click', onClickTarget, { passive: true, capture: true }];
776
+ this.eventsListeners.push([rootElement, ...listenerParams]);
777
+ rootElement.addEventListener(...listenerParams);
778
+ });
779
+
780
+ this.elementWaiters.push(clear);
781
+
782
+ return promise;
783
+ }
784
+
785
+ onHover({ promise, resolve }) {
786
+ const onHoverTarget = ({ isTrusted, target }) => {
787
+ if (!isTrusted) return;
788
+ const targetValid = this.target ? target.isEqualNode(this.target) : isTargetValid(target, this.selector);
789
+ return targetValid && resolve(true);
790
+ };
791
+
792
+ const { clear } = waitForElement(this.selector, (target) => {
793
+ const rootElement = target.getRootNode();
794
+ const eventTarget =
795
+ 'body' in rootElement
796
+ ? rootElement.body
797
+ : [...rootElement.childNodes].find((child) => child.contains(target));
798
+ const listenerParams = ['mouseenter', onHoverTarget, { passive: true, capture: true }];
799
+ this.eventsListeners.push([eventTarget, ...listenerParams]);
800
+ eventTarget.addEventListener(...listenerParams);
801
+ });
802
+
803
+ this.elementWaiters.push(clear);
804
+
805
+ return promise;
806
+ }
807
+
808
+ onExitIntent({ promise, resolve }) {
809
+ const onMouseLeave = ({ isTrusted, clientY }) => {
810
+ if (isTrusted && clientY <= 0) resolve(true);
811
+ };
812
+
813
+ const listenerParams = ['mouseleave', onMouseLeave, { passive: true }];
814
+ const { clear } = waitForElement('html', (documentElement) => {
815
+ clear();
816
+ this.eventsListeners.push([documentElement, ...listenerParams]);
817
+ documentElement.addEventListener(...listenerParams);
818
+ });
819
+ return promise;
820
+ }
821
+
822
+ onReengage({ promise, resolve }) {
823
+ const originalTimer = this.delay;
824
+ let timer = originalTimer;
825
+ const onUserActivity = ({ isTrusted }) => {
826
+ if (isTrusted) timer = originalTimer;
827
+ };
828
+
829
+ const trackActivityTargets = [...document.querySelectorAll('*:empty')]
830
+ .map((element) => element.contentDocument || element.shadowRoot)
831
+ .filter((element) => element);
832
+ const eventsType = ['click', 'mousemove', 'scroll', 'keypress'];
833
+ const listenerParams = [onUserActivity, { passive: true }];
834
+ eventsType.forEach((event) => {
835
+ [document, ...trackActivityTargets].forEach(rootElement => {
836
+ this.eventsListeners.push([rootElement, event, ...listenerParams]);
837
+ rootElement.addEventListener(event, ...listenerParams);
838
+ });
839
+ });
840
+
841
+ const interval = setInterval(() => {
842
+ if (timer <= 0) {
843
+ resolve(true);
844
+ } else {
845
+ timer -= 100;
846
+ }
847
+ }, 100);
848
+ this.intervals.push(interval);
849
+
850
+ return promise;
851
+ }
852
+
853
+ onCustomTrigger({ promise, resolve }) {
854
+ const { triggerEventCustomScript } = DATA;
855
+ const triggerEventCustomScriptFunction =
856
+ typeof DATA_JS !== 'undefined' && DATA_JS?.triggerEventCustomScript;
857
+ /* eslint-disable no-new-func */
858
+ const customFunction =
859
+ typeof triggerEventCustomScriptFunction === 'function'
860
+ ? () =>
861
+ new Promise((resolve) => triggerEventCustomScriptFunction(resolve))
862
+ : new Function(
863
+ `return new Promise(async resolve => {${triggerEventCustomScript}})`
864
+ );
865
+ /* eslint-enable no-new-func */
866
+ customFunction().then((response) => response && resolve(true));
867
+ return promise;
868
+ }
869
+
870
+ onScrollUp({ promise, resolve }) {
871
+ let scrollPosition = 0;
872
+ const onScroll = ({ isTrusted }) => {
873
+ if (!isTrusted) return;
874
+ if (window.scrollY < scrollPosition) resolve(true);
875
+ else scrollPosition = window.scrollY;
876
+ };
877
+ const listenerParams = ['scroll', onScroll, { passive: true, capture: true }];
878
+ this.eventsListeners.push([document, ...listenerParams]);
879
+ document.addEventListener(...listenerParams);
880
+ return promise;
881
+ }
882
+
883
+ onScrollPercentReached({ promise, resolve }) {
884
+ const { triggerEventScrollPercent } = DATA;
885
+
886
+ const getScrollPercent = () => {
887
+ const { documentElement, body } = document;
888
+ const scrollTop = documentElement.scrollTop || body.scrollTop;
889
+ const scrollHeight = documentElement.scrollHeight || body.scrollHeight;
890
+ return Math.trunc((scrollTop / (scrollHeight - documentElement.clientHeight)) * 100, 10);
891
+ };
892
+
893
+ const onScroll = ({ isTrusted }) => {
894
+ if (!isTrusted) return;
895
+ const scrollPercent = getScrollPercent();
896
+ if (triggerEventScrollPercent < scrollPercent) resolve(true);
897
+ };
898
+
899
+ const listenerParams = ['scroll', onScroll, { passive: true, capture: true }];
900
+ this.eventsListeners.push([document, ...listenerParams]);
901
+ document.addEventListener(...listenerParams);
902
+ return promise;
903
+ }
904
+
905
+ checkSocialProofConditions(key, urlKey, compareFunction, resolve) {
906
+ const accountId = getAccountIdentifier();
907
+ const { viewInterval, spNoTrim } = DATA;
908
+
909
+ if (this.socialProofStore.hasOwnProperty(key)) {
910
+ if (compareFunction(this.socialProofStore[key])) {
911
+ resolve(`${this.socialProofStore[key][viewInterval]}`);
912
+ } else {
913
+ resolve(false);
914
+ }
915
+ } else if (key && accountId) {
916
+ const url = `${SOCIAL_PROOF_API_BASE}${accountId}/metrics/${urlKey}?key=${key}${
917
+ spNoTrim ? '&noTrim=true' : ''
918
+ }`;
919
+
920
+ const onJsonResponse = (response) => {
921
+ this.socialProofStore[key] = response;
922
+ return resolve(compareFunction(response) ? `${response[viewInterval]}` : false);
923
+ };
924
+
925
+ fetch(url)
926
+ .then((response) => response.ok && response.json())
927
+ .then(onJsonResponse)
928
+ .catch(() => widgetLog('Failed to fetch datas from server.'));
929
+ } else {
930
+ resolve(false);
931
+ }
932
+ };
933
+
934
+ getSocialProofDatas({ promise, resolve }, metric, requiresProductKey = false) {
935
+ const { productKey, keyType } = getProductKey();
936
+ const { viewInterval, triggerSocialProofMinVisitors, triggerSocialProofMinPurchases, triggerSocialProofMinPageViews } = DATA;
937
+
938
+ const metricValue = {
939
+ pv: triggerSocialProofMinPageViews,
940
+ i: triggerSocialProofMinPurchases,
941
+ 'v-pv': triggerSocialProofMinVisitors,
942
+ }[metric];
943
+
944
+ const cannotCheck = [
945
+ typeof viewInterval,
946
+ typeof metricValue,
947
+ ].includes("undefined");
948
+
949
+ if (cannotCheck) resolve(false);
950
+
951
+ const isMetricHigherThanValue = (response) => {
952
+ const metricHigherThanValue =
953
+ typeof response[viewInterval] !== 'undefined' &&
954
+ response[viewInterval] >= metricValue;
955
+
956
+ if (!metricHigherThanValue)
957
+ widgetLog(
958
+ `Widget will not be shown, Social Proof API returned ${response[viewInterval]} while ${metricValue} are required`
959
+ );
960
+
961
+ return metricHigherThanValue;
962
+ };
963
+
964
+ if (requiresProductKey && !productKey) {
965
+ widgetLog(
966
+ `Not able to find ABTastyProductKey, impossible to call the API, read documentation for more informations:
967
+ https://support.abtasty.com/hc/en-us/articles/4710919241628-Widgets-List#h_84c04344-c655-4e5e-b9ab-d26a798ad9b0`
968
+ );
969
+ resolve(false);
970
+ }
971
+
972
+ this.checkSocialProofConditions(productKey, metric === 'v-pv' && keyType === 'sku' ? 'v-i' : metric, isMetricHigherThanValue, resolve);
973
+ return promise;
974
+ }
975
+
976
+ onConsent({ promise, resolve }) {
977
+ if (!isConsentReady()) {
978
+ const onConsentValid = () => resolve(true);
979
+ const listenerParams = ['abtasty_consentValid', onConsentValid];
980
+ this.eventsListeners.push(listenerParams);
981
+ window.addEventListener(...listenerParams);
982
+ return promise;
983
+ }
984
+
985
+ resolve(true);
986
+ return promise;
987
+ }
988
+
989
+ onTrackingSent({ promise, resolve }) {
990
+ const { triggerEventTrackingSent } = DATA;
991
+ let ABTastyData = localStorage.getItem(abtastyDataStorageName);
992
+
993
+ const isActionTrackingSent = () =>
994
+ JSON.parse(ABTastyData)?.ActionTracking?.some(
995
+ ({ name }) => name === triggerEventTrackingSent
996
+ );
997
+
998
+ const onStorage = ({ key, newValue }) => {
999
+ if (key !== abtastyDataStorageName) return;
1000
+ ABTastyData = newValue;
1001
+ if (isActionTrackingSent()) resolve(true);
1002
+ };
1003
+
1004
+ const listenerParams = ['storage', onStorage, { passive: true, capture: true }];
1005
+ const setEvent = () => {
1006
+ this.eventsListeners.push([window, ...listenerParams]);
1007
+ window.addEventListener(...listenerParams);
1008
+ };
1009
+
1010
+ if (!ABTastyData || !isActionTrackingSent()) setEvent();
1011
+ else resolve(true);
1012
+
1013
+ return promise;
1014
+ }
1015
+
1016
+ onMinPagesViewed({ promise, resolve }) {
1017
+ const { triggerEventMinPagesViewed } = DATA;
1018
+ let ABTastyData = localStorage.getItem(abtastyDataStorageName);
1019
+
1020
+ const getNumberOfPagesViewed = () =>
1021
+ ABTastyData ? JSON.parse(ABTastyData)?.VisitedPages?.length : 0;
1022
+
1023
+ const isGoalReached = () => triggerEventMinPagesViewed <= getNumberOfPagesViewed();
1024
+
1025
+ const onStorage = ({ key, newValue }) => {
1026
+ if (key !== abtastyDataStorageName) return;
1027
+ ABTastyData = newValue;
1028
+ if (isGoalReached()) resolve(true);
1029
+ };
1030
+
1031
+ const listenerParams = ['storage', onStorage, { passive: true, capture: true }];
1032
+ const setEvent = () => {
1033
+ this.eventsListeners.push([window, ...listenerParams]);
1034
+ window.addEventListener(...listenerParams);
1035
+ };
1036
+
1037
+ if (!ABTastyData || !isGoalReached()) setEvent();
1038
+ else resolve(true);
1039
+
1040
+ return promise;
1041
+ }
1042
+
1043
+ onRageClick({ promise, resolve }) {
1044
+ const { triggerEventRageClickQuantity, triggerEventRageClickDelay } = DATA;
1045
+ let clicksCount = 0;
1046
+ let countInProgress = false;
1047
+
1048
+ const onClick = ({ isTrusted }) => {
1049
+ if (!isTrusted) return;
1050
+
1051
+ clicksCount += 1;
1052
+
1053
+ if (clicksCount >= triggerEventRageClickQuantity) resolve(true);
1054
+
1055
+ if (!countInProgress) {
1056
+ countInProgress = true;
1057
+ const rageClickTimeout = setTimeout(() => {
1058
+ clicksCount = 0;
1059
+ countInProgress = false;
1060
+ }, triggerEventRageClickDelay);
1061
+ this.timeouts.push(rageClickTimeout);
1062
+ }
1063
+ };
1064
+
1065
+ const listenerParams = ['click', onClick, { passive: true, capture: true }];
1066
+
1067
+ const setRageCLickListener = (target) => {
1068
+ this.eventsListeners.push([target, ...listenerParams]);
1069
+ target.addEventListener(...listenerParams);
1070
+ };
1071
+
1072
+ const { clear } = waitForElement('iframe []contentDocument[] body > *', () => {
1073
+ const iframes = document.getElementsByTagName('iframe');
1074
+ for (const iframe of iframes) {
1075
+ if ('contentDocument' in iframe && 'body' in iframe.contentDocument) {
1076
+ setRageCLickListener(iframe.contentDocument);
1077
+ }
1078
+ const onIframeLoad = () => setRageCLickListener(iframe.contentDocument);
1079
+ iframe.addEventListener('load', onIframeLoad);
1080
+ this.eventsListeners.push([iframe, 'onIframeLoad', onIframeLoad]);
1081
+ }
1082
+ });
1083
+
1084
+ this.elementWaiters.push(clear);
1085
+ setRageCLickListener(document);
1086
+
1087
+ return promise;
1088
+ }
1089
+
1090
+ clear() {
1091
+ this.triggerElements = this.triggerElements.filter((element) => {
1092
+ element.remove();
1093
+ return false;
1094
+ });
1095
+
1096
+ this.eventsListeners = this.eventsListeners.filter((event) => {
1097
+ const [target, ...eventParams] = event;
1098
+ if (target && eventParams.length > 1) target.removeEventListener(...eventParams);
1099
+ return false;
1100
+ });
1101
+
1102
+ this.timeouts = this.timeouts.filter((timeout) => {
1103
+ clearTimeout(timeout);
1104
+ return false;
1105
+ });
1106
+
1107
+ this.intervals = this.intervals.filter((interval) => {
1108
+ clearInterval(interval);
1109
+ return false
1110
+ });
1111
+
1112
+ const uniqueId = getUniqueId();
1113
+ this.visibilityObservers = this.visibilityObservers.filter((visibilityObserver) => {
1114
+ visibilityObserver.clear(this.selector, uniqueId);
1115
+ return false;
1116
+ });
1117
+
1118
+ this.promises = this.promises.filter((promise) => {
1119
+ promise.resolve(false);
1120
+ return false;
1121
+ });
1122
+
1123
+ this.elementWaiters = this.elementWaiters.filter((clearElementWaiter) => {
1124
+ clearElementWaiter();
1125
+ return false;
1126
+ });
1127
+
1128
+ return this;
1129
+ }
1130
+
1131
+ async isTriggered() {
1132
+ this.clear();
1133
+
1134
+ const defferedPromise = promiseDeferrer(this.event);
1135
+ this.promises.push(defferedPromise);
1136
+
1137
+ const triggersLauncher = {
1138
+ consent: () => this.onConsent(defferedPromise),
1139
+ direct: () => true,
1140
+ pageLoad: () => this.onPageLoad(defferedPromise),
1141
+ click: () => this.onClick(defferedPromise),
1142
+ exitIntent: () => this.onExitIntent(defferedPromise),
1143
+ reengage: () => this.onReengage(defferedPromise),
1144
+ elementVisible: () => this.onElementVisible(defferedPromise),
1145
+ script: () => this.onCustomTrigger(defferedPromise),
1146
+ hover: () => this.onHover(defferedPromise),
1147
+ scrollUp: () => this.onScrollUp(defferedPromise),
1148
+ scrollPercent: () => this.onScrollPercentReached(defferedPromise),
1149
+ rageClick: () => this.onRageClick(defferedPromise),
1150
+ minPagesViewed: () => this.onMinPagesViewed(defferedPromise),
1151
+ trackingSent: () => this.onTrackingSent(defferedPromise),
1152
+ socialProofPurchases: () => this.getSocialProofDatas(defferedPromise, 'i', true),
1153
+ socialProofPageViews: () => this.getSocialProofDatas(defferedPromise, 'pv'),
1154
+ socialProofVisitors: () => this.getSocialProofDatas(defferedPromise, 'v-pv'),
1155
+ };
1156
+
1157
+ const eventTrigered = Object.prototype.hasOwnProperty.call(triggersLauncher, this.event)
1158
+ ? await triggersLauncher[this.event]()
1159
+ : true;
1160
+
1161
+ if (eventTrigered) this.clear();
1162
+
1163
+ const waitDelay = async () => {
1164
+ const defferedDelayPromise = promiseDeferrer(`${this.event}Delay`);
1165
+ this.promises.push(defferedDelayPromise);
1166
+ const delayTimeout = setTimeout(() => {
1167
+ defferedDelayPromise.resolve(true);
1168
+ this.clear();
1169
+ }, this.delay);
1170
+ this.timeouts.push(delayTimeout);
1171
+ return defferedDelayPromise.promise;
1172
+ };
1173
+
1174
+ const isTrigger =
1175
+ this.event !== 'reengage' && this.delay
1176
+ ? eventTrigered && (await waitDelay())
1177
+ : eventTrigered;
1178
+ return isTrigger;
1179
+ }
1180
+ }
1181
+
1182
+ const DISPLAY = 'display';
1183
+ const CLOSING = 'closing';
1184
+ const VALIDATION = 'validation';
1185
+ const WIDGETS_STORAGE = 'ABTastyWidgets';
1186
+ const TEMPORARY_STORAGE = `${WIDGETS_STORAGE}Temporary`;
1187
+
1188
+ class Recurrence {
1189
+ constructor({ displayRecurrence, closingRecurrence, validationRecurrence }, onSetCallback) {
1190
+ this.displayRecurrence = parseFloat(displayRecurrence);
1191
+ this.closingRecurrence = parseFloat(closingRecurrence);
1192
+ this.validationRecurrence = parseFloat(validationRecurrence);
1193
+ this.onSetCallback = onSetCallback;
1194
+ this.widgetName = getWidgetName();
1195
+ this.uniqueId = getUniqueId();
1196
+ this.recurrenceKey = `${this.widgetName}_${this.uniqueId}`;
1197
+ this.isListeningStorageEvent = this.listenStorageEvent();
1198
+ this.pendingRecurrence = false;
1199
+ this.pendingRecurrenceValue = {};
1200
+ }
1201
+
1202
+ onStorage({ key }) {
1203
+ const temporaryStorage = localStorage.getItem(TEMPORARY_STORAGE);
1204
+ const sessionStoredRecurrence = sessionStorage.getItem(WIDGETS_STORAGE);
1205
+
1206
+ if (key === 'ABTastyData' && !temporaryStorage && sessionStoredRecurrence)
1207
+ localStorage.setItem(TEMPORARY_STORAGE, sessionStoredRecurrence);
1208
+ }
1209
+
1210
+ listenStorageEvent() {
1211
+ if (!this.isListeningStorageEvent)
1212
+ window.addEventListener('storage', this.onStorage.bind(this));
1213
+ return true;
1214
+ }
1215
+
1216
+ getGivenRecurrenceStorageParsed(storageType) {
1217
+ try {
1218
+ const storage = storageType.getItem(WIDGETS_STORAGE);
1219
+ return JSON.parse(storage);
1220
+ } catch (error) {
1221
+ storageType.removeItem(WIDGETS_STORAGE);
1222
+ return false;
1223
+ }
1224
+ }
1225
+
1226
+ getSessionRecurrenceStorageParsed() {
1227
+ return this.getGivenRecurrenceStorageParsed(window.sessionStorage);
1228
+ }
1229
+
1230
+ getLocalRecurrenceStorageParsed() {
1231
+ return this.getGivenRecurrenceStorageParsed(window.localStorage);
1232
+ }
1233
+
1234
+ removeGivenStorage(storageType, currentParsedStorage) {
1235
+ const { [this.recurrenceKey]: removedStorage, ...newStorage } = currentParsedStorage;
1236
+
1237
+ if (!Object.entries(newStorage).length) {
1238
+ storageType.removeItem(WIDGETS_STORAGE);
1239
+ return false;
1240
+ }
1241
+
1242
+ storageType.setItem(WIDGETS_STORAGE, JSON.stringify(newStorage));
1243
+ return newStorage;
1244
+ }
1245
+
1246
+ removeSessionRecurrenceStorage() {
1247
+ const sessionWidgetsRecurrence = this.getSessionRecurrenceStorageParsed();
1248
+ if (!sessionWidgetsRecurrence) return false;
1249
+ return this.removeGivenStorage(window.sessionStorage, sessionWidgetsRecurrence);
1250
+ }
1251
+
1252
+ removeLocalRecurrenceStorage() {
1253
+ const localWidgetsRecurrence = this.getLocalRecurrenceStorageParsed();
1254
+ if (!localWidgetsRecurrence) return false;
1255
+ return this.removeGivenStorage(window.localStorage, localWidgetsRecurrence);
1256
+ }
1257
+
1258
+ getSessionRecurrence() {
1259
+ const sessionRecurrence = this.getSessionRecurrenceStorageParsed();
1260
+ return !!sessionRecurrence && sessionRecurrence[this.recurrenceKey];
1261
+ }
1262
+
1263
+ getLocalRecurrence() {
1264
+ const localRecurrence = this.getLocalRecurrenceStorageParsed();
1265
+ return !!localRecurrence && localRecurrence[this.recurrenceKey];
1266
+ }
1267
+
1268
+ getCurrentRecurrence() {
1269
+ if (this.pendingRecurrence) return this.pendingRecurrenceValue;
1270
+
1271
+ const sessionRecurrence = this.getSessionRecurrence();
1272
+ const localRecurrence = this.getLocalRecurrence();
1273
+ return sessionRecurrence || localRecurrence || { type: false };
1274
+ }
1275
+
1276
+ isOver() {
1277
+ const temporaryStorage = localStorage.getItem(TEMPORARY_STORAGE);
1278
+ const sessionRecurrence =
1279
+ temporaryStorage && temporaryStorage.includes(this.recurrenceKey)
1280
+ ? true
1281
+ : this.getSessionRecurrence();
1282
+
1283
+ if (temporaryStorage) {
1284
+ sessionStorage.setItem(WIDGETS_STORAGE, temporaryStorage);
1285
+ localStorage.removeItem(TEMPORARY_STORAGE);
1286
+ }
1287
+
1288
+ const localRecurrence = this.getLocalRecurrence();
1289
+ const localRecurrenceStamp = localRecurrence ? parseFloat(localRecurrence.stamp) : 0;
1290
+ const now = new Date().getTime();
1291
+ const stampIsDone = localRecurrenceStamp < now;
1292
+
1293
+ if (stampIsDone) {
1294
+ this.removeLocalRecurrenceStorage();
1295
+ }
1296
+
1297
+ return (
1298
+ !this.pendingRecurrence && stampIsDone && !this.getLocalRecurrence() && !sessionRecurrence
1299
+ );
1300
+ }
1301
+
1302
+ setRecurrence(recurrence, type) {
1303
+ if (recurrence !== 0) {
1304
+ window.removeEventListener('storage', this.onStorage.bind(this));
1305
+ this.isListeningStorageEvent = false;
1306
+ }
1307
+
1308
+ const neededStorageInfos = this.getTypeOfStorage(recurrence);
1309
+ if (isOnPreview() || (!neededStorageInfos && typeof neededStorageInfos !== 'object'))
1310
+ return false;
1311
+
1312
+ const { storageString, storageMethod } = neededStorageInfos;
1313
+ const stamp = this.getStamp(recurrence);
1314
+ const storeObject = { type, stamp };
1315
+ const { type: currentType } = this.getCurrentRecurrence();
1316
+
1317
+ const store = async () => {
1318
+ if (!isConsentReady()) {
1319
+ this.pendingRecurrence = true;
1320
+ this.pendingRecurrenceValue = storeObject;
1321
+ const waitForConsent = new Trigger({ triggerEvent: 'consent' });
1322
+ await waitForConsent.isTriggered();
1323
+ this.pendingRecurrence = false;
1324
+ this.pendingRecurrenceValue = {};
1325
+ }
1326
+
1327
+ const sessionRecurrence = this.getSessionRecurrence();
1328
+ const localRecurrence = this.getLocalRecurrence();
1329
+ let storageWithoutCurrent;
1330
+
1331
+ if (storageString === 'session') {
1332
+ if (sessionRecurrence) {
1333
+ storageWithoutCurrent = this.removeSessionRecurrenceStorage();
1334
+ } else {
1335
+ this.removeLocalRecurrenceStorage();
1336
+ storageWithoutCurrent = this.getSessionRecurrenceStorageParsed();
1337
+ }
1338
+ } else if (storageString === 'local') {
1339
+ if (localRecurrence) {
1340
+ storageWithoutCurrent = this.removeLocalRecurrenceStorage();
1341
+ } else {
1342
+ this.removeSessionRecurrenceStorage();
1343
+ storageWithoutCurrent = this.getLocalRecurrenceStorageParsed();
1344
+ }
1345
+ }
1346
+
1347
+ const newStorage = storageWithoutCurrent
1348
+ ? { [this.recurrenceKey]: storeObject, ...storageWithoutCurrent }
1349
+ : { [this.recurrenceKey]: storeObject };
1350
+
1351
+ storageMethod.setItem(WIDGETS_STORAGE, JSON.stringify(newStorage));
1352
+ if (this.onSetCallback && typeof this.onSetCallback === 'function') this.onSetCallback();
1353
+ };
1354
+
1355
+ if (!storageMethod) return false;
1356
+
1357
+ if (!currentType || type === VALIDATION) {
1358
+ store();
1359
+ } else if (type === CLOSING && currentType !== VALIDATION) {
1360
+ store();
1361
+ } else if (type === DISPLAY && currentType !== VALIDATION && currentType !== CLOSING) {
1362
+ store();
1363
+ } else {
1364
+ return false;
1365
+ }
1366
+
1367
+ return stamp;
1368
+ }
1369
+
1370
+ setDisplayRecurrence() {
1371
+ const type = DISPLAY;
1372
+ this.setRecurrence(this.displayRecurrence, type);
1373
+ }
1374
+
1375
+ setClosingRecurrence() {
1376
+ const type = CLOSING;
1377
+ this.setRecurrence(this.closingRecurrence, type);
1378
+ }
1379
+
1380
+ setValidationRecurrence() {
1381
+ const type = VALIDATION;
1382
+ this.setRecurrence(this.validationRecurrence, type);
1383
+ }
1384
+
1385
+ getStamp(recurrence) {
1386
+ const day = 86400000;
1387
+ const now = new Date().getTime();
1388
+ return now + day * recurrence;
1389
+ }
1390
+
1391
+ getTypeOfStorage(recurrence) {
1392
+ if (isNaN(recurrence) || recurrence < 0 || (recurrence !== 0 && !recurrence)) {
1393
+ return false;
1394
+ }
1395
+
1396
+ if (recurrence > 0) {
1397
+ return { storageString: 'local', storageMethod: window.localStorage };
1398
+ }
1399
+ if (recurrence === 0) {
1400
+ return { storageString: 'session', storageMethod: window.sessionStorage };
1401
+ }
1402
+ return false;
1403
+ }
1404
+ }
1405
+
1406
+ /* Params :
1407
+ recurrence : as initiated recurrence
1408
+ isWidgetApplied : as a function that return true or false depending on widget specificities and allow us to callback or not in case all other native actions are true
1409
+ callback : as a function that is called when you need to do any action to your widget / params : as a string 'remove' or 'rebuild'
1410
+ */
1411
+
1412
+ class PageWatcher {
1413
+ constructor(isWidgetApplied, callback, shouldUpdate) {
1414
+ this.isWidgetApplied = isWidgetApplied;
1415
+ this.callback = callback;
1416
+ this.shouldUpdate = shouldUpdate;
1417
+ this.triggerIframeTarget = null;
1418
+ this.observer = new MutationObserver(this.observerHandler.bind(this));
1419
+ this.tagRollbackEventParams = [TAG_RESET_EVENT, this.onTagRollback.bind(this)];
1420
+ this.onCampaignLaunchedEventParams = [TAG_CAMPAIGN_LAUNCHED_EVENT, this.onCampaignLaunched.bind(this)];
1421
+ }
1422
+
1423
+ decisionHandler(event) {
1424
+ const widgetApplied = !event && this.isWidgetApplied();
1425
+ const action = widgetApplied ? this.shouldUpdate && UPDATE_WIDGET : REBUILD_WIDGET;
1426
+ if (!action) return this;
1427
+
1428
+ this.clearWatcher();
1429
+ this.callback(action, !event, widgetApplied);
1430
+ this.watch();
1431
+
1432
+ return this;
1433
+ }
1434
+
1435
+ onCampaignLaunched({ detail: { campaignId } }) {
1436
+ if (campaignId !== TEST_ID) return;
1437
+ this.callback(REBUILD_WIDGET, false);
1438
+ this.watch();
1439
+ }
1440
+
1441
+ onTagRollback({ target }) {
1442
+ this.clearWatcher(target);
1443
+ this.callback(REMOVE_WIDGET, false, true);
1444
+ window.addEventListener(...this.onCampaignLaunchedEventParams);
1445
+ return this;
1446
+ }
1447
+
1448
+ observerHandler(mutations) {
1449
+ if (!isAffected()) return this.callback(REMOVE_WIDGET, false);
1450
+
1451
+ const domChanges = mutations.some(mutation => ['removedNodes', 'addedNodes'].some(prop => mutation[prop] && mutation[prop].length));
1452
+ if (domChanges) return this.decisionHandler();
1453
+
1454
+ return this;
1455
+ }
1456
+
1457
+ watch(rootElement, triggerSelector) {
1458
+ if (isOnEditor()) return this;
1459
+ this.clearWatcher(rootElement);
1460
+
1461
+ window.removeEventListener(...this.onCampaignLaunchedEventParams);
1462
+ document.addEventListener(...this.tagRollbackEventParams);
1463
+
1464
+ if (triggerSelector?.includes('[]contentDocument[]')) {
1465
+ const iframeSelector = triggerSelector.split('[]')[0].trim();
1466
+ const { clear } = waitForElement(iframeSelector, (iframeTargetElement) => {
1467
+ clear();
1468
+ this.triggerIframeTarget = iframeTargetElement;
1469
+ iframeTargetElement.addEventListener('load', this.decisionHandler.bind(this));
1470
+ });
1471
+ }
1472
+
1473
+ const iframeContainer = rootElement?.defaultView?.frameElement;
1474
+ if (iframeContainer && this.triggerIframeTarget !== iframeContainer) {
1475
+ iframeContainer.addEventListener('load', this.decisionHandler.bind(this));
1476
+ }
1477
+
1478
+ const { clear } = waitForElement('body', (body) => {
1479
+ clear();
1480
+ const observerTarget = rootElement?.body || rootElement || body;
1481
+ this.observer.observe(observerTarget, { childList: true, subtree: true });
1482
+ });
1483
+
1484
+ return this;
1485
+ }
1486
+
1487
+ clearTriggerElementWatcher() {
1488
+ this.triggerIframeTarget?.removeEventListener('load', this.decisionHandler.bind(this));
1489
+ }
1490
+
1491
+ clearWatcher(rootElement) {
1492
+ document.removeEventListener(...this.tagRollbackEventParams);
1493
+ this.observer.disconnect();
1494
+ this.clearTriggerElementWatcher();
1495
+ rootElement?.defaultView?.frameElement?.removeEventListener('load', this.decisionHandler.bind(this));
1496
+ return this;
1497
+ }
1498
+ }
1499
+
1500
+ const fontHashRegex = /.+\/([^.]+)\.(otf|ttf)$/;
1501
+ const svgClosingCross = `<svg viewBox="0 0 16 16">
1502
+ <defs><path id="prefix__a" d="M12 4.991L11.009 4 8 7.009 4.991 4 4 4.991 7.009 8 4 11.009 4.991 12 8 8.991 11.009 12 12 11.009 8.991 8z"></path></defs>
1503
+ <g><use xlink:href="#prefix__a"></use></g>
1504
+ </svg>`;
1505
+
1506
+ const shouldUpdateOnPageChange = [
1507
+ 'socialProofPurchases',
1508
+ 'socialProofPageViews',
1509
+ 'socialProofVisitors',
1510
+ ];
1511
+
1512
+ class WidgetContainer {
1513
+ constructor(target, index) {
1514
+ this.children = undefined;
1515
+ this.uniqueId = `${getUniqueId()}${index ? `_${index}` : ''}`;
1516
+ this.widgetName = getWidgetName();
1517
+ this.prettyName = getPrettyWidgetName();
1518
+ this.recurrenceParams = getRecurrenceParams();
1519
+ this.triggerParams = getTriggerParams(target);
1520
+ this.recurrence = this.recurrenceParams
1521
+ ? new Recurrence(
1522
+ this.recurrenceParams,
1523
+ this.clearGivenClearables.bind(this)
1524
+ )
1525
+ : false;
1526
+ this.trigger = this.triggerParams ? new Trigger(this.triggerParams) : false;
1527
+ this.shouldUpdate = this.triggerParams
1528
+ ? shouldUpdateOnPageChange.includes(this.triggerParams.triggerEvent)
1529
+ : false;
1530
+ this.pageWatcher = new PageWatcher(
1531
+ this.isWidgetApplied.bind(this),
1532
+ this.onPageChange.bind(this)
1533
+ );
1534
+ this.hasOncePerPageTrigger = isTriggerOncePerPage();
1535
+ this.basicClassName = `ab_widget_container_${this.widgetName}`;
1536
+ this.widgetContainerId = `${this.basicClassName}_${this.uniqueId}`;
1537
+ this.contentClassName = `${this.basicClassName}_content`;
1538
+ this.overlayClassName = `${this.basicClassName}_overlay`;
1539
+ this.closeButtonClassName = `${this.basicClassName}_close_button`;
1540
+ this.hideClassName = `ab_hide_${this.uniqueId}`;
1541
+
1542
+ this.rootElement = null;
1543
+ this.domElement = this.getDom();
1544
+ this.hasBeenShown = false;
1545
+ this.closedByUser = false;
1546
+ this.websiteFocusedElement = null;
1547
+ this.elementsWaiters = [];
1548
+ }
1549
+
1550
+ clearGivenClearables() {
1551
+ for (const elementWaiter of this.elementsWaiters) {
1552
+ elementWaiter.clear();
1553
+ }
1554
+ this.elementsWaiters = [];
1555
+ }
1556
+
1557
+ isWidgetApplied() {
1558
+ return (
1559
+ this.domElement?.isConnected && this.domElement.ownerDocument?.defaultView
1560
+ );
1561
+ }
1562
+
1563
+ removeOldDomElement() {
1564
+ const oldElement = this.rootElement?.getElementById(this.widgetContainerId);
1565
+ oldElement?.remove();
1566
+ return this;
1567
+ }
1568
+
1569
+ async insert() {
1570
+ if (this.isWidgetApplied()) return false;
1571
+
1572
+ const inElementLayouts = ['free'];
1573
+ if (DATA.layout === 'drawer' && DATA.customTarget)
1574
+ inElementLayouts.push('drawer');
1575
+
1576
+ const widgetHaveTargetLayout = inElementLayouts.includes(DATA.layout);
1577
+
1578
+ const waitForReferrenceElementPromise = new Promise((resolve) => {
1579
+ const { elementReferrer = 'body', referrerInsertType = 'beforeend' } =
1580
+ widgetHaveTargetLayout ? DATA : {};
1581
+
1582
+ const waitForReferrenceElement = waitForElement(
1583
+ elementReferrer,
1584
+ (element) => {
1585
+ this.elementsWaiters = this.elementsWaiters.filter(
1586
+ (waiter) => waiter.selector !== elementReferrer
1587
+ );
1588
+ this.rootElement = element.getRootNode();
1589
+ this.removeOldDomElement();
1590
+ this.domElement.appendChild(this.styleElement);
1591
+ resolve(
1592
+ element.insertAdjacentElement(referrerInsertType, this.domElement)
1593
+ );
1594
+ }
1595
+ );
1596
+ this.elementsWaiters.push(waitForReferrenceElement);
1597
+ });
1598
+
1599
+ return waitForReferrenceElementPromise.then(() => this);
1600
+ }
1601
+
1602
+ remove() {
1603
+ if (this.trigger) this.trigger.clear();
1604
+ this.pageWatcher.clearWatcher(this.rootElement);
1605
+ for (const elementWaiter of this.elementsWaiters) {
1606
+ if (![DATA.elementReferrer, 'body'].includes(elementWaiter.selector))
1607
+ continue;
1608
+ elementWaiter.clear();
1609
+ }
1610
+ this.domElement?.isConnected && this.domElement.remove();
1611
+
1612
+ if (this.hasOncePerPageTrigger) {
1613
+ this.pageWatcher.watch(this.rootElement);
1614
+ } else if (!isOnEditor()) {
1615
+ this.init().then(({ response }) => (response ? this.show() : this));
1616
+ }
1617
+ return this;
1618
+ }
1619
+
1620
+ show() {
1621
+ const { layout, overlay = true } = DATA;
1622
+ if (!isOnEditor() && (!this.hasBeenShown || !this.hasOncePerPageTrigger)) {
1623
+ window.ABTastyEvent(`${this.prettyName} displayed`, null, TEST_ID);
1624
+ }
1625
+ this.closedByUser = false;
1626
+ this.websiteFocusedElement = document.activeElement;
1627
+ setTimeout(() => {
1628
+ this.domElement.classList.remove(this.hideClassName);
1629
+ if (!isOnEditor() && layout === 'popin' && overlay === true) {
1630
+ this.domElement
1631
+ .querySelector('input[type="text"], textarea, a, button')
1632
+ ?.focus();
1633
+ }
1634
+ }, 50);
1635
+ if (this.recurrence) this.recurrence.setDisplayRecurrence();
1636
+ this.hasBeenShown = true;
1637
+ this.pageWatcher.watch(this.rootElement);
1638
+ return this;
1639
+ }
1640
+
1641
+ hide(hideByUser = true) {
1642
+ if (!isOnEditor() && this.hasBeenShown && hideByUser) {
1643
+ window.ABTastyEvent(`${this.prettyName} closed`, null, TEST_ID);
1644
+ }
1645
+ if (hideByUser) {
1646
+ this.pageWatcher.clearWatcher(this.rootElement);
1647
+ this.closedByUser = true;
1648
+ }
1649
+ this.domElement.classList.add(this.hideClassName);
1650
+ if (!isOnEditor() && this.websiteFocusedElement?.isConnected) {
1651
+ this.websiteFocusedElement.focus();
1652
+ }
1653
+ return this;
1654
+ }
1655
+
1656
+ async init(firstInit) {
1657
+ const onEditor = isOnEditor();
1658
+ const affected = isAffected();
1659
+
1660
+ const alreadyAwaitingTrigger = this.trigger?.promises?.length;
1661
+ const recurrenceDone = this.recurrence ? this.recurrence.isOver() : true;
1662
+
1663
+ if ((!onEditor && !affected) || alreadyAwaitingTrigger || !recurrenceDone) {
1664
+ return { container: this, response: false };
1665
+ }
1666
+
1667
+ this.pageWatcher.watch(
1668
+ this.rootElement || document,
1669
+ this.triggerParams.triggerSelector
1670
+ );
1671
+
1672
+ const canLaunch =
1673
+ onEditor ||
1674
+ !this.trigger ||
1675
+ (this.trigger && (await this.trigger.isTriggered()));
1676
+ this.pageWatcher.clearTriggerElementWatcher();
1677
+ const returnValue = { container: this, response: canLaunch };
1678
+
1679
+ if (!canLaunch) return returnValue;
1680
+
1681
+ await this.insert();
1682
+ this.addCloseEvent();
1683
+
1684
+ if (
1685
+ !onEditor &&
1686
+ !firstInit &&
1687
+ !this.hasBeenShown &&
1688
+ typeof this.children !== 'undefined' &&
1689
+ typeof this.children.refreshContent === 'function'
1690
+ ) {
1691
+ this.children.refreshContent(canLaunch);
1692
+ }
1693
+
1694
+ return returnValue;
1695
+ }
1696
+
1697
+ onPageChange(changeType, isDomModif, widgetApplied) {
1698
+ const relaunch = () =>
1699
+ this.init().then(({ response }) => {
1700
+ response ? this.show() : this.hide(false);
1701
+ });
1702
+
1703
+ if (!isDomModif) {
1704
+ this.hasBeenShown = false;
1705
+ if (widgetApplied) this.domElement.remove();
1706
+ if (this.trigger) this.trigger.clear();
1707
+ }
1708
+
1709
+ const cases = {
1710
+ [REMOVE_WIDGET]: () =>
1711
+ widgetApplied
1712
+ ? this.remove()
1713
+ : this.pageWatcher.watch(this.rootElement),
1714
+ [REBUILD_WIDGET]: () => {
1715
+ if (this.hasBeenShown) {
1716
+ if (this.closedByUser) {
1717
+ this.pageWatcher.watch(this.rootElement);
1718
+ } else if (!widgetApplied) {
1719
+ this.insert()
1720
+ .then((self) => self.show())
1721
+ .catch(this.pageWatcher.watch);
1722
+ }
1723
+ } else {
1724
+ relaunch();
1725
+ }
1726
+ },
1727
+ [UPDATE_WIDGET]: () => {
1728
+ if (this.hasBeenShown) {
1729
+ this.pageWatcher.watch();
1730
+ return;
1731
+ }
1732
+ relaunch();
1733
+ },
1734
+ };
1735
+
1736
+ if (typeof cases[changeType] === 'function') cases[changeType]();
1737
+ }
1738
+
1739
+ addCloseEvent(...closeElements) {
1740
+ const {
1741
+ closeButton,
1742
+ overlay,
1743
+ overlayClickable,
1744
+ layout,
1745
+ animationDuration = 1000,
1746
+ } = DATA;
1747
+
1748
+ const closeElementsSelectors = [];
1749
+ if (
1750
+ (typeof overlay === 'undefined' || overlay === true) &&
1751
+ overlayClickable === true &&
1752
+ layout === 'popin'
1753
+ ) {
1754
+ closeElementsSelectors.push(`.${this.overlayClassName}`);
1755
+ }
1756
+ if (typeof closeButton !== 'undefined' && closeButton) {
1757
+ closeElementsSelectors.push(`.${this.closeButtonClassName}`);
1758
+ }
1759
+
1760
+ if (!closeElementsSelectors.length) return this;
1761
+
1762
+ const nativeCloseElements = this.domElement.querySelectorAll(
1763
+ closeElementsSelectors.join(', ')
1764
+ );
1765
+
1766
+ if (!nativeCloseElements.length) return this;
1767
+
1768
+ const onUserClose = (event) => {
1769
+ const isClick = event.type === 'click';
1770
+ const isEscape = event.type === 'keyup' && event.code === 'Escape' && event.isTrusted;
1771
+
1772
+ if (!isClick && !isEscape) return;
1773
+
1774
+ avoidEventDetection(event);
1775
+ if (this.recurrence) this.recurrence.setClosingRecurrence();
1776
+ this.hide(true);
1777
+ setTimeout(() => this.remove(), animationDuration * 1.05);
1778
+ };
1779
+
1780
+ const onCloseParams = [
1781
+ 'click',
1782
+ onUserClose,
1783
+ { once: true, capture: true },
1784
+ ];
1785
+
1786
+ closeElements.push(...nativeCloseElements);
1787
+
1788
+ for (const closeElement of closeElements) {
1789
+ if (isOnEditor()) {
1790
+ // eslint-disable-next-line no-param-reassign
1791
+ closeElement.dataset.abtastyActionnable = 'true';
1792
+ }
1793
+ closeElement.removeEventListener(...onCloseParams);
1794
+ closeElement.addEventListener(...onCloseParams);
1795
+ }
1796
+
1797
+ window.removeEventListener('keyup', onUserClose, { once: true });
1798
+ window.addEventListener('keyup', onUserClose, { once: true });
1799
+ return this;
1800
+ }
1801
+
1802
+ getDom() {
1803
+ const { closeButton, layout, overlayClickable, overlay = true } = DATA;
1804
+ const widgetContainerElement = document.createElement('div');
1805
+ widgetContainerElement.className = `${this.basicClassName} ${this.hideClassName}`;
1806
+ widgetContainerElement.id = this.widgetContainerId;
1807
+
1808
+ if (['popin', 'bannerTop', 'bannerBottom'].includes(layout)){
1809
+ widgetContainerElement.role = 'dialog';
1810
+ if (layout === 'popin' && overlay === true) widgetContainerElement.ariaModal = "true";
1811
+ }
1812
+
1813
+ widgetContainerElement.innerHTML = `
1814
+ ${
1815
+ layout === 'popin' && overlay === true
1816
+ ? `<div ${
1817
+ overlayClickable ? 'aria-label="Close dialog"' : ''
1818
+ } class="${this.overlayClassName}"></div>`
1819
+ : ''
1820
+ }
1821
+ <div class="${this.contentClassName}">
1822
+ ${
1823
+ closeButton
1824
+ ? `<button class="${this.closeButtonClassName}" aria-label="Close dialog">${svgClosingCross}</button>`
1825
+ : ''
1826
+ }
1827
+ </div>`;
1828
+ return widgetContainerElement;
1829
+ }
1830
+
1831
+ loadFont(name, styleSrc) {
1832
+ if (!name || name === 'inherit' || !/otf|ttf/g.test(styleSrc)) return;
1833
+ const newStyle = document.createElement('style');
1834
+ const styleHash = styleSrc.match(fontHashRegex)
1835
+ ? styleSrc.match(fontHashRegex)[1]
1836
+ : '';
1837
+ newStyle.innerHTML = `@font-face { font-family: '${name}_${styleHash}'; src: url('${styleSrc}'); font-display: swap; }`;
1838
+
1839
+ const stylesContainer = this.rootElement?.head || document.head;
1840
+ stylesContainer?.appendChild(newStyle);
1841
+ }
1842
+
1843
+ getStyleTag(uniqueStyles = '', widgetData = DATA) {
1844
+ const { noStyles, layout } = widgetData;
1845
+ const {
1846
+ backgroundColor,
1847
+ isBackgroundImage,
1848
+ backgroundImage,
1849
+ backgroundSize,
1850
+ backgroundPosition,
1851
+ backgroundRepeat,
1852
+ borderColor,
1853
+ borderRadius,
1854
+ borderWidth,
1855
+ textColor,
1856
+ textAlign,
1857
+ fontName,
1858
+ fontStyle,
1859
+ fontSize,
1860
+ isTitle,
1861
+ titleTextAlign,
1862
+ titleTextColor,
1863
+ titleFontName,
1864
+ titleFontStyle,
1865
+ titleFontSize,
1866
+ overlay,
1867
+ overlayColor,
1868
+ dropShadow,
1869
+ dropShadowColor,
1870
+ dropShadowBlur,
1871
+ containerMargin,
1872
+ containerPadding,
1873
+ closeButton,
1874
+ closeButtonPosition,
1875
+ closeButtonSize,
1876
+ closeButtonBorderRadius,
1877
+ closeButtonBorderWidth,
1878
+ closeButtonBorderColor,
1879
+ closeButtonColor,
1880
+ closeButtonBackgroundColor,
1881
+ buttonsAlign,
1882
+ buttonsBorderWidth,
1883
+ buttonsBorderColor,
1884
+ buttonsBorderRadius,
1885
+ buttonsBackgroundColor,
1886
+ buttonsTextColor,
1887
+ buttonsFontName,
1888
+ buttonsFontStyle,
1889
+ buttonsFontSize,
1890
+ secondLink: hasSecondLink,
1891
+ secondLinkBorderWidth,
1892
+ secondLinkBorderColor,
1893
+ secondLinkBorderRadius,
1894
+ secondLinkBackgroundColor,
1895
+ secondLinkTextColor,
1896
+ secondLinkFontName,
1897
+ secondLinkFontStyle,
1898
+ secondLinkFontSize,
1899
+ animation,
1900
+ animationDuration,
1901
+ animationBehaviour,
1902
+ animationSlideDirection,
1903
+ } = noStyles ? {} : widgetData;
1904
+ const styleDomElement = document.createElement('style');
1905
+ if (isOnEditor())
1906
+ styleDomElement.setAttribute('abtasty-script-added', 'true');
1907
+ this.loadFont(fontName, fontStyle);
1908
+ this.loadFont(titleFontName, titleFontStyle);
1909
+ this.loadFont(buttonsFontName, buttonsFontStyle);
1910
+ this.loadFont(secondLinkFontName, secondLinkFontStyle);
1911
+
1912
+ const backgroundProps = [
1913
+ typeof backgroundColor === 'string' ? backgroundColor : WHITE,
1914
+ isBackgroundImage &&
1915
+ typeof backgroundImage === 'string' &&
1916
+ backgroundImage.length
1917
+ ? `url(${backgroundImage})`
1918
+ : '',
1919
+ isBackgroundImage &&
1920
+ typeof backgroundPosition === 'string' &&
1921
+ backgroundSize !== '100% 100%'
1922
+ ? backgroundPosition
1923
+ : '0 0',
1924
+ isBackgroundImage && typeof backgroundSize === 'string'
1925
+ ? `/ ${backgroundSize}`
1926
+ : '/ auto',
1927
+ isBackgroundImage &&
1928
+ backgroundRepeat &&
1929
+ !['cover', '100% 100%'].includes(backgroundSize)
1930
+ ? 'repeat'
1931
+ : 'no-repeat',
1932
+ ];
1933
+ const backgroundStyle = `background: ${backgroundProps.join(' ').trim()};`;
1934
+
1935
+ const isBorderWithMoreThanZero =
1936
+ typeof borderWidth === 'number' && borderWidth > 0;
1937
+ const borderProps = [
1938
+ isBorderWithMoreThanZero ? `${borderWidth}px` : 'unset',
1939
+ isBorderWithMoreThanZero ? `solid` : '',
1940
+ isBorderWithMoreThanZero &&
1941
+ typeof borderColor === 'string' &&
1942
+ borderColor.length
1943
+ ? borderColor
1944
+ : '',
1945
+ ];
1946
+ const borderStyle = `border: ${borderProps.join(' ').trim()};`;
1947
+ const borderRadiusStyle =
1948
+ typeof borderRadius !== 'undefined'
1949
+ ? `border-radius: ${borderRadius}px;`
1950
+ : '';
1951
+
1952
+ const textColorStyle =
1953
+ typeof textColor !== 'undefined'
1954
+ ? `color: ${textColor}; fill: ${textColor}; -webkit-text-fill-color: ${textColor};`
1955
+ : '';
1956
+ const textAlignStyle =
1957
+ typeof textAlign !== 'undefined' ? `text-align: ${textAlign};` : '';
1958
+ const fontNameStyle =
1959
+ fontName && fontName !== 'inherit'
1960
+ ? `font-family:${fontName}_${
1961
+ fontStyle.match(fontHashRegex)
1962
+ ? fontStyle.match(fontHashRegex)[1]
1963
+ : ''
1964
+ };`
1965
+ : fontStyle || '';
1966
+ const fontSizeStyle = fontSize ? `font-size: ${fontSize}px;` : '';
1967
+
1968
+ const dropShadowStyle =
1969
+ typeof dropShadow !== 'undefined' && dropShadow
1970
+ ? `box-shadow: 0 5px ${dropShadowBlur}px 0 ${dropShadowColor};`
1971
+ : '';
1972
+
1973
+ const margin =
1974
+ containerMargin instanceof Array &&
1975
+ containerMargin.length === 1 &&
1976
+ containerMargin[0];
1977
+ const marginsStyle = margin
1978
+ ? `margin: ${margin.top}px ${margin.right}px ${margin.bottom}px ${margin.left}px;`
1979
+ : '';
1980
+ const marginSmallScreens = margin
1981
+ ? `margin: calc(${margin.top}px * 0.5) calc(${margin.right}px * 0.5) calc(${margin.bottom}px * 0.5) calc(${margin.left}px * 0.5);`
1982
+ : '';
1983
+ const padding =
1984
+ containerPadding instanceof Array &&
1985
+ containerPadding.length === 1 &&
1986
+ containerPadding[0];
1987
+ const paddingsStyle = padding
1988
+ ? `padding: ${padding.top}px ${padding.right}px ${padding.bottom}px ${padding.left}px;`
1989
+ : '';
1990
+ const paddingSmallScreens = padding
1991
+ ? `padding: calc(${padding.top}px * 0.5) calc(${padding.right}px * 0.5) calc(${padding.bottom}px * 0.5) calc(${padding.left}px * 0.5);`
1992
+ : '';
1993
+
1994
+ const buttonsBorderWidthStyle =
1995
+ typeof buttonsBorderWidth !== 'undefined' && buttonsBorderWidth
1996
+ ? `border-width: ${buttonsBorderWidth}px; border-style: solid;`
1997
+ : '';
1998
+ const buttonsBorderColorStyle =
1999
+ [buttonsBorderColor, buttonsBorderWidth].every(
2000
+ (prop) => typeof prop !== 'undefined'
2001
+ ) && buttonsBorderWidth
2002
+ ? `border-color: ${buttonsBorderColor};`
2003
+ : '';
2004
+ const buttonsBorderRadiusStyle =
2005
+ typeof buttonsBorderRadius !== 'undefined'
2006
+ ? `border-radius: ${buttonsBorderRadius}px;`
2007
+ : '';
2008
+ const buttonsBackgroundColorStyle =
2009
+ typeof buttonsBackgroundColor !== 'undefined'
2010
+ ? `background-color: ${buttonsBackgroundColor};`
2011
+ : '';
2012
+ const buttonsTextColorStyle =
2013
+ typeof buttonsTextColor !== 'undefined'
2014
+ ? `color: ${buttonsTextColor}; fill: ${buttonsTextColor}; -webkit-text-fill-color: ${buttonsTextColor};`
2015
+ : '';
2016
+ const buttonsFontNameStyle =
2017
+ buttonsFontName && buttonsFontName !== 'inherit'
2018
+ ? `font-family:${buttonsFontName}_${
2019
+ buttonsFontStyle.match(fontHashRegex)
2020
+ ? buttonsFontStyle.match(fontHashRegex)[1]
2021
+ : ''
2022
+ };`
2023
+ : buttonsFontStyle || '';
2024
+ const buttonsFontSizeStyle = buttonsFontSize
2025
+ ? `font-size: ${buttonsFontSize}px;`
2026
+ : '';
2027
+
2028
+ const secondLinkBorderWidthStyle =
2029
+ typeof secondLinkBorderWidth === 'number'
2030
+ ? `border-width: ${secondLinkBorderWidth}px; border-style: solid;`
2031
+ : '';
2032
+ const secondLinkBorderColorStyle =
2033
+ [secondLinkBorderColor, secondLinkBorderWidth].every(
2034
+ (prop) => typeof prop !== 'undefined'
2035
+ ) && secondLinkBorderWidth
2036
+ ? `border-color: ${secondLinkBorderColor};`
2037
+ : '';
2038
+ const secondLinkBorderRadiusStyle =
2039
+ typeof secondLinkBorderRadius !== 'undefined'
2040
+ ? `border-radius: ${secondLinkBorderRadius}px;`
2041
+ : '';
2042
+ const secondLinkBackgroundColorStyle =
2043
+ typeof secondLinkBackgroundColor !== 'undefined'
2044
+ ? `background-color: ${secondLinkBackgroundColor};`
2045
+ : '';
2046
+ const secondLinkTextColorStyle =
2047
+ typeof secondLinkTextColor !== 'undefined'
2048
+ ? `color: ${secondLinkTextColor}; fill: ${secondLinkTextColor}; -webkit-text-fill-color: ${secondLinkTextColor};`
2049
+ : '';
2050
+ const secondLinkFontNameStyle =
2051
+ secondLinkFontName && secondLinkFontName !== 'inherit'
2052
+ ? `font-family:${secondLinkFontName}_${
2053
+ secondLinkFontStyle.match(fontHashRegex)
2054
+ ? secondLinkFontStyle.match(fontHashRegex)[1]
2055
+ : ''
2056
+ };`
2057
+ : secondLinkFontStyle || '';
2058
+ const secondLinkFontSizeStyle = secondLinkFontSize
2059
+ ? `font-size: ${secondLinkFontSize}px;`
2060
+ : '';
2061
+
2062
+ const overlayRules =
2063
+ layout === 'popin' && (typeof overlay === 'undefined' || overlay === true)
2064
+ ? [
2065
+ `#${this.widgetContainerId} .${this.overlayClassName} {`,
2066
+ `background-color: ${
2067
+ typeof overlayColor !== 'undefined'
2068
+ ? overlayColor
2069
+ : 'rgba(0, 0, 0, 0.6)'
2070
+ };`,
2071
+ '}',
2072
+ ].join('')
2073
+ : '';
2074
+
2075
+ const closeButtonSizeNumber =
2076
+ typeof closeButtonSize === 'number' ? closeButtonSize : 16;
2077
+ const halfCloseButtonSize = closeButtonSizeNumber / 2;
2078
+ const closeButtonRules =
2079
+ noStyles || (typeof closeButton !== 'undefined' && closeButton)
2080
+ ? [
2081
+ `#${this.widgetContainerId} .${this.contentClassName} .${this.closeButtonClassName} {`,
2082
+ 'position: absolute;',
2083
+ `${
2084
+ closeButtonPosition === 'out'
2085
+ ? `bottom: calc(100% + ${halfCloseButtonSize}px)`
2086
+ : `top: ${halfCloseButtonSize}px`
2087
+ };`,
2088
+ `right: ${halfCloseButtonSize}px;`,
2089
+ 'width: auto;',
2090
+ 'height: auto;',
2091
+ 'background: none;',
2092
+ 'border: none;',
2093
+ 'cursor: pointer;',
2094
+ 'padding: 0;',
2095
+ 'margin: 0;',
2096
+ 'line-height: 0;',
2097
+ 'z-index: 9;',
2098
+ `${
2099
+ typeof closeButtonBorderRadius === 'number'
2100
+ ? `border-radius: ${closeButtonBorderRadius}px;`
2101
+ : ''
2102
+ }`,
2103
+ `${
2104
+ typeof closeButtonBorderWidth === 'number' &&
2105
+ closeButtonBorderWidth > 0
2106
+ ? `border: ${closeButtonBorderWidth}px solid ${
2107
+ typeof closeButtonBorderColor !== 'undefined'
2108
+ ? closeButtonBorderColor
2109
+ : DARK_GRAY
2110
+ };`
2111
+ : ''
2112
+ }`,
2113
+ `${
2114
+ typeof closeButtonBackgroundColor === 'string'
2115
+ ? `background-color: ${closeButtonBackgroundColor};`
2116
+ : ''
2117
+ }`,
2118
+ '}',
2119
+ `#${this.widgetContainerId} .${this.contentClassName} .${this.closeButtonClassName} svg {`,
2120
+ 'pointer-events: none;',
2121
+ `width: ${closeButtonSizeNumber}px;`,
2122
+ `height: ${closeButtonSizeNumber}px;`,
2123
+ `${
2124
+ typeof closeButtonColor === 'string'
2125
+ ? `fill: ${closeButtonColor};`
2126
+ : ''
2127
+ }`,
2128
+ '}',
2129
+ ].join('')
2130
+ : '';
2131
+
2132
+ const titleRules =
2133
+ isTitle && typeof titleTextColor === 'string'
2134
+ ? [
2135
+ `#${this.widgetContainerId} .${this.contentClassName} > * h1, `,
2136
+ `#${this.widgetContainerId} .${this.contentClassName} > * h2, `,
2137
+ `#${this.widgetContainerId} .${this.contentClassName} > * h3, `,
2138
+ `#${this.widgetContainerId} .${this.contentClassName} > * h4, `,
2139
+ `#${this.widgetContainerId} .${this.contentClassName} > * h5, `,
2140
+ `#${this.widgetContainerId} .${this.contentClassName} > * h6 {`,
2141
+ `color: ${titleTextColor}; fill: ${titleTextColor}; -webkit-text-fill-color: ${titleTextColor};`,
2142
+ typeof titleTextAlign !== 'undefined'
2143
+ ? `text-align: ${titleTextAlign};`
2144
+ : '',
2145
+ titleFontName && titleFontName !== 'inherit'
2146
+ ? `font-family:${titleFontName}_${
2147
+ titleFontStyle.match(fontHashRegex)
2148
+ ? titleFontStyle.match(fontHashRegex)[1]
2149
+ : ''
2150
+ };`
2151
+ : titleFontStyle || '',
2152
+ titleFontSize ? `font-size: ${titleFontSize}px;` : '',
2153
+ '}',
2154
+ ].join('')
2155
+ : '';
2156
+
2157
+ let animationRules = '';
2158
+
2159
+ if (typeof animation === 'string') {
2160
+ const millisecondsDuration = (animationDuration / 1000).toFixed(2);
2161
+ const slideFromTopOrBottom = ['top', 'bottom'].includes(
2162
+ animationSlideDirection
2163
+ );
2164
+ const translateAxisPopin = Number(slideFromTopOrBottom);
2165
+ const translateParams = [
2166
+ `${
2167
+ ['top', 'left'].includes(animationSlideDirection) ? '-' : ''
2168
+ }100vmax`,
2169
+ this.translateValues ? this.translateValues[translateAxisPopin] : '0',
2170
+ ];
2171
+
2172
+ if (slideFromTopOrBottom) translateParams.reverse();
2173
+
2174
+ animationRules = {
2175
+ none: [`.${this.hideClassName} {`, 'opacity: 0 !important;', '}'],
2176
+ fade: [
2177
+ `.${this.hideClassName} {`,
2178
+ 'opacity: 0 !important;',
2179
+ '}',
2180
+ `#${this.widgetContainerId} {`,
2181
+ `transition: opacity ${millisecondsDuration}s ${animationBehaviour};`,
2182
+ '}',
2183
+ `@media (prefers-reduced-motion: reduce) {`,
2184
+ `#${this.widgetContainerId} {`,
2185
+ 'transition: unset;',
2186
+ '}',
2187
+ '}',
2188
+ ],
2189
+ slide: [
2190
+ `.${this.hideClassName} .${this.overlayClassName} {`,
2191
+ 'opacity: 0 !important;',
2192
+ '}',
2193
+ `#${this.widgetContainerId} .${this.overlayClassName} {`,
2194
+ `transition: opacity ${millisecondsDuration}s ${animationBehaviour};`,
2195
+ '}',
2196
+ `.${this.hideClassName} .${this.contentClassName} {`,
2197
+ `transform: translate(${translateParams.join(', ')}) !important;`,
2198
+ '}',
2199
+ `#${this.widgetContainerId} .${this.contentClassName} {`,
2200
+ `transition: transform ${millisecondsDuration}s ${animationBehaviour};`,
2201
+ '}',
2202
+ `@media (prefers-reduced-motion: reduce) {`,
2203
+ `#${this.widgetContainerId} .${this.overlayClassName},`,
2204
+ `.${this.hideClassName} .${this.contentClassName},`,
2205
+ `#${this.widgetContainerId} .${this.contentClassName} {`,
2206
+ 'transition: unset;',
2207
+ '}',
2208
+ '}',
2209
+ ],
2210
+ }[
2211
+ isOnEditor() && !ABTASTY_S.WIDGETS.animationChanged ? 'none' : animation
2212
+ ].join('');
2213
+ }
2214
+
2215
+ const secondLinkStyles = [
2216
+ `#${this.widgetContainerId} .${this.contentClassName} .buttons_container .second_link {`,
2217
+ `margin-${buttonsAlign === 'fill' ? 'top' : 'left'}: 8px;`,
2218
+ secondLinkBorderWidthStyle,
2219
+ secondLinkBorderColorStyle,
2220
+ secondLinkBorderRadiusStyle,
2221
+ secondLinkBackgroundColorStyle,
2222
+ secondLinkTextColorStyle,
2223
+ secondLinkFontNameStyle,
2224
+ secondLinkFontSizeStyle,
2225
+ '}',
2226
+ `#${this.widgetContainerId} .${this.contentClassName} .buttons_container .second_link {`,
2227
+ secondLinkTextColorStyle,
2228
+ secondLinkFontNameStyle,
2229
+ secondLinkFontSizeStyle,
2230
+ '}',
2231
+ ];
2232
+
2233
+ styleDomElement.textContent = [
2234
+ `#${this.widgetContainerId} style { display: none; }`,
2235
+ `.${this.hideClassName} {`,
2236
+ 'pointer-events: none;',
2237
+ '}',
2238
+ `#${this.widgetContainerId} {`,
2239
+ 'opacity: 1;',
2240
+ '}',
2241
+ `#${this.widgetContainerId} .${this.contentClassName} {`,
2242
+ backgroundStyle,
2243
+ borderRadiusStyle,
2244
+ borderStyle,
2245
+ textColorStyle,
2246
+ textAlignStyle,
2247
+ dropShadowStyle,
2248
+ marginsStyle,
2249
+ fontNameStyle,
2250
+ fontSizeStyle,
2251
+ '}',
2252
+ `#${this.widgetContainerId} .${this.contentClassName} p {`,
2253
+ textColorStyle,
2254
+ textAlignStyle,
2255
+ fontNameStyle,
2256
+ fontSizeStyle,
2257
+ '}',
2258
+ `#${this.widgetContainerId} .${this.contentClassName} > * {`,
2259
+ 'display: block;',
2260
+ 'line-height: 1;',
2261
+ 'text-indent: unset;',
2262
+ paddingsStyle,
2263
+ fontNameStyle,
2264
+ fontSizeStyle,
2265
+ '}',
2266
+ `#${this.widgetContainerId} .${this.contentClassName} a {`,
2267
+ 'text-decoration: underline;',
2268
+ '}',
2269
+ `#${this.widgetContainerId} .${this.contentClassName} div.buttons_container a, `,
2270
+ `#${this.widgetContainerId} .${this.contentClassName} button {`,
2271
+ 'text-decoration: none;',
2272
+ 'box-sizing: border-box;',
2273
+ 'display: inline-block;',
2274
+ buttonsBorderWidthStyle,
2275
+ buttonsBorderColorStyle,
2276
+ buttonsBorderRadiusStyle,
2277
+ buttonsBackgroundColorStyle,
2278
+ buttonsTextColorStyle,
2279
+ buttonsFontNameStyle,
2280
+ buttonsFontSizeStyle,
2281
+ '}',
2282
+ `#${this.widgetContainerId} .${this.contentClassName} div.buttons_container a *:not(.second_link span), `,
2283
+ `#${this.widgetContainerId} .${this.contentClassName} button:not([class*="close_button"], [class*="csatEmojiButton"]) * {`,
2284
+ buttonsTextColorStyle,
2285
+ buttonsFontNameStyle,
2286
+ buttonsFontSizeStyle,
2287
+ '}',
2288
+ ...(hasSecondLink ? secondLinkStyles : []),
2289
+ '@media screen and (max-width: 579px) {',
2290
+ `#${this.widgetContainerId} .${this.contentClassName} {`,
2291
+ marginSmallScreens,
2292
+ '}',
2293
+ `#${this.widgetContainerId} .${this.contentClassName} > * {`,
2294
+ paddingSmallScreens,
2295
+ '}',
2296
+ '}',
2297
+ overlayRules,
2298
+ closeButtonRules,
2299
+ titleRules,
2300
+ animationRules,
2301
+ `${uniqueStyles}`,
2302
+ ].join('');
2303
+
2304
+ return styleDomElement;
2305
+ }
2306
+ }
2307
+
2308
+ const xPosition = ['top: 0;', 'top: 50%;', 'bottom: 0;'];
2309
+ const yPosition = ['left: 0;', 'left: 50%;', 'right: 0;'];
2310
+ const getTranslatePercent = (axis) => (axis === 1 ? '-50%' : 0);
2311
+
2312
+ const getPopinPosition = () => {
2313
+ if (Array.isArray(DATA.popinPosition)) {
2314
+ const {
2315
+ popinPosition: [{ x, y }],
2316
+ } = DATA;
2317
+ const translateValue = `translate(${getTranslatePercent(y)}, ${getTranslatePercent(x)});`;
2318
+ return `${xPosition[x]}${yPosition[y]}transform: ${translateValue}`;
2319
+ }
2320
+ return 'left: 50%;top: 50%;transform: translate(-50%, -50%);';
2321
+ };
2322
+
2323
+ const useDimensionsAuto = () => 'autoWidth' in DATA && DATA.autoWidth === true;
2324
+
2325
+ const getPopinDimensions = () => {
2326
+ if (useDimensionsAuto()) return `width: auto; height: auto; min-width: fit-content;`;
2327
+
2328
+ const {
2329
+ popinPercentWidth,
2330
+ popinPixelsWidth,
2331
+ widthUnit,
2332
+ autoHeight,
2333
+ popinPercentHeight,
2334
+ popinPixelsHeight,
2335
+ heightUnit,
2336
+ } = DATA;
2337
+ const width = widthUnit === 'px' ? popinPixelsWidth : popinPercentWidth;
2338
+ const height = heightUnit === 'px' ? popinPixelsHeight : popinPercentHeight;
2339
+ return `width: ${width}${widthUnit};height: ${autoHeight ? 'auto' : `${height}${heightUnit}`};`;
2340
+ };
2341
+
2342
+ class Popin extends WidgetContainer {
2343
+ constructor() {
2344
+ super();
2345
+ this.translateValues = Object.values(DATA.popinPosition[0]).map(value => getTranslatePercent(value));
2346
+ this.stringStyles = this.getStyles();
2347
+ this.styleElement = this.getStyleTag(this.stringStyles);
2348
+ }
2349
+
2350
+ getStyles() {
2351
+ const { zindex, zindexCustom, widthUnit } = DATA;
2352
+ const overlay = typeof DATA.overlay === 'string' ? false : DATA.overlay;
2353
+
2354
+ return [
2355
+ `#${this.widgetContainerId} {`,
2356
+ 'position: fixed;',
2357
+ 'top: 0;',
2358
+ 'left: 0;',
2359
+ 'width: 100%;',
2360
+ 'height: 100%;',
2361
+ `z-index: ${zindex === 'custom' ? zindexCustom : zindex};`,
2362
+ 'background: none;',
2363
+ `pointer-events: ${overlay ? 'all' : 'none'}`,
2364
+ '}',
2365
+ `#${this.widgetContainerId} .${this.overlayClassName} {`,
2366
+ 'position: absolute;',
2367
+ 'z-index: -1;',
2368
+ 'top: 0;',
2369
+ 'left: 0;',
2370
+ 'width: 100%;',
2371
+ 'height: 100%;',
2372
+ '}',
2373
+ `#${this.widgetContainerId} .${this.contentClassName} {`,
2374
+ 'position: absolute;',
2375
+ getPopinPosition(),
2376
+ getPopinDimensions(),
2377
+ 'pointer-events: all',
2378
+ '}',
2379
+ `${
2380
+ !useDimensionsAuto()
2381
+ ? [
2382
+ `#${this.widgetContainerId} .${this.contentClassName} > div {`,
2383
+ 'height: 100%;',
2384
+ 'overflow: auto;',
2385
+ 'box-sizing: border-box;',
2386
+ '}',
2387
+ ].join('')
2388
+ : ''
2389
+ }`,
2390
+ `${
2391
+ !useDimensionsAuto() && ['px', 'em'].includes(widthUnit)
2392
+ ? [
2393
+ '@media screen and (max-width: 579px) {',
2394
+ `#${this.widgetContainerId} .${this.contentClassName} {`,
2395
+ 'max-width: 94vw;',
2396
+ '}',
2397
+ '}',
2398
+ ].join('')
2399
+ : ''
2400
+ }`,
2401
+ ].join('');
2402
+ }
2403
+ }
2404
+
2405
+ class Banner extends WidgetContainer {
2406
+ constructor() {
2407
+ super();
2408
+ this.position =
2409
+ typeof DATA.layout === 'string' && DATA.layout === 'bannerTop' ? 'top' : 'bottom';
2410
+ this.stringStyles = this.getStyles();
2411
+ this.styleElement = this.getStyleTag(this.stringStyles);
2412
+ }
2413
+
2414
+ getStyles() {
2415
+ const { zindex, zindexCustom } = DATA;
2416
+ return [
2417
+ `#${this.widgetContainerId} {`,
2418
+ 'position: fixed;',
2419
+ `${this.position}: 0;`,
2420
+ 'left: 0;',
2421
+ 'width: 100%;',
2422
+ 'height: auto;',
2423
+ `z-index: ${zindex === 'custom' ? zindexCustom : zindex};`,
2424
+ 'background: none;',
2425
+ '}',
2426
+ `#${this.widgetContainerId} .${this.contentClassName} {`,
2427
+ 'position: relative;',
2428
+ '}'
2429
+ ].join('');
2430
+ }
2431
+ }
2432
+
2433
+ class Free extends WidgetContainer {
2434
+ constructor(target, index) {
2435
+ super(target, index);
2436
+ this.stringStyles = this.getStyles();
2437
+ this.styleElement = this.getStyleTag(this.stringStyles);
2438
+ }
2439
+
2440
+ getStyles() {
2441
+ return [
2442
+ `#${this.widgetContainerId} {`,
2443
+ 'width: auto;',
2444
+ 'height: auto;',
2445
+ 'margin: 0;',
2446
+ 'padding: 0;',
2447
+ 'background: none;',
2448
+ '}',
2449
+ `#${this.widgetContainerId} .${this.contentClassName} {`,
2450
+ 'position: relative;',
2451
+ '}'
2452
+ ].join('');
2453
+ }
2454
+ }
2455
+
2456
+ const getWidgetContainer = () => {
2457
+ const { layout } = DATA;
2458
+
2459
+ let parentContainer;
2460
+
2461
+ switch (layout) {
2462
+ case 'popin':
2463
+ parentContainer = new Popin();
2464
+ break;
2465
+ case 'bannerTop':
2466
+ case 'bannerBottom':
2467
+ parentContainer = new Banner();
2468
+ break;
2469
+ case 'free':
2470
+ parentContainer = new Free();
2471
+ break;
2472
+ default:
2473
+ parentContainer = new WidgetContainer();
2474
+ break;
2475
+ }
2476
+
2477
+ return parentContainer;
2478
+ };
2479
+
2480
+ function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
2481
+ function _classCallCheck(a, n) { if (!(a instanceof n)) throw new TypeError("Cannot call a class as a function"); }
2482
+ function _defineProperties(e, r) { for (var t = 0; t < r.length; t++) { var o = r[t]; o.enumerable = o.enumerable || false, o.configurable = true, "value" in o && (o.writable = true), Object.defineProperty(e, _toPropertyKey(o.key), o); } }
2483
+ function _createClass(e, r, t) { return r && _defineProperties(e.prototype, r), t && _defineProperties(e, t), Object.defineProperty(e, "prototype", { writable: false }), e; }
2484
+ function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : i + ""; }
2485
+ function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return (String )(t); }
2486
+ var Widget = /*#__PURE__*/function () {
2487
+ function Widget(_ref) {
2488
+ var parentContainer = _ref.parentContainer;
2489
+ _classCallCheck(this, Widget);
2490
+ this.parentContainer = parentContainer;
2491
+ this.baseClassName = "qualitywidget_container";
2492
+ this.className = "".concat(this.baseClassName, "_").concat(parentContainer.uniqueId);
2493
+ this.contentElement = this.getContentElement();
2494
+ }
2495
+ return _createClass(Widget, [{
2496
+ key: "insertIn",
2497
+ value: function insertIn(element, position) {
2498
+ this.setStyles();
2499
+ element.insertAdjacentElement(position, this.contentElement);
2500
+ return this;
2501
+ }
2502
+ }, {
2503
+ key: "addCloseEvent",
2504
+ value: function addCloseEvent(closeElement) {
2505
+ var _this = this;
2506
+ if (closeElement) closeElement.addEventListener('click', function onClose(event) {
2507
+ avoidEventDetection(event);
2508
+ if (!isOnEditor()) _this.parentContainer.recurrence.setClosingRecurrence();
2509
+ _this.parentContainer.hide();
2510
+ setTimeout(function () {
2511
+ return _this.parentContainer.remove();
2512
+ }, 1000);
2513
+ }, {
2514
+ capture: true,
2515
+ passive: false
2516
+ });
2517
+ }
2518
+ }, {
2519
+ key: "addRedirectionEvent",
2520
+ value: function addRedirectionEvent(element) {
2521
+ var _this2 = this;
2522
+ if (!isOnEditor() && element) element.addEventListener('click', function onRedirect() {
2523
+ var _DATA = DATA,
2524
+ autoHide = _DATA.autoHide,
2525
+ timeHide = _DATA.timeHide;
2526
+ if (autoHide) setTimeout(function () {
2527
+ return _this2.parentContainer.hide();
2528
+ }, timeHide * 1000);
2529
+ if (!isOnEditor()) _this2.parentContainer.recurrence.setValidationRecurrence();
2530
+ }, {
2531
+ capture: true,
2532
+ passive: true
2533
+ });
2534
+ }
2535
+ }, {
2536
+ key: "getButton",
2537
+ value: function getButton() {
2538
+ var _DATA2 = DATA,
2539
+ linkType = _DATA2.linkType,
2540
+ buttonText = _DATA2.buttonText,
2541
+ redirectionUrl = _DATA2.redirectionUrl,
2542
+ openInNewTab = _DATA2.openInNewTab;
2543
+ var button = document.createElement('a');
2544
+ button.ariaLabel = buttonText;
2545
+ button.className = 'popin_link';
2546
+ button.innerHTML = "<span>".concat(buttonText, "</span>");
2547
+ if (linkType === 'button') {
2548
+ button.href = redirectionUrl;
2549
+ button.target = openInNewTab ? '_blank' : '_self';
2550
+ this.addRedirectionEvent(button);
2551
+ } else {
2552
+ button.href = '#';
2553
+ button.dataset.abtastyActionnable = 'true';
2554
+ this.addCloseEvent(button);
2555
+ }
2556
+ return button;
2557
+ }
2558
+ }, {
2559
+ key: "getContentElement",
2560
+ value: function getContentElement() {
2561
+ var _DATA3 = DATA,
2562
+ isTitle = _DATA3.isTitle,
2563
+ isText = _DATA3.isText,
2564
+ linkType = _DATA3.linkType,
2565
+ buttonText = _DATA3.buttonText,
2566
+ iconPicker = _DATA3.iconPicker;
2567
+ var elementType = typeof linkType === 'string' && linkType.includes('widget') ? 'a' : 'div';
2568
+ var contentElement = document.createElement(elementType);
2569
+ contentElement.className = this.className;
2570
+ if ((iconPicker === null || iconPicker === void 0 ? void 0 : iconPicker.src) !== '') {
2571
+ var imgElement = document.createElement('img');
2572
+ imgElement.setAttribute('src', iconPicker.src);
2573
+ imgElement.setAttribute('alt', iconPicker.alt);
2574
+ imgElement.classList.add('iconPicker');
2575
+ contentElement.appendChild(imgElement);
2576
+ }
2577
+ if (linkType === 'widget') {
2578
+ var _DATA4 = DATA,
2579
+ redirectionUrl = _DATA4.redirectionUrl,
2580
+ openInNewTab = _DATA4.openInNewTab;
2581
+ contentElement.href = redirectionUrl;
2582
+ contentElement.target = openInNewTab ? '_blank' : '_self';
2583
+ this.addRedirectionEvent(contentElement);
2584
+ } else if (linkType === 'widgetClose') {
2585
+ contentElement.href = '#';
2586
+ contentElement.dataset.abtastyActionnable = 'true';
2587
+ this.addCloseEvent(contentElement);
2588
+ }
2589
+ if (isTitle) {
2590
+ var _DATA5 = DATA,
2591
+ title = _DATA5.title;
2592
+ var titleElement = document.createElement('h4');
2593
+ titleElement.textContent = title;
2594
+ contentElement.appendChild(titleElement);
2595
+ }
2596
+ if (isText) {
2597
+ var _DATA6 = DATA,
2598
+ text = _DATA6.text,
2599
+ includeVariables = _DATA6.includeVariables;
2600
+ var textElement = document.createElement('p');
2601
+ var textContent = includeVariables ? Widget.getVariableText() : text;
2602
+ textElement.innerHTML = textContent;
2603
+ contentElement.appendChild(textElement);
2604
+ }
2605
+ if ([linkType, buttonText].every(function (prop) {
2606
+ return typeof prop === 'string';
2607
+ }) && linkType.includes('button') && buttonText.length) {
2608
+ var button = this.getButton();
2609
+ var buttonsContainer = document.createElement('div');
2610
+ buttonsContainer.className = 'buttons_container';
2611
+ buttonsContainer.appendChild(button);
2612
+ contentElement.appendChild(buttonsContainer);
2613
+ }
2614
+ return contentElement;
2615
+ }
2616
+ }, {
2617
+ key: "setStyles",
2618
+ value: function setStyles() {
2619
+ var _this$parentContainer = this.parentContainer,
2620
+ styleElement = _this$parentContainer.styleElement,
2621
+ widgetContainerId = _this$parentContainer.widgetContainerId;
2622
+ var _DATA7 = DATA,
2623
+ textColor = _DATA7.textColor,
2624
+ textAlign = _DATA7.textAlign,
2625
+ buttonsAlign = _DATA7.buttonsAlign;
2626
+ var baseSelector = "#".concat(widgetContainerId, " .").concat(this.className);
2627
+ var textColorValue = typeof textColor !== 'undefined' ? "color: ".concat(textColor, ";") : '';
2628
+ var textAlignValue = typeof textAlign !== 'undefined' ? "text-align: ".concat(textAlign, ";") : '';
2629
+ var buttonsAlignValue = typeof buttonsAlign !== 'undefined' && buttonsAlign !== 'fill' ? "text-align: ".concat(buttonsAlign, ";") : '';
2630
+ var stylesTextContent = ["".concat(baseSelector, " > * {"), 'display: inline-block;', 'vertical-align: middle;', '}', "".concat(baseSelector, " .iconPicker {"), 'width: 26px;', 'height: 26px;', '}', "".concat(baseSelector, " h4 {"), 'margin-bottom: 24px;', 'display: inline-block;', 'width: 100%', '}', "".concat(baseSelector, " p {"), 'width: 100%;', 'margin: 0;', 'white-space: pre-line;', textColorValue, textAlignValue, '}', "".concat(baseSelector, " .buttons_container {"), 'display: inline-block;', 'width: 100%;', buttonsAlignValue, '}', "".concat(baseSelector, " a {"), 'margin-top: 24px;', 'padding: 6px 16px;', "width: ".concat(buttonsAlign === 'fill' ? '100%' : 'auto', ";"), '}', '@media screen and (min-width: 1024px) {', '}', '@media screen and (max-width: 1023px) {', '}'].join('');
2631
+ styleElement.insertAdjacentText('beforeend', stylesTextContent);
2632
+ return styleElement;
2633
+ }
2634
+ }], [{
2635
+ key: "getVariableText",
2636
+ value: function getVariableText() {
2637
+ var _DATA8 = DATA,
2638
+ textVariables = _DATA8.textVariables,
2639
+ date = _DATA8.date,
2640
+ time = _DATA8.time,
2641
+ datetime = _DATA8.datetime,
2642
+ datetimeTimezone = _DATA8.datetimeTimezone;
2643
+
2644
+ // const jsTime = new Date(datetime);
2645
+ var jsDate = new Date(date);
2646
+ var jsDateTime = new Date(datetime);
2647
+
2648
+ // const hours = `${jsTime.getHours()}`;
2649
+ // const minutes = `${jsTime.getMinutes()}`;
2650
+ var jsDateDay = "".concat(jsDate.getDate());
2651
+ var jsDateMonth = "".concat(jsDate.getMonth() + 1);
2652
+ var jsDateYear = "".concat(jsDate.getFullYear());
2653
+ var jsDateTimeHours = "".concat(jsDateTime.getHours());
2654
+ var jsDateTimeMinutes = "".concat(jsDateTime.getMinutes());
2655
+ var jsDateTimeDay = "".concat(jsDateTime.getDate());
2656
+ var jsDateTimeMonth = "".concat(jsDateTime.getMonth() + 1);
2657
+ var jsDateTimeYear = "".concat(jsDateTime.getFullYear());
2658
+ var formatedDate = "".concat(jsDateDay.length < 2 ? "0".concat(jsDateDay) : jsDateDay, "/").concat(jsDateMonth.length < 2 ? "0".concat(jsDateMonth) : jsDateMonth, "/").concat(jsDateYear);
2659
+ var formatedTimeDate = "".concat(jsDateTimeHours.length < 2 ? "0".concat(jsDateTimeHours) : jsDateTimeHours, ":").concat(jsDateTimeMinutes.length < 2 ? "0".concat(jsDateTimeMinutes) : jsDateTimeMinutes);
2660
+ var formatedDateTime = "".concat(jsDateTimeDay.length < 2 ? "0".concat(jsDateTimeDay) : jsDateTimeDay, "/").concat(jsDateTimeMonth.length < 2 ? "0".concat(jsDateTimeMonth) : jsDateTimeMonth, "/").concat(jsDateTimeYear);
2661
+ var _datetimeTimezone$raw = datetimeTimezone.raw,
2662
+ followTheSun = _datetimeTimezone$raw.followTheSun,
2663
+ timezone = _datetimeTimezone$raw.timezone,
2664
+ previewTimezone = _datetimeTimezone$raw.previewTimezone,
2665
+ _datetimeTimezone$raw2 = _datetimeTimezone$raw.timedef,
2666
+ minute = _datetimeTimezone$raw2.minute,
2667
+ hour = _datetimeTimezone$raw2.hour,
2668
+ day = _datetimeTimezone$raw2.day,
2669
+ month = _datetimeTimezone$raw2.month,
2670
+ year = _datetimeTimezone$raw2.year;
2671
+ var formatedTimeTimezone = "".concat("".concat(hour).length < 2 ? "0".concat(hour) : hour, ":").concat("".concat(minute).length < 2 ? "0".concat(minute) : minute);
2672
+ var formatedDateTimezone = "".concat("".concat(day).length < 2 ? "0".concat(day) : day, "/").concat("".concat(month).length < 2 ? "0".concat(month) : month, "/").concat(year);
2673
+ var outputText = textVariables.replace('!time!', "<code class=\"time\">".concat(JSON.stringify(time, null, 0), "</code>")).replace('!date!', "<span class=\"date\">".concat(formatedDate, "</span>")).replace('!timedate!', "<span class=\"timedate\">".concat(formatedTimeDate, "</span>")).replace('!datetime!', "<span class=\"datetime\">".concat(formatedDateTime, "</span>")).replace('!timeTimezone!', "<span class=\"timeTimezone\">".concat(formatedTimeTimezone, "</span>")).replace('!dateTimezone!', "<span class=\"dateTimezone\">".concat(formatedDateTimezone, "</span>")).replace('!timezone!', "<span class=\"timezone\">".concat(followTheSun ? previewTimezone : timezone, "</span>"));
2674
+ return outputText;
2675
+ }
2676
+ }]);
2677
+ }();
2678
+
2679
+ function start() {
2680
+ widgetLog('Widget launch');
2681
+ var parentContainer = getWidgetContainer();
2682
+ var containerElement = parentContainer.domElement.querySelector(".".concat(parentContainer.contentClassName));
2683
+ var widget = new Widget({
2684
+ parentContainer: parentContainer
2685
+ });
2686
+ parentContainer.children = widget;
2687
+ widget.insertIn(containerElement, 'beforeend');
2688
+ parentContainer.init(true).then(function (_ref) {
2689
+ var response = _ref.response;
2690
+ if (response) parentContainer.show();
2691
+ });
2692
+ return {
2693
+ parentContainer: parentContainer,
2694
+ widget: widget
2695
+ };
2696
+ }
2697
+ start();
2698
+
2699
+ })();