@mycookies/widget 0.2.1 → 0.2.2

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.
@@ -189,6 +189,12 @@ export declare interface ConsentConfig {
189
189
  subscriptionId: string;
190
190
  /** List of consent categories the tenant uses */
191
191
  categories: ConsentCategory[];
192
+ /**
193
+ * Number of days after which stored consent is considered expired.
194
+ * Absent or undefined falls back to the engine's built-in 365-day default.
195
+ * Must be sourced from the signed remote config payload — never from user input.
196
+ */
197
+ expirationDays?: number;
192
198
  }
193
199
 
194
200
  /**
@@ -614,6 +620,14 @@ export declare interface RemoteConfigPayload {
614
620
  * framework (e.g. 'gdpr') to the subscription in the portal.
615
621
  */
616
622
  consentLogging?: boolean;
623
+ /**
624
+ * Number of days after which stored consent is considered expired and the
625
+ * consent banner is shown again. Determined server-side by the legal framework
626
+ * configured for the subscription (e.g. 365 for GDPR).
627
+ *
628
+ * Absent from the payload means the client falls back to the 365-day default.
629
+ */
630
+ consentExpirationDays?: number;
617
631
  }
618
632
 
619
633
  /** Signed envelope wrapping the config payload */
package/dist/index.cjs.js CHANGED
@@ -1 +1 @@
1
- "use strict";var e=Object.defineProperty,t=(t,o,n)=>((t,o,n)=>o in t?e(t,o,{enumerable:!0,configurable:!0,writable:!0,value:n}):t[o]=n)(t,"symbol"!=typeof o?o+"":o,n);Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const o="_mycookies_consent_v1_";class n{constructor(e,o,n){t(this,"config",null),t(this,"state",{}),t(this,"storage"),t(this,"eventBus"),t(this,"providerRegistry"),t(this,"initialized",!1),this.storage=e,this.eventBus=o,this.providerRegistry=n}init(e){if(this.initialized)throw new Error("ConsentEngine is already initialized");this.validateConfig(e);const t=o+e.subscriptionId,n=this.storage.get(t);null!==n&&this.isValidEnvelope(n)?this.state=this.buildStateFromStored(e.categories,n.state):this.state=this.buildDefaultState(e.categories),this.config=e,this.initialized=!0,this.eventBus.emit({...this.state}),this.providerRegistry.initAll({...this.state})}updateConsent(e){this.assertInitialized();let t=!1;for(const o of Object.keys(e))this.config.categories.includes(o)?this.state[o]!==e[o]&&(this.state[o]=e[o],t=!0):console.warn(`[MyCookies] Unknown consent category "${o}" — skipped`);const n=o+this.config.subscriptionId,i={version:1,state:{...this.state},updatedAt:Date.now()};if(this.storage.set(n,i),t){const e={...this.state};this.eventBus.emit(e),this.providerRegistry.notifyAll(e)}}getConsentState(){return this.assertInitialized(),{...this.state}}hasConsent(e){return this.assertInitialized(),!0===this.state[e]}hasStoredConsent(){this.assertInitialized();const e=o+this.config.subscriptionId,t=this.storage.get(e);return null!==t&&this.isValidEnvelope(t)}onConsentChange(e){return this.eventBus.subscribe(e)}registerProvider(e){if(this.providerRegistry.register(e),this.initialized)try{e.init({...this.state})}catch(t){console.error(`[MyCookies] Provider "${e.name}" threw during late init:`,t)}}getProvider(e){return this.providerRegistry.get(e)}getEventBus(){return this.eventBus}validateConfig(e){if(!e.subscriptionId||0===e.subscriptionId.trim().length)throw new Error("ConsentConfig.subscriptionId must be a non-empty string");if(!/^[a-zA-Z0-9_-]+$/.test(e.subscriptionId))throw new Error("ConsentConfig.subscriptionId must contain only alphanumeric characters, hyphens, and underscores");if(!Array.isArray(e.categories)||0===e.categories.length)throw new Error("ConsentConfig.categories must be a non-empty array")}isValidEnvelope(e){return null!==e&&"object"==typeof e&&1===e.version&&"object"==typeof e.state&&null!==e.state}buildStateFromStored(e,t){const o={};for(const n of e)o[n]=!0===t[n];return o}buildDefaultState(e){const t={};for(const o of e)t[o]=!1;return t}assertInitialized(){if(!this.initialized)throw new Error("ConsentEngine is not initialized. Call init() first.")}}class i{constructor(){t(this,"listeners",new Set),t(this,"currentState",null),t(this,"channels",new Map)}subscribe(e){if(this.listeners.add(e),null!==this.currentState)try{e(Object.freeze({...this.currentState}))}catch(o){console.error("[MyCookies] Subscriber callback threw during immediate dispatch:",o)}let t=!1;return()=>{t||(this.listeners.delete(e),t=!0)}}emit(e){if(null!==this.currentState&&this.isEqual(this.currentState,e))return;this.currentState={...e};const t=[...this.listeners];for(const n of t)try{n(Object.freeze({...this.currentState}))}catch(o){console.error("[MyCookies] Subscriber callback threw during emit:",o)}}on(e,t){const o=this.channels.get(e),n=o??new Set;o||this.channels.set(e,n);const i=t;n.add(i);let s=!1;return()=>{s||(n.delete(i),s=!0)}}emitChannel(e,t){const o=this.channels.get(e);if(!o)return;const n=[...o];for(const s of n)try{s(t)}catch(i){console.error(`[MyCookies] Channel "${e}" callback threw:`,i)}}clear(){this.listeners.clear(),this.channels.clear()}isEqual(e,t){const o=Object.keys(e),n=Object.keys(t);if(o.length!==n.length)return!1;for(const i of o)if(e[i]!==t[i])return!1;return!0}}class s{constructor(){t(this,"providers",new Map)}register(e){if(this.providers.has(e.name))throw new Error(`Provider "${e.name}" is already registered`);this.providers.set(e.name,e)}get(e){return this.providers.get(e)}getAll(){return Array.from(this.providers.values())}initAll(e){for(const o of this.providers.values())try{o.init(e)}catch(t){console.error(`[MyCookies] Provider "${o.name}" threw during init:`,t)}}notifyAll(e){for(const o of this.providers.values())try{o.updateConsent(e)}catch(t){console.error(`[MyCookies] Provider "${o.name}" threw during updateConsent:`,t)}}}class r{get(e){try{const t=window.localStorage.getItem(e);return null===t?null:JSON.parse(t)}catch{return console.warn(`[MyCookies] Failed to read key "${e}" from localStorage`),null}}set(e,t){try{window.localStorage.setItem(e,JSON.stringify(t))}catch{console.warn(`[MyCookies] Failed to write key "${e}" to localStorage (quota exceeded?)`)}}clear(e){try{window.localStorage.removeItem(e)}catch{console.warn(`[MyCookies] Failed to remove key "${e}" from localStorage`)}}}class a{constructor(e){t(this,"path"),t(this,"domain"),t(this,"secure"),t(this,"sameSite"),t(this,"maxAge"),this.path=(null==e?void 0:e.path)??"/",this.domain=null==e?void 0:e.domain,this.secure=(null==e?void 0:e.secure)??("undefined"!=typeof location&&"https:"===location.protocol),this.sameSite=(null==e?void 0:e.sameSite)??"Lax",this.maxAge=(null==e?void 0:e.maxAge)??31536e3}get(e){try{const t=this.readCookie(e);return null===t?null:JSON.parse(decodeURIComponent(t))}catch{return console.warn(`[MyCookies] Failed to read cookie "${e}"`),null}}set(e,t){try{const o=encodeURIComponent(JSON.stringify(t));o.length>4e3&&console.warn(`[MyCookies] Cookie "${e}" exceeds 4KB (${o.length} chars) — may be truncated by browser`);const n=this.buildCookieString(e,o,this.maxAge);document.cookie=n}catch{console.warn(`[MyCookies] Failed to write cookie "${e}"`)}}clear(e){try{const t=this.buildCookieString(e,"",0);document.cookie=t}catch{console.warn(`[MyCookies] Failed to clear cookie "${e}"`)}}readCookie(e){const t=encodeURIComponent(e),o=document.cookie.split(";");for(const n of o){const[e,...o]=n.split("=");if(e.trim()===t)return o.join("=")}return null}buildCookieString(e,t,o){let n=`${encodeURIComponent(e)}=${t}; path=${this.path}; max-age=${o}; SameSite=${this.sameSite}`;return this.domain&&(n+=`; domain=${this.domain}`),this.secure&&(n+="; Secure"),n}}const c="__mycookies_storage_test__";function l(e){try{window.localStorage.setItem(c,"1");const e=window.localStorage.getItem(c);if(window.localStorage.removeItem(c),"1"===e)return new r}catch{}return new a(e)}function d(e){const t=(null==e?void 0:e.storage)??l(),o=new i,r=new s;return new n(t,o,r)}const u=["analytics_storage","ad_storage","ad_user_data","ad_personalization"],h={analytics:["analytics_storage"],marketing:["ad_storage","ad_user_data","ad_personalization"]};class m{constructor(e){t(this,"name","google-consent-mode"),t(this,"categoryMapping"),t(this,"consentMode"),t(this,"waitForUpdate"),t(this,"reverseMap"),t(this,"lastParamState",null),this.categoryMapping=(null==e?void 0:e.categoryMapping)??{...h},this.consentMode=(null==e?void 0:e.consentMode)??"basic",void 0!==(null==e?void 0:e.waitForUpdate)?this.waitForUpdate=e.waitForUpdate:"basic"===this.consentMode?this.waitForUpdate=500:this.waitForUpdate=void 0,this.validateMapping(),this.reverseMap=this.buildReverseMap()}init(e){if("undefined"==typeof window)return;this.validateStateCategories(e);const t=this.resolveGtag();if(null===t)return;const o=this.buildAllDenied(),n={...o};void 0!==this.waitForUpdate&&(n.wait_for_update=this.waitForUpdate),t("consent","default",n);const i=this.mapStateToParams(e);this.lastParamState=i,this.paramsEqual(o,i)||t("consent","update",{...i})}updateConsent(e){if("undefined"==typeof window)return;const t=this.resolveGtag();if(null===t)return;const o=this.mapStateToParams(e);if(null!==this.lastParamState&&this.paramsEqual(this.lastParamState,o))return;this.lastParamState=o;t("consent","update",{...o})}resolveGtag(){const e=window;if("function"==typeof e.gtag)return e.gtag;if(Array.isArray(e.dataLayer)){const t=e.dataLayer,o=(e,o,n)=>{t.push([e,o,n])};return e.gtag=o,o}return console.warn("[MyCookies] GoogleConsentModeProvider: neither window.gtag nor window.dataLayer found. Google Tag Manager must be loaded for consent signals to work."),null}mapStateToParams(e){const t={};for(const o of u){const n=this.reverseMap.get(o);if(n&&0!==n.length){const i=n.every(t=>!0===e[t]);t[o]=i?"granted":"denied"}else t[o]="denied"}return t}buildReverseMap(){const e=new Map;for(const[t,o]of Object.entries(this.categoryMapping))for(const n of o){const o=e.get(n)??[];o.push(t),e.set(n,o)}return e}validateMapping(){const e=new Set;for(const[t,o]of Object.entries(this.categoryMapping)){if(!Array.isArray(o)||0===o.length)throw new Error(`[MyCookies] GoogleConsentModeProvider: category "${t}" has an empty mapping array`);for(const n of o){if(!u.includes(n))throw new Error(`[MyCookies] GoogleConsentModeProvider: unknown Google consent parameter "${n}" in mapping for category "${t}". Valid parameters: ${u.join(", ")}`);e.add(n)}}for(const t of u)if(!e.has(t))throw new Error(`[MyCookies] GoogleConsentModeProvider: Google consent parameter "${t}" is not covered by any category in the mapping. All 4 parameters must be mapped.`)}validateStateCategories(e){for(const t of Object.keys(this.categoryMapping))if(!(t in e))throw new Error(`[MyCookies] GoogleConsentModeProvider: mapped category "${t}" not found in consent state. Available categories: ${Object.keys(e).join(", ")}`)}buildAllDenied(){const e={};for(const t of u)e[t]="denied";return e}paramsEqual(e,t){for(const o of u)if(e[o]!==t[o])return!1;return!0}}const g={INVALID_SUBSCRIPTION_ID:"INVALID_SUBSCRIPTION_ID",FETCH_FAILED:"FETCH_FAILED",FETCH_TIMEOUT:"FETCH_TIMEOUT",HTTP_NOT_FOUND:"HTTP_NOT_FOUND",HTTP_FORBIDDEN:"HTTP_FORBIDDEN",HTTP_ERROR:"HTTP_ERROR",MALFORMED_RESPONSE:"MALFORMED_RESPONSE",CRYPTO_UNAVAILABLE:"CRYPTO_UNAVAILABLE",UNKNOWN_KEY_ID:"UNKNOWN_KEY_ID",SIGNATURE_INVALID:"SIGNATURE_INVALID",DOMAIN_UNAUTHORIZED:"DOMAIN_UNAUTHORIZED"};class p extends Error{constructor(e,o){super(o),t(this,"code"),this.name="ConfigError",this.code=e}}const y=new Map([["mycookies-key-v1",{kid:"mycookies-key-v1",jwk:{kty:"EC",crv:"P-256",x:"ALnbo6MOBq2wWi3keDxDS2FTLwfsqnWZRns2dFRT6Ac",y:"A19Kb_qZr4Ux5_IynCq0SIVi6UAFpynKtMj6CN8DNNg",ext:!0}}]]);function f(){return void 0!==globalThis.crypto&&void 0!==globalThis.crypto.subtle}async function b(e,t,o){const n=function(e){const t=y.get(e);if(t)return{...t,jwk:{...t.jwk}}}(o);if(!n)throw new p(g.UNKNOWN_KEY_ID,`Unknown key ID: "${o}"`);const i=await globalThis.crypto.subtle.importKey("jwk",n.jwk,{name:"ECDSA",namedCurve:"P-256"},!1,["verify"]),s=function(e){const t=atob(e),o=new Uint8Array(t.length);for(let n=0;n<t.length;n++)o[n]=t.charCodeAt(n);return o.buffer}(t),r=(new TextEncoder).encode(e);return globalThis.crypto.subtle.verify({name:"ECDSA",hash:"SHA-256"},i,s,r)}function v(e,t){const o=e.toLowerCase();for(const n of t){const e=n.toLowerCase();if(e===o)return!0;if(e.startsWith("*.")){const t=e.slice(2);if(o===t)return!0;if(o.endsWith("."+t))return!0}}return!1}let k=null;function w(){var e,t;if("function"==typeof(null==(e=globalThis.crypto)?void 0:e.randomUUID))return globalThis.crypto.randomUUID();if("function"==typeof(null==(t=globalThis.crypto)?void 0:t.getRandomValues)){const e=new Uint8Array(16);globalThis.crypto.getRandomValues(e),e[6]=15&e[6]|64,e[8]=63&e[8]|128;const t=Array.from(e,e=>e.toString(16).padStart(2,"0")).join("");return`${t.slice(0,8)}-${t.slice(8,12)}-${t.slice(12,16)}-${t.slice(16,20)}-${t.slice(20)}`}return"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,e=>{const t=16*Math.random()|0;return("x"===e?t:3&t|8).toString(16)})}const x=/^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;async function C(e){try{if(!x.test(e.subscriptionId))return S(g.INVALID_SUBSCRIPTION_ID,`Invalid subscriptionId format: "${e.subscriptionId}"`);const t=e.timeoutMs??5e3,o={"X-Request-Id":w(),"X-Session-Id":(null===k&&(k=w()),k),"X-Client-Version":Z},n=await async function(e,t,o){const n=new AbortController,i=setTimeout(()=>n.abort(),t);try{return await globalThis.fetch(e,{signal:n.signal,cache:"no-store",headers:o})}catch(s){if(s instanceof DOMException&&"AbortError"===s.name)throw new p(g.FETCH_TIMEOUT,`Request timed out after ${t}ms`);throw new p(g.FETCH_FAILED,`Fetch failed: ${String(s)}`)}finally{clearTimeout(i)}}(`https://api.mycookies.ws/v1/config/${e.subscriptionId}`,t,o);if(!n.ok)return function(e){if(404===e)return S(g.HTTP_NOT_FOUND,"Subscription configuration not found (404)");if(403===e)return S(g.HTTP_FORBIDDEN,"Access forbidden (403)");return S(g.HTTP_ERROR,`HTTP error: ${e}`)}(n.status);const i=await async function(e){let t;try{t=await e.json()}catch{throw new p(g.MALFORMED_RESPONSE,"Response is not valid JSON")}if(!function(e){if("object"!=typeof e||null===e)return!1;const t=e;return"string"==typeof t.payload&&"string"==typeof t.signature&&"string"==typeof t.kid}(t))throw new p(g.MALFORMED_RESPONSE,"Response does not match expected shape (payload, signature, kid)");return t}(n);if(!f())return S(g.CRYPTO_UNAVAILABLE,"Web Crypto API (crypto.subtle) is not available in this environment");const s=await async function(e){try{return await b(e.payload,e.signature,e.kid)}catch(t){if(t instanceof p)throw t;throw new p(g.SIGNATURE_INVALID,`Signature verification error: ${String(t)}`)}}(i);if(!s)return S(g.SIGNATURE_INVALID,"Signature verification failed");const r=function(e){let t;try{t=JSON.parse(e)}catch{throw new p(g.MALFORMED_RESPONSE,"Payload is not valid JSON")}if(!function(e){if("object"!=typeof e||null===e)return!1;const t=e;return Array.isArray(t.categories)&&"object"==typeof t.labels&&null!==t.labels&&"object"==typeof t.descriptions&&null!==t.descriptions&&Array.isArray(t.allowedDomains)&&"object"==typeof t.branding&&null!==t.branding&&Array.isArray(t.requiredCategories)&&"string"==typeof t.tier}(t))throw new p(g.MALFORMED_RESPONSE,"Payload does not match expected RemoteConfigPayload shape");return t}(i.payload),a=e.hostname??function(){if(void 0!==globalThis.location)return globalThis.location.hostname;return""}();return v(a,r.allowedDomains)?{ok:!0,payload:r,envelope:i}:S(g.DOMAIN_UNAUTHORIZED,`Domain "${a}" is not authorized for subscription "${e.subscriptionId}"`)}catch(t){return t instanceof p?{ok:!1,error:t}:S(g.FETCH_FAILED,`Unexpected error: ${String(t)}`)}}function S(e,t){return{ok:!1,error:new p(e,t)}}function E(e){try{const t=JSON.parse(e);if("object"!=typeof t||null===t)return null;const o=t;return Array.isArray(o.categories)&&Array.isArray(o.allowedDomains)?t:null}catch{return null}}class _{constructor(e,o){t(this,"storage"),t(this,"ttlMs"),this.storage=e,this.ttlMs=(null==o?void 0:o.ttlMs)??864e5}async get(e,t){const o=this.loadEntry(e);return o?Date.now()-o.cachedAt>this.ttlMs?null:this.verify(e,o,t):null}async getStale(e,t){const o=this.loadEntry(e);return o?this.verify(e,o,t):null}set(e,t){const o={envelope:t,cachedAt:Date.now()};this.storage.set(this.key(e),o)}clear(e){this.storage.clear(this.key(e))}has(e){return null!==this.loadEntry(e)}getUnverified(e){const t=this.loadEntry(e);return t?E(t.envelope.payload):null}key(e){return`_mycookies_config_v1_${e}`}loadEntry(e){return this.storage.get(this.key(e))}async verify(e,t,o){if(!f())return this.clear(e),null;try{if(!(await b(t.envelope.payload,t.envelope.signature,t.envelope.kid)))return this.clear(e),null}catch{return this.clear(e),null}const n=E(t.envelope.payload);return n&&v(o,n.allowedDomains)?{ok:!0,payload:n,envelope:t.envelope}:(this.clear(e),null)}}async function M(e){const{subscriptionId:t,timeoutMs:o,onError:n}=e,i=void 0!==globalThis.location?globalThis.location.hostname:"",s=function(){try{return new _(new r)}catch{return null}}();if(s){const e=await s.getStale(t,i);if(e){return await s.get(t,i)||function(e,t,o){const n=void 0!==globalThis.location?globalThis.location.hostname:void 0;C({subscriptionId:e,timeoutMs:t,hostname:n}).then(t=>{t.ok&&o.set(e,t.envelope)}).catch(()=>{})}(t,o,s),{ok:!0,payload:e.payload,envelope:e.envelope,cache:s}}}const a=await C({subscriptionId:t,timeoutMs:o,hostname:i||void 0});if(a.ok)return s&&s.set(t,a.envelope),{ok:!0,payload:a.payload,envelope:a.envelope,cache:s};throw n&&n(a.error),a.error}class A{constructor(){t(this,"entries",new Map)}enqueue(e){const t=this.entries.get(e.category);t?t.push(e):this.entries.set(e.category,[e])}dequeueByCategory(e){const t=this.entries.get(e);return t?(this.entries.delete(e),t):[]}getAll(){const e=[];for(const t of this.entries.values())e.push(...t);return e}getByCategory(e){return void 0===e?this.getAll():this.entries.get(e)??[]}clear(){this.entries.clear()}}const I="data-mycookies-category";class T{constructor(e,o){t(this,"engine"),t(this,"config"),t(this,"pendingQueue",new A),t(this,"activatedScripts",[]),t(this,"deferredScripts",[]),t(this,"previousState",{}),t(this,"observer",null),t(this,"unsubscribeConsent",null),t(this,"_active",!1),this.engine=e,this.config={observe:(null==o?void 0:o.observe)??!0,scanExisting:(null==o?void 0:o.scanExisting)??!0,nonce:(null==o?void 0:o.nonce)??""}}start(){if(!this._active&&"undefined"!=typeof document){this._active=!0;try{this.previousState=this.engine.getConsentState()}catch{this.previousState={}}this.unsubscribeConsent=this.engine.onConsentChange(e=>{this.handleConsentChange(e)}),this.config.scanExisting&&this.scanExistingScripts(),this.config.observe&&this.setupObserver()}}destroy(){this.observer&&(this.observer.disconnect(),this.observer=null),this.unsubscribeConsent&&(this.unsubscribeConsent(),this.unsubscribeConsent=null);for(const e of this.deferredScripts)e.reject(new Error("ScriptManager destroyed"));this.deferredScripts.length=0,this.pendingQueue.clear(),this.activatedScripts.length=0,this.previousState={},this._active=!1}loadScript(e,t,o){if(!e||0===e.trim().length)return Promise.reject(new Error("loadScript requires a non-empty src"));const n={element:document.createElement("script"),category:t,status:"pending",src:e,inline:!1};return this.engine.hasConsent(t)?this.injectExternalScript(n,null==o?void 0:o.nonce):new Promise((e,t)=>{this.deferredScripts.push({script:n,nonce:null==o?void 0:o.nonce,resolve:e,reject:t})})}getManagedScripts(e){return[...this.pendingQueue.getByCategory(e),...e?this.deferredScripts.filter(t=>t.script.category===e).map(e=>e.script):this.deferredScripts.map(e=>e.script),...e?this.activatedScripts.filter(t=>t.category===e):[...this.activatedScripts]]}get active(){return this._active}scanExistingScripts(){const e=document.querySelectorAll('script[type="text/plain"][data-mycookies-category]');for(const t of e)this.processScriptElement(t)}setupObserver(){this.observer=new MutationObserver(e=>{for(const t of e)for(const e of t.addedNodes)this.isManagedScriptElement(e)&&this.processScriptElement(e)}),this.observer.observe(document.documentElement,{childList:!0,subtree:!0})}isManagedScriptElement(e){return e.nodeType===Node.ELEMENT_NODE&&"SCRIPT"===e.tagName&&"text/plain"===e.getAttribute("type")&&e.hasAttribute(I)}processScriptElement(e){var t;const o=e.getAttribute(I);if(!o)return;const n=e.getAttribute("src")??void 0,i=!n;if(i&&!(null==(t=e.textContent)?void 0:t.trim()))return void console.warn(`[MyCookies] ScriptManager: empty inline script for category "${o}" — skipped`);const s={element:e,category:o,status:"pending",src:n,inline:i};let r=!1;try{r=this.engine.hasConsent(o)}catch{}r?this.activateScript(s):this.pendingQueue.enqueue(s)}handleConsentChange(e){const t=this.previousState;this.previousState={...e};for(const o of Object.keys(e))!0===e[o]&&!0!==t[o]&&(this.activatePendingForCategory(o),this.resolveDeferredForCategory(o));for(const o of Object.keys(t))!0===t[o]&&!0!==e[o]&&this.revokeCategory(o)}activatePendingForCategory(e){const t=this.pendingQueue.dequeueByCategory(e);for(const o of t)this.activateScript(o)}resolveDeferredForCategory(e){const t=[];for(const o of this.deferredScripts)o.script.category===e?this.injectExternalScript(o.script,o.nonce).then(o.resolve).catch(o.reject):t.push(o);this.deferredScripts.length=0,this.deferredScripts.push(...t)}activateScript(e){try{e.inline?this.activateInlineScript(e):this.activateExternalScript(e)}catch(t){e.status="error";const o=t instanceof Error?t:new Error(String(t));this.emitError(e.category,o,e.element,e.src)}}activateInlineScript(e){var t,o;const n=document.createElement("script");n.type="text/javascript",n.textContent=e.element.textContent,this.copyAttributes(e.element,n);const i=this.resolveNonce(e.element);i&&(n.nonce=i),null==(t=e.element.parentNode)||t.insertBefore(n,e.element.nextSibling),null==(o=e.element.parentNode)||o.removeChild(e.element),e.element=n,e.status="activated",this.activatedScripts.push(e),this.emitActivated(e)}activateExternalScript(e){var t,o;const n=document.createElement("script");n.type="text/javascript",n.src=e.src,this.copyAttributes(e.element,n);const i=this.resolveNonce(e.element);i&&(n.nonce=i),null==(t=e.element.parentNode)||t.insertBefore(n,e.element.nextSibling),null==(o=e.element.parentNode)||o.removeChild(e.element),e.element=n,e.status="activated",this.activatedScripts.push(e),this.emitActivated(e)}injectExternalScript(e,t){return new Promise((o,n)=>{try{const i=document.createElement("script");i.type="text/javascript",i.src=e.src;const s=t??e.element.nonce??e.element.getAttribute("nonce")??(this.config.nonce||void 0);s&&(i.nonce=s),i.onload=()=>{e.element=i,e.status="activated",this.activatedScripts.push(e),this.emitActivated(e),o(i)},i.onerror=()=>{e.status="error";const t=new Error(`Failed to load script: ${e.src}`);this.emitError(e.category,t,i,e.src),n(t)},document.head.appendChild(i)}catch(i){e.status="error";const t=i instanceof Error?i:new Error(String(i));this.emitError(e.category,t,e.element,e.src),n(t)}})}revokeCategory(e){const t=[];for(const o of this.activatedScripts)o.category===e&&"activated"===o.status&&(o.status="blocked",o.element.setAttribute("data-mycookies-blocked","true"),t.push(o.element));t.length>0&&this.emitRevoked(e,t)}copyAttributes(e,t){const o=new Set(["type","src","nonce",I]);for(const n of e.attributes)o.has(n.name)||n.name.toLowerCase().startsWith("on")||t.setAttribute(n.name,n.value)}resolveNonce(e){const t=e.nonce||e.getAttribute("nonce");return t||(this.config.nonce?this.config.nonce:void 0)}emitActivated(e){const t={type:"script:activated",element:e.element,category:e.category,src:e.src,inline:e.inline};try{this.engine.getEventBus().emitChannel("script:activated",t)}catch(o){console.error("[MyCookies] ScriptManager: failed to emit script:activated event:",o)}}emitRevoked(e,t){const o={type:"script:revoked",category:e,elements:t};try{this.engine.getEventBus().emitChannel("script:revoked",o)}catch(n){console.error("[MyCookies] ScriptManager: failed to emit script:revoked event:",n)}}emitError(e,t,o,n){const i={type:"script:error",category:e,error:t,element:o,src:n};try{this.engine.getEventBus().emitChannel("script:error",i)}catch(s){console.error("[MyCookies] ScriptManager: failed to emit script:error event:",s)}}}function N(e,t,o){const n={scriptManager:null,consentLogger:null};return function(e,t,o){if(!1===o)return;if(!(null==t?void 0:t.enabled))return;try{const n={consentMode:t.consentMode,categoryMapping:t.categoryMapping};void 0!==t.waitForUpdate&&(n.waitForUpdate=t.waitForUpdate),void 0!==o&&(void 0!==o.consentMode&&(n.consentMode=o.consentMode),void 0!==o.categoryMapping&&(n.categoryMapping=o.categoryMapping),void 0!==o.waitForUpdate&&(n.waitForUpdate=o.waitForUpdate)),void 0!==n.consentMode&&"basic"!==n.consentMode&&"advanced"!==n.consentMode&&(console.warn(`[MyCookies] Invalid consentMode "${String(n.consentMode)}" from remote config. Falling back to "basic".`),n.consentMode="basic");const i=new m(n);e.registerProvider(i)}catch(n){console.warn("[MyCookies] Failed to auto-register GoogleConsentModeProvider from remote config:",n instanceof Error?n.message:n)}}(e,null==t?void 0:t.googleConsentMode,null==o?void 0:o.googleConsentMode),n.scriptManager=function(e,t,o){if(!1===o)return null;if(!(null==t?void 0:t.enabled))return null;try{const n={};void 0!==t.observe&&(n.observe=t.observe),void 0!==t.scanExisting&&(n.scanExisting=t.scanExisting),void 0!==o&&(void 0!==o.observe&&(n.observe=o.observe),void 0!==o.scanExisting&&(n.scanExisting=o.scanExisting),void 0!==o.nonce&&(n.nonce=o.nonce));const i=new T(e,n);return i.start(),i}catch(n){return console.warn("[MyCookies] Failed to auto-start ScriptManager from remote config:",n instanceof Error?n.message:n),null}}(e,null==t?void 0:t.scriptManager,null==o?void 0:o.scriptManager),n}const R=9e5;class D{constructor(e){var o;t(this,"subscriptionId"),t(this,"cache"),t(this,"intervalMs"),t(this,"timeoutMs"),t(this,"hostname"),t(this,"timerId",null),t(this,"lastPollAt",0),t(this,"destroyed",!1),t(this,"started",!1),t(this,"handleVisibilityChange",()=>{if(!this.destroyed&&"undefined"!=typeof document)if(document.hidden)null!==this.timerId&&(clearTimeout(this.timerId),this.timerId=null);else{const e=Date.now()-this.lastPollAt;e>=this.intervalMs?this.pollAndSchedule():this.scheduleNext(this.intervalMs-e)}}),this.subscriptionId=e.subscriptionId,this.cache=e.cache,this.intervalMs=(o=e.intervalMs??R,!Number.isFinite(o)||o<6e4?R:o),this.timeoutMs=e.timeoutMs??5e3,this.hostname=e.hostname}start(){this.destroyed||this.started||(this.started=!0,this.lastPollAt=Date.now(),"undefined"!=typeof document&&"function"==typeof document.addEventListener&&document.addEventListener("visibilitychange",this.handleVisibilityChange),this.scheduleNext(this.intervalMs))}destroy(){this.destroyed||(this.destroyed=!0,null!==this.timerId&&(clearTimeout(this.timerId),this.timerId=null),"undefined"!=typeof document&&"function"==typeof document.removeEventListener&&document.removeEventListener("visibilitychange",this.handleVisibilityChange))}get active(){return this.started&&!this.destroyed}scheduleNext(e){this.timerId=setTimeout(()=>{this.pollAndSchedule()},e)}async pollAndSchedule(){this.timerId=null,this.destroyed||(await this.poll(),this.destroyed||this.scheduleNext(this.intervalMs))}async poll(){try{const e=this.hostname??(void 0!==globalThis.location?globalThis.location.hostname:void 0),t=await C({subscriptionId:this.subscriptionId,timeoutMs:this.timeoutMs,hostname:e});t.ok?this.cache.set(this.subscriptionId,t.envelope):console.warn(`[MyCookies] Config poll failed (${t.error.code}): ${t.error.message}`)}catch(e){console.warn("[MyCookies] Config poll error:",e instanceof Error?e.message:e)}this.lastPollAt=Date.now()}}function O(e,t,o,n,i){if(!1===(null==n?void 0:n.enabled))return null;if(!1===(null==o?void 0:o.enabled))return null;if(!t)return null;const s=(null==n?void 0:n.intervalMs)??(null==o?void 0:o.intervalMs)??void 0,r=new D({subscriptionId:e,cache:t,intervalMs:s,timeoutMs:i});return r.start(),r}const L="_mycookies_visitor_v1";class P{constructor(e){t(this,"options"),t(this,"unsubscribe",null),this.options=e}start(e){let t=!1;this.unsubscribe=e.onConsentChange(e=>{t&&this.sendEvent(e)}),t=!0}destroy(){var e;null==(e=this.unsubscribe)||e.call(this),this.unsubscribe=null}getOrCreateVisitorId(){try{const e=window.localStorage.getItem(L);if(e)return e;const t=`anon-${w().replace(/-/g,"").slice(0,8)}`;return window.localStorage.setItem(L,t),t}catch{return`anon-${w().replace(/-/g,"").slice(0,8)}`}}determineAction(e){const{categories:t,requiredCategories:o}=this.options,n=t.filter(e=>!o.includes(e));if(0===n.length)return"save_preferences";if(n.every(t=>!0===e[t]))return"accept_all";return n.every(t=>!0!==e[t])?"reject_all":"save_preferences"}sendEvent(e){const{categories:t,configSignature:o}=this.options,n={visitorId:this.getOrCreateVisitorId(),action:this.determineAction(e),granted:t.filter(t=>!0===e[t]),denied:t.filter(t=>!0!==e[t]),timestamp:(new Date).toISOString(),screenWidth:window.screen.width,screenHeight:window.screen.height,locale:navigator.language,timezone:Intl.DateTimeFormat().resolvedOptions().timeZone,pageUrl:window.location.href};o&&(n.configSignature=o);const i=`https://api.mycookies.ws/v1/consent-events/${this.options.subscriptionId}`;fetch(i,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(n)}).then(e=>{e.ok||e.json().then(e=>{if("object"==typeof e&&null!==e&&"error"in e&&"object"==typeof e.error){const t=e.error;console.warn(`[MyCookies] Consent event rejected: ${t.code}`)}}).catch(()=>{})}).catch(()=>{})}}function F(e,t,o,n){if(!o.consentLogging)return null;try{const i=new P({subscriptionId:t,categories:o.categories,requiredCategories:o.requiredCategories,configSignature:n});return i.start(e),i}catch(i){return console.warn("[MyCookies] Failed to start ConsentLogger:",i instanceof Error?i.message:i),null}}const U=["a[href]","button:not([disabled])","input:not([disabled])","select:not([disabled])","textarea:not([disabled])",'[tabindex]:not([tabindex="-1"])'].join(", ");function j(e){return Array.from(e.querySelectorAll(U))}function $(e=document){const t=e.activeElement;return(null==t?void 0:t.shadowRoot)?$(t.shadowRoot):t}function B(e,t){const o=o=>{var n;if("Escape"===o.key)return void(null==(n=null==t?void 0:t.onEscape)||n.call(t));if("Tab"!==o.key)return;const i=j(e);if(0===i.length)return void o.preventDefault();const s=i[0],r=i[i.length-1],a=$();o.shiftKey?a===s&&(o.preventDefault(),r.focus()):a===r&&(o.preventDefault(),s.focus())};e.addEventListener("keydown",o);const n=j(e);return n.length>0&&n[0].focus(),()=>{e.removeEventListener("keydown",o)}}function z(e="modal"){const t=document.createElement("div");return t.className=`mc-backdrop mc-backdrop--${e}`,"modal"===e&&t.setAttribute("data-action","close-modal"),t}function H(e,t,o,n){const i=document.createElement("button");i.className="mc-toggle"+(t?" mc-toggle--on":""),i.setAttribute("role","switch"),i.setAttribute("aria-checked",String(t)),i.setAttribute("aria-labelledby",n),i.setAttribute("data-action","toggle"),i.setAttribute("data-category",e),o&&i.setAttribute("disabled","");const s=document.createElement("span");s.className="mc-toggle__track",i.appendChild(s);const r=document.createElement("span");return r.className="mc-toggle__knob",i.appendChild(r),i}function V(){const e=document.createElement("div");return e.className="mc-tier-badge",e.textContent="Powered by MyCookies",e}function q(e,t,o){const n=document.createElement("button");return n.className=o,n.setAttribute("data-action",t),n.textContent=e,n}function G(e,t){return{...e,categories:t.categories,categoryLabels:{...e.categoryLabels,...t.labels},categoryDescriptions:{...e.categoryDescriptions,...t.descriptions},position:t.branding.position,requiredCategories:t.requiredCategories,tier:t.tier,poweredBy:t.branding.poweredBy,theme:e.theme??t.branding.theme,customCssUrl:e.customCssUrl??t.branding.customCssUrl,scrollLock:t.branding.scrollLock??e.scrollLock}}class W{constructor(e){t(this,"shadowHost"),t(this,"shadowRoot"),t(this,"engine"),t(this,"config"),t(this,"_onDestroy",[]),t(this,"_wiredScriptManager",null),t(this,"_wiredPoller",null),t(this,"currentView","banner"),t(this,"unsubscribe",null),t(this,"deactivateFocusTrap",null),t(this,"modalTriggerSource",null),t(this,"savedBodyOverflow",null),t(this,"savedBodyPaddingRight",null),t(this,"handleClick",e=>{const t=e.target.closest("[data-action]");if(t){const e=t.getAttribute("data-action");e&&this.handleAction(e,t)}}),t(this,"handleExternalConsentChange",e=>{}),this.config=e,e.engine?this.engine=e.engine:(this.engine=d(),this.engine.init({subscriptionId:e.subscriptionId,categories:e.categories})),this.shadowHost=document.createElement("div"),this.shadowHost.setAttribute("data-mycookies-widget",""),this.shadowRoot=this.shadowHost.attachShadow({mode:"open"}),"light"!==e.theme&&"dark"!==e.theme||this.shadowHost.setAttribute("data-theme",e.theme);const o=document.createElement("style");if(o.textContent=':host{--mycookies-bg: #ffffff;--mycookies-text: #1a1a2e;--mycookies-text-secondary: #6b7280;--mycookies-accent: #2563eb;--mycookies-border: #e5e7eb;--mycookies-btn-primary-bg: #1a1a2e;--mycookies-btn-primary-text: #ffffff;--mycookies-btn-secondary-bg: transparent;--mycookies-btn-secondary-text: #1a1a2e;--mycookies-btn-secondary-border: #e5e7eb;--mycookies-toggle-bg: #d1d5db;--mycookies-toggle-bg-on: #2563eb;--mycookies-toggle-knob: #ffffff;--mycookies-backdrop: rgba(0, 0, 0, .4);--mycookies-backdrop-blur: 4px;--mycookies-shadow: 0 -2px 16px rgba(0, 0, 0, .1);--mycookies-shadow-modal: 0 4px 24px rgba(0, 0, 0, .15);--mycookies-fab-shadow: 0 2px 8px rgba(0, 0, 0, .2);--mycookies-focus-ring: #2563eb;--mycookies-font-family: system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;--mycookies-font-size-sm: .875rem;--mycookies-font-size-base: 1rem;--mycookies-font-size-lg: 1.125rem;--mycookies-spacing-xs: .5rem;--mycookies-spacing-sm: .75rem;--mycookies-spacing-md: 1rem;--mycookies-spacing-lg: 1.5rem;--mycookies-radius-sm: .375rem;--mycookies-radius-md: .5rem;--mycookies-radius-lg: .75rem;--mycookies-radius-full: 9999px}@media(prefers-color-scheme:dark){:host{--mycookies-bg: #1a1a2e;--mycookies-text: #e8e8e8;--mycookies-text-secondary: #9ca3af;--mycookies-accent: #3b82f6;--mycookies-border: #374151;--mycookies-btn-primary-bg: #e8e8e8;--mycookies-btn-primary-text: #1a1a2e;--mycookies-btn-secondary-bg: transparent;--mycookies-btn-secondary-text: #e8e8e8;--mycookies-btn-secondary-border: #374151;--mycookies-toggle-bg: #4b5563;--mycookies-toggle-bg-on: #3b82f6;--mycookies-toggle-knob: #ffffff;--mycookies-backdrop: rgba(0, 0, 0, .6);--mycookies-shadow: 0 -2px 16px rgba(0, 0, 0, .3);--mycookies-shadow-modal: 0 4px 24px rgba(0, 0, 0, .4);--mycookies-fab-shadow: 0 2px 8px rgba(0, 0, 0, .4);--mycookies-focus-ring: #3b82f6}}:host([data-theme="light"]){--mycookies-bg: #ffffff;--mycookies-text: #1a1a2e;--mycookies-text-secondary: #6b7280;--mycookies-accent: #2563eb;--mycookies-border: #e5e7eb;--mycookies-btn-primary-bg: #1a1a2e;--mycookies-btn-primary-text: #ffffff;--mycookies-btn-secondary-bg: transparent;--mycookies-btn-secondary-text: #1a1a2e;--mycookies-btn-secondary-border: #e5e7eb;--mycookies-toggle-bg: #d1d5db;--mycookies-toggle-bg-on: #2563eb;--mycookies-toggle-knob: #ffffff;--mycookies-backdrop: rgba(0, 0, 0, .4);--mycookies-shadow: 0 -2px 16px rgba(0, 0, 0, .1);--mycookies-shadow-modal: 0 4px 24px rgba(0, 0, 0, .15);--mycookies-fab-shadow: 0 2px 8px rgba(0, 0, 0, .2);--mycookies-focus-ring: #2563eb}:host([data-theme="dark"]){--mycookies-bg: #1a1a2e;--mycookies-text: #e8e8e8;--mycookies-text-secondary: #9ca3af;--mycookies-accent: #3b82f6;--mycookies-border: #374151;--mycookies-btn-primary-bg: #e8e8e8;--mycookies-btn-primary-text: #1a1a2e;--mycookies-btn-secondary-bg: transparent;--mycookies-btn-secondary-text: #e8e8e8;--mycookies-btn-secondary-border: #374151;--mycookies-toggle-bg: #4b5563;--mycookies-toggle-bg-on: #3b82f6;--mycookies-toggle-knob: #ffffff;--mycookies-backdrop: rgba(0, 0, 0, .6);--mycookies-shadow: 0 -2px 16px rgba(0, 0, 0, .3);--mycookies-shadow-modal: 0 4px 24px rgba(0, 0, 0, .4);--mycookies-fab-shadow: 0 2px 8px rgba(0, 0, 0, .4);--mycookies-focus-ring: #3b82f6}:host,*,*:before,*:after{box-sizing:border-box}:host{font-size:16px;font-family:var(--mycookies-font-family);line-height:1.5;color:var(--mycookies-text)}*:focus-visible{outline:2px solid var(--mycookies-focus-ring);outline-offset:2px}.mc-banner{position:fixed;left:0;right:0;z-index:10000;display:flex;flex-direction:column;justify-content:space-between;gap:var(--mycookies-spacing-md);padding:var(--mycookies-spacing-lg);background:var(--mycookies-bg);box-shadow:var(--mycookies-shadow)}.mc-banner--top{top:0;border-bottom:1px solid var(--mycookies-border)}.mc-banner--bottom{bottom:0;border-top:1px solid var(--mycookies-border)}.mc-banner__content{display:flex;flex-direction:column;gap:var(--mycookies-spacing-sm)}.mc-banner__text{margin:0;font-size:var(--mycookies-font-size-sm);line-height:1.5;color:var(--mycookies-text)}.mc-banner__actions{display:flex;flex-direction:column;gap:var(--mycookies-spacing-xs)}.mc-btn{display:inline-flex;align-items:center;justify-content:center;min-height:44px;padding:var(--mycookies-spacing-xs) var(--mycookies-spacing-md);font-size:var(--mycookies-font-size-sm);font-family:var(--mycookies-font-family);font-weight:600;line-height:1.5;border-radius:var(--mycookies-radius-md);cursor:pointer;transition:opacity .15s ease,box-shadow .15s ease;white-space:nowrap;text-decoration:none;border:none}.mc-btn:hover{opacity:.9}.mc-btn:active{opacity:.8}.mc-btn--primary{background:var(--mycookies-btn-primary-bg);color:var(--mycookies-btn-primary-text)}.mc-btn--secondary{background:var(--mycookies-btn-secondary-bg);color:var(--mycookies-btn-secondary-text);border:1px solid var(--mycookies-btn-secondary-border)}.mc-btn--text{background:transparent;color:var(--mycookies-text-secondary);border:none}.mc-btn--text:hover{color:var(--mycookies-text);opacity:1}.mc-btn--full{width:100%}.mc-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;background:var(--mycookies-backdrop);backdrop-filter:blur(var(--mycookies-backdrop-blur));-webkit-backdrop-filter:blur(var(--mycookies-backdrop-blur))}.mc-backdrop--banner{z-index:9999}.mc-backdrop--modal{z-index:10001}.mc-modal{position:fixed;top:0;right:0;bottom:0;left:0;z-index:10002;display:flex;flex-direction:column;background:var(--mycookies-bg);box-shadow:var(--mycookies-shadow-modal)}.mc-modal__header{display:flex;align-items:center;justify-content:space-between;padding:var(--mycookies-spacing-md) var(--mycookies-spacing-lg);border-bottom:1px solid var(--mycookies-border)}.mc-modal__title{margin:0;font-size:var(--mycookies-font-size-lg);font-weight:700;color:var(--mycookies-text)}.mc-modal__close{display:inline-flex;align-items:center;justify-content:center;padding:var(--mycookies-spacing-xs);background:transparent;border:none;border-radius:var(--mycookies-radius-sm);cursor:pointer;color:var(--mycookies-text-secondary);transition:color .15s ease}.mc-modal__close:hover{color:var(--mycookies-text)}.mc-modal__body{flex:1;overflow-y:auto;padding:var(--mycookies-spacing-lg)}.mc-modal__footer{display:flex;align-items:center;justify-content:flex-end;gap:var(--mycookies-spacing-xs);padding:var(--mycookies-spacing-md) var(--mycookies-spacing-lg);border-top:1px solid var(--mycookies-border)}.mc-modal__footer .mc-tier-badge{margin-left:auto;padding:0}.mc-category{display:flex;align-items:flex-start;justify-content:space-between;gap:var(--mycookies-spacing-md);padding:var(--mycookies-spacing-sm) 0;border-bottom:1px solid var(--mycookies-border)}.mc-category:last-child{border-bottom:none}.mc-category__info{flex:1;min-width:0}.mc-category__name{display:block;font-size:var(--mycookies-font-size-sm);font-weight:600;color:var(--mycookies-text)}.mc-category__desc{display:block;margin-top:.25rem;font-size:var(--mycookies-font-size-sm);color:var(--mycookies-text-secondary)}.mc-toggle{position:relative;flex-shrink:0;cursor:pointer;background:none;border:none;padding:0}.mc-toggle:disabled{cursor:not-allowed;opacity:.5}.mc-toggle__track{display:block;width:44px;height:24px;border-radius:var(--mycookies-radius-full);background:var(--mycookies-toggle-bg);transition:background .2s ease}.mc-toggle--on .mc-toggle__track{background:var(--mycookies-toggle-bg-on)}.mc-toggle__knob{position:absolute;top:2px;left:2px;width:20px;height:20px;border-radius:var(--mycookies-radius-full);background:var(--mycookies-toggle-knob);transition:transform .2s ease;box-shadow:0 1px 3px #0000001a}.mc-toggle--on .mc-toggle__knob{transform:translate(20px)}.mc-fab{position:fixed;z-index:10000;display:inline-flex;align-items:center;justify-content:center;width:48px;height:48px;padding:0;border:none;border-radius:var(--mycookies-radius-full);background:var(--mycookies-btn-primary-bg);color:var(--mycookies-btn-primary-text);box-shadow:var(--mycookies-fab-shadow);cursor:pointer;transition:opacity .15s ease,box-shadow .15s ease}.mc-fab:hover{opacity:.9}.mc-fab--bottom-left{bottom:var(--mycookies-spacing-lg);left:var(--mycookies-spacing-lg)}.mc-fab--bottom-right{bottom:var(--mycookies-spacing-lg);right:var(--mycookies-spacing-lg)}.mc-tier-badge{padding:var(--mycookies-spacing-xs) 0;font-size:.75rem;color:var(--mycookies-text-secondary);text-align:center}@media(min-width:640px){.mc-modal{inset:auto;top:50%;left:50%;transform:translate(-50%,-50%);width:calc(100% - 2 * var(--mycookies-spacing-lg));max-width:560px;max-height:85vh;border:1px solid var(--mycookies-border);border-radius:var(--mycookies-radius-lg)}}@media(min-width:768px){.mc-banner{display:grid;grid-template-columns:1fr auto;grid-template-rows:auto auto;gap:0 var(--mycookies-spacing-md)}.mc-banner__content{grid-column:1;min-width:0}.mc-banner__actions{grid-column:2;grid-row:1 / -1;align-self:center;flex-direction:row;align-items:center;gap:var(--mycookies-spacing-sm)}.mc-btn--full{width:auto}.mc-banner>.mc-tier-badge{grid-column:1;margin-top:var(--mycookies-spacing-xs);text-align:left}}',this.shadowRoot.appendChild(o),e.customCssUrl){const t=document.createElement("link");t.rel="stylesheet",t.href=e.customCssUrl,this.shadowRoot.appendChild(t)}this.shadowRoot.addEventListener("click",this.handleClick),this.unsubscribe=this.engine.onConsentChange(this.handleExternalConsentChange),this.mount(()=>{const e=this.engine.hasStoredConsent()?"idle":"banner";this.show(e)})}static async createWithRemoteConfig(e){var t,o;try{const n=await M({subscriptionId:e.subscriptionId,timeoutMs:null==(t=e.remote)?void 0:t.timeoutMs,onError:null==(o=e.remote)?void 0:o.onError});return W.buildFromPayload(e,n.payload,n.cache,n.envelope.signature)}catch(n){if(!e.categories||0===e.categories.length)throw n;return new W(e)}}static buildFromPayload(e,t,o=null,n){var i,s;const r=G(e,t);if(0===r.categories.length){const t=new p(g.MALFORMED_RESPONSE,"Remote configuration contains no consent categories");if((null==(i=e.remote)?void 0:i.onError)&&e.remote.onError(t),e.categories.length>0)return new W(e);throw t}const a=d(),c=N(a,t.integrations,void 0);a.init({subscriptionId:e.subscriptionId,categories:r.categories});const l=F(a,e.subscriptionId,t,n),u=new W({...r,engine:a});if(c.scriptManager){const e=c.scriptManager;u._wiredScriptManager=e,u._addDestroyHook(()=>e.destroy())}if(l){const e=l;u._addDestroyHook(()=>e.destroy())}const h=O(e.subscriptionId,o,t.polling,void 0,null==(s=e.remote)?void 0:s.timeoutMs);return h&&(u._wiredPoller=h,u._addDestroyHook(()=>h.destroy())),u}_addDestroyHook(e){this._onDestroy.push(e)}destroy(){this.shadowRoot.removeEventListener("click",this.handleClick),"banner"!==this.currentView&&"modal"!==this.currentView||this.unlockScroll(),this.deactivateFocusTrap&&(this.deactivateFocusTrap(),this.deactivateFocusTrap=null),this.unsubscribe&&(this.unsubscribe(),this.unsubscribe=null);for(const e of this._onDestroy)try{e()}catch{}this.shadowHost.remove()}showPreferences(){this.show("modal")}getEngine(){return this.engine}mount(e){document.body?(document.body.appendChild(this.shadowHost),e()):document.addEventListener("DOMContentLoaded",()=>{document.body.appendChild(this.shadowHost),e()})}show(e){switch(this.deactivateFocusTrap&&(this.deactivateFocusTrap(),this.deactivateFocusTrap=null),"idle"===e&&this.unlockScroll(),this.clearContent(),this.currentView=e,e){case"banner":this.lockScroll(),this.renderBannerView();break;case"modal":this.lockScroll(),this.renderModalView();break;case"idle":this.renderIdleView()}}renderBannerView(){const e=z("banner");this.shadowRoot.appendChild(e);const t=function(e,t){const o=document.createElement("div");o.className=`mc-banner mc-banner--${t}`,o.setAttribute("role","region"),o.setAttribute("aria-label","Cookie consent");const n=document.createElement("div");n.className="mc-banner__content";const i=document.createElement("p");i.className="mc-banner__text",i.textContent=e.text??"We use cookies to improve your experience. Choose your cookie preferences.",n.appendChild(i);const s=document.createElement("div");s.className="mc-banner__actions",s.setAttribute("role","group"),s.setAttribute("aria-label","Consent choices");const r=q(e.acceptLabel??"Accept All","accept-all","mc-btn mc-btn--primary mc-btn--full");s.appendChild(r);const a=q(e.rejectLabel??"Reject All","reject-all","mc-btn mc-btn--text mc-btn--full");s.appendChild(a);const c=q(e.customizeLabel??"Customize","customize","mc-btn mc-btn--secondary mc-btn--full");return s.appendChild(c),o.appendChild(n),o.appendChild(s),o}(this.config.banner??{},this.config.position??"bottom");if(this.shadowRoot.appendChild(t),"free"===this.config.tier||!0===this.config.poweredBy){const e=V();t.appendChild(e)}}renderModalView(){const e=z("modal");this.shadowRoot.appendChild(e);const t=this.buildCategoryDisplayInfo(),o=this.engine.getConsentState(),n=function(e,t,o){const n=document.createElement("div");n.className="mc-modal",n.setAttribute("role","dialog"),n.setAttribute("aria-modal","true"),n.setAttribute("aria-labelledby","mc-modal-title");const i=document.createElement("div");i.className="mc-modal__header";const s=document.createElement("h2");s.className="mc-modal__title",s.id="mc-modal-title",s.textContent=e.title??"Cookie Preferences",i.appendChild(s);const r=document.createElement("button");r.className="mc-modal__close",r.setAttribute("data-action","close-modal"),r.setAttribute("aria-label","Close cookie preferences"),r.innerHTML='<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><line x1="5" y1="5" x2="15" y2="15"/><line x1="15" y1="5" x2="5" y2="15"/></svg>',i.appendChild(r),n.appendChild(i);const a=document.createElement("div");a.className="mc-modal__body";for(const d of t){const e=document.createElement("div");e.className="mc-category";const t=document.createElement("div");t.className="mc-category__info";const n=`mc-cat-${d.key}`,i=document.createElement("span");i.className="mc-category__name",i.id=n,i.textContent=d.label,t.appendChild(i);const s=document.createElement("span");s.className="mc-category__desc",s.textContent=d.description,t.appendChild(s),e.appendChild(t);const r=!0===d.required,c=!!r||!0===o[d.key],l=H(d.key,c,r,n);r&&l.setAttribute("aria-disabled","true"),e.appendChild(l),a.appendChild(e)}n.appendChild(a);const c=document.createElement("div");c.className="mc-modal__footer";const l=q(e.saveLabel??"Save Preferences","save-preferences","mc-btn mc-btn--primary");return c.appendChild(l),n.appendChild(c),n}(this.config.modal??{},t,o);if("free"===this.config.tier||!0===this.config.poweredBy){const e=n.querySelector(".mc-modal__footer");if(e){const t=V();e.appendChild(t)}}this.shadowRoot.appendChild(n),this.deactivateFocusTrap=B(n,{onEscape:()=>this.handleAction("close-modal")})}renderIdleView(){const e=function(e){const t=document.createElement("button"),o=e.position??"bottom-right";return t.className=`mc-fab mc-fab--${o}`,t.setAttribute("data-action","open-modal"),t.setAttribute("aria-label",e.ariaLabel??"Cookie preferences"),t.innerHTML='<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M10.343 3.94c.09-.542.56-.94 1.11-.94h1.093c.55 0 1.02.398 1.11.94l.149.894c.07.424.384.764.78.93.398.164.855.142 1.205-.108l.737-.527a1.125 1.125 0 0 1 1.45.12l.773.774c.39.389.44 1.002.12 1.45l-.527.737c-.25.35-.272.806-.107 1.204.165.397.505.71.93.78l.893.15c.543.09.94.559.94 1.109v1.094c0 .55-.397 1.02-.94 1.11l-.894.149c-.424.07-.764.383-.929.78-.165.398-.143.854.107 1.204l.527.738c.32.447.269 1.06-.12 1.45l-.774.773a1.125 1.125 0 0 1-1.449.12l-.738-.527c-.35-.25-.806-.272-1.203-.107-.398.165-.71.505-.781.929l-.149.894c-.09.542-.56.94-1.11.94h-1.094c-.55 0-1.019-.398-1.11-.94l-.148-.894c-.071-.424-.384-.764-.781-.93-.398-.164-.854-.142-1.204.108l-.738.527c-.447.32-1.06.269-1.45-.12l-.773-.774a1.125 1.125 0 0 1-.12-1.45l.527-.737c.25-.35.272-.806.108-1.204-.165-.397-.506-.71-.93-.78l-.894-.15c-.542-.09-.94-.56-.94-1.109v-1.094c0-.55.398-1.02.94-1.11l.894-.149c.424-.07.765-.383.93-.78.165-.398.143-.854-.108-1.204l-.526-.738a1.125 1.125 0 0 1 .12-1.45l.773-.773a1.125 1.125 0 0 1 1.45-.12l.737.527c.35.25.807.272 1.204.107.397-.165.71-.505.78-.929l.15-.894Z"/><path d="M15 12a3 3 0 1 1-6 0 3 3 0 0 1 6 0Z"/></svg>',t}(this.config.floatingButton??{});this.shadowRoot.appendChild(e)}handleAction(e,t){switch(e){case"accept-all":{const e=this.buildAllState(!0);this.engine.updateConsent(e),this.show("idle");break}case"reject-all":{const e=this.buildAllState(!1);this.engine.updateConsent(e),this.show("idle");break}case"customize":this.modalTriggerSource="customize",this.show("modal");break;case"save-preferences":{const e=this.getToggleStates();this.engine.updateConsent(e),this.show("idle");break}case"close-modal":this.engine.hasStoredConsent()?this.show("idle"):this.show("banner"),this.restoreFocusAfterModalClose(),this.modalTriggerSource=null;break;case"open-modal":this.modalTriggerSource="fab",this.show("modal");break;case"toggle":this.handleToggle(t)}}restoreFocusAfterModalClose(){if("customize"===this.modalTriggerSource){const e=this.shadowRoot.querySelector('[data-action="customize"]');null==e||e.focus()}else if("fab"===this.modalTriggerSource){const e=this.shadowRoot.querySelector('[data-action="open-modal"]');null==e||e.focus()}}handleToggle(e){if(!e)return;if(e.hasAttribute("disabled"))return;e.classList.contains("mc-toggle--on")?(e.classList.remove("mc-toggle--on"),e.setAttribute("aria-checked","false")):(e.classList.add("mc-toggle--on"),e.setAttribute("aria-checked","true"))}getToggleStates(){const e={},t=this.shadowRoot.querySelectorAll('[data-action="toggle"]');for(const n of t){const t=n.getAttribute("data-category");t&&(e[t]=n.classList.contains("mc-toggle--on"))}const o=this.config.requiredCategories??[];for(const n of o)e[n]=!0;return e}buildAllState(e){const t={};for(const o of this.config.categories)t[o]=e;return t}buildCategoryDisplayInfo(){const e=this.config.requiredCategories??[];return this.config.categories.map(t=>{var o,n;return{key:t,label:(null==(o=this.config.categoryLabels)?void 0:o[t])??t.charAt(0).toUpperCase()+t.slice(1),description:(null==(n=this.config.categoryDescriptions)?void 0:n[t])??"",required:e.includes(t)}})}clearContent(){const e=Array.from(this.shadowRoot.childNodes);for(const t of e)if(t instanceof HTMLElement){const e=t.tagName.toLowerCase();"style"!==e&&"link"!==e&&t.remove()}}lockScroll(){if(!1===this.config.scrollLock)return;if(this.config.onScrollLockChange)return void this.config.onScrollLockChange(!0);if(null!==this.savedBodyOverflow)return;const e=window.innerWidth-document.documentElement.clientWidth;if(this.savedBodyOverflow=document.documentElement.style.overflow,this.savedBodyPaddingRight=document.documentElement.style.paddingRight,document.documentElement.style.overflow="hidden",e>0){const t=parseFloat(getComputedStyle(document.documentElement).paddingRight)||0;document.documentElement.style.paddingRight=`${t+e}px`}}unlockScroll(){!1!==this.config.scrollLock&&(this.config.onScrollLockChange?this.config.onScrollLockChange(!1):(null!==this.savedBodyOverflow&&(document.documentElement.style.overflow=this.savedBodyOverflow,this.savedBodyOverflow=null),null!==this.savedBodyPaddingRight&&(document.documentElement.style.paddingRight=this.savedBodyPaddingRight,this.savedBodyPaddingRight=null)))}}const K=/^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;function J(e){if(!K.test(e))throw new Error(`Invalid subscriptionId format: "${e}". Expected a valid UUID v4.`)}const Z="0.0.0";exports.ConfigCache=_,exports.ConfigError=p,exports.ConfigErrorCode=g,exports.ConfigPoller=D,exports.ConsentEngine=n,exports.ConsentLogger=P,exports.CookieStorageAdapter=a,exports.GoogleConsentModeProvider=m,exports.LocalStorageAdapter=r,exports.ScriptManager=T,exports.VERSION=Z,exports.WidgetController=W,exports.createConsentEngine=d,exports.createValidatedEngine=async function(e){var t,o,n;J(e.subscriptionId);const i=await M({subscriptionId:e.subscriptionId,timeoutMs:null==(t=e.remote)?void 0:t.timeoutMs,onError:null==(o=e.remote)?void 0:o.onError}),s=d({storage:e.storage}),r=N(s,i.payload.integrations,void 0);return s.init({subscriptionId:e.subscriptionId,categories:i.payload.categories}),r.consentLogger=F(s,e.subscriptionId,i.payload,i.envelope.signature),{engine:s,integrations:r,poller:O(e.subscriptionId,i.cache,i.payload.polling,e.polling,null==(n=e.remote)?void 0:n.timeoutMs)}},exports.createWidget=async function(e){var t,o,n,i;J(e.subscriptionId);const s=await M({subscriptionId:e.subscriptionId,timeoutMs:null==(t=e.remote)?void 0:t.timeoutMs,onError:null==(o=e.remote)?void 0:o.onError}),r=O(e.subscriptionId,s.cache,s.payload.polling,e.polling,null==(n=e.remote)?void 0:n.timeoutMs);if(0===s.payload.categories.length){const t=new p(g.MALFORMED_RESPONSE,"Remote configuration contains no consent categories");throw(null==(i=e.remote)?void 0:i.onError)&&e.remote.onError(t),t}let a=e.engine,c=null,l=null;if(!a){a=d({storage:e.storage});c=N(a,s.payload.integrations,e.integrations).scriptManager,a.init({subscriptionId:e.subscriptionId,categories:s.payload.categories}),l=F(a,e.subscriptionId,s.payload,s.envelope.signature)}const u=G({subscriptionId:e.subscriptionId,categories:[],banner:e.banner,modal:e.modal,floatingButton:e.floatingButton,theme:e.theme,customCssUrl:e.customCssUrl,scrollLock:e.scrollLock,onScrollLockChange:e.onScrollLockChange,engine:a},s.payload),h=new W(u);if(c){const e=c;h._addDestroyHook(()=>e.destroy())}if(l){const e=l;h._addDestroyHook(()=>e.destroy())}return r&&h._addDestroyHook(()=>r.destroy()),h},exports.detectStorage=l,exports.isCryptoAvailable=f,exports.isDomainAuthorized=v,exports.mergeRemoteConfig=G,exports.resolveConfig=C,exports.validateSubscriptionUuid=J;
1
+ "use strict";var e=Object.defineProperty,t=(t,o,i)=>((t,o,i)=>o in t?e(t,o,{enumerable:!0,configurable:!0,writable:!0,value:i}):t[o]=i)(t,"symbol"!=typeof o?o+"":o,i);Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const o="_mycookies_consent_v1_";class i{constructor(e,o,i){t(this,"config",null),t(this,"state",{}),t(this,"storage"),t(this,"eventBus"),t(this,"providerRegistry"),t(this,"initialized",!1),this.storage=e,this.eventBus=o,this.providerRegistry=i}init(e){if(this.initialized)throw new Error("ConsentEngine is already initialized");this.validateConfig(e);const t=o+e.subscriptionId,i=this.storage.get(t),n=24*(e.expirationDays??365)*60*60*1e3;null!==i&&this.isValidEnvelope(i)?Date.now()-i.updatedAt>n?(this.storage.clear(t),this.state=this.buildDefaultState(e.categories)):this.state=this.buildStateFromStored(e.categories,i.state):this.state=this.buildDefaultState(e.categories),this.config=e,this.initialized=!0,this.eventBus.emit({...this.state}),this.providerRegistry.initAll({...this.state})}updateConsent(e){this.assertInitialized();let t=!1;for(const o of Object.keys(e))this.config.categories.includes(o)?this.state[o]!==e[o]&&(this.state[o]=e[o],t=!0):console.warn(`[MyCookies] Unknown consent category "${o}" — skipped`);const i=o+this.config.subscriptionId,n={version:1,state:{...this.state},updatedAt:Date.now()};if(this.storage.set(i,n),t){const e={...this.state};this.eventBus.emit(e),this.providerRegistry.notifyAll(e)}}getConsentState(){return this.assertInitialized(),{...this.state}}hasConsent(e){return this.assertInitialized(),!0===this.state[e]}hasStoredConsent(){this.assertInitialized();const e=o+this.config.subscriptionId,t=this.storage.get(e);return null!==t&&this.isValidEnvelope(t)}onConsentChange(e){return this.eventBus.subscribe(e)}registerProvider(e){if(this.providerRegistry.register(e),this.initialized)try{e.init({...this.state})}catch(t){console.error(`[MyCookies] Provider "${e.name}" threw during late init:`,t)}}getProvider(e){return this.providerRegistry.get(e)}getEventBus(){return this.eventBus}validateConfig(e){if(!e.subscriptionId||0===e.subscriptionId.trim().length)throw new Error("ConsentConfig.subscriptionId must be a non-empty string");if(!/^[a-zA-Z0-9_-]+$/.test(e.subscriptionId))throw new Error("ConsentConfig.subscriptionId must contain only alphanumeric characters, hyphens, and underscores");if(!Array.isArray(e.categories)||0===e.categories.length)throw new Error("ConsentConfig.categories must be a non-empty array")}isValidEnvelope(e){return null!==e&&"object"==typeof e&&1===e.version&&"object"==typeof e.state&&null!==e.state}buildStateFromStored(e,t){const o={};for(const i of e)o[i]=!0===t[i];return o}buildDefaultState(e){const t={};for(const o of e)t[o]=!1;return t}assertInitialized(){if(!this.initialized)throw new Error("ConsentEngine is not initialized. Call init() first.")}}class n{constructor(){t(this,"listeners",new Set),t(this,"currentState",null),t(this,"channels",new Map)}subscribe(e){if(this.listeners.add(e),null!==this.currentState)try{e(Object.freeze({...this.currentState}))}catch(o){console.error("[MyCookies] Subscriber callback threw during immediate dispatch:",o)}let t=!1;return()=>{t||(this.listeners.delete(e),t=!0)}}emit(e){if(null!==this.currentState&&this.isEqual(this.currentState,e))return;this.currentState={...e};const t=[...this.listeners];for(const i of t)try{i(Object.freeze({...this.currentState}))}catch(o){console.error("[MyCookies] Subscriber callback threw during emit:",o)}}on(e,t){const o=this.channels.get(e),i=o??new Set;o||this.channels.set(e,i);const n=t;i.add(n);let s=!1;return()=>{s||(i.delete(n),s=!0)}}emitChannel(e,t){const o=this.channels.get(e);if(!o)return;const i=[...o];for(const s of i)try{s(t)}catch(n){console.error(`[MyCookies] Channel "${e}" callback threw:`,n)}}clear(){this.listeners.clear(),this.channels.clear()}isEqual(e,t){const o=Object.keys(e),i=Object.keys(t);if(o.length!==i.length)return!1;for(const n of o)if(e[n]!==t[n])return!1;return!0}}class s{constructor(){t(this,"providers",new Map)}register(e){if(this.providers.has(e.name))throw new Error(`Provider "${e.name}" is already registered`);this.providers.set(e.name,e)}get(e){return this.providers.get(e)}getAll(){return Array.from(this.providers.values())}initAll(e){for(const o of this.providers.values())try{o.init(e)}catch(t){console.error(`[MyCookies] Provider "${o.name}" threw during init:`,t)}}notifyAll(e){for(const o of this.providers.values())try{o.updateConsent(e)}catch(t){console.error(`[MyCookies] Provider "${o.name}" threw during updateConsent:`,t)}}}class r{get(e){try{const t=window.localStorage.getItem(e);return null===t?null:JSON.parse(t)}catch{return console.warn(`[MyCookies] Failed to read key "${e}" from localStorage`),null}}set(e,t){try{window.localStorage.setItem(e,JSON.stringify(t))}catch{console.warn(`[MyCookies] Failed to write key "${e}" to localStorage (quota exceeded?)`)}}clear(e){try{window.localStorage.removeItem(e)}catch{console.warn(`[MyCookies] Failed to remove key "${e}" from localStorage`)}}}class a{constructor(e){t(this,"path"),t(this,"domain"),t(this,"secure"),t(this,"sameSite"),t(this,"maxAge"),this.path=(null==e?void 0:e.path)??"/",this.domain=null==e?void 0:e.domain,this.secure=(null==e?void 0:e.secure)??("undefined"!=typeof location&&"https:"===location.protocol),this.sameSite=(null==e?void 0:e.sameSite)??"Lax",this.maxAge=(null==e?void 0:e.maxAge)??31536e3}get(e){try{const t=this.readCookie(e);return null===t?null:JSON.parse(decodeURIComponent(t))}catch{return console.warn(`[MyCookies] Failed to read cookie "${e}"`),null}}set(e,t){try{const o=encodeURIComponent(JSON.stringify(t));o.length>4e3&&console.warn(`[MyCookies] Cookie "${e}" exceeds 4KB (${o.length} chars) — may be truncated by browser`);const i=this.buildCookieString(e,o,this.maxAge);document.cookie=i}catch{console.warn(`[MyCookies] Failed to write cookie "${e}"`)}}clear(e){try{const t=this.buildCookieString(e,"",0);document.cookie=t}catch{console.warn(`[MyCookies] Failed to clear cookie "${e}"`)}}readCookie(e){const t=encodeURIComponent(e),o=document.cookie.split(";");for(const i of o){const[e,...o]=i.split("=");if(e.trim()===t)return o.join("=")}return null}buildCookieString(e,t,o){let i=`${encodeURIComponent(e)}=${t}; path=${this.path}; max-age=${o}; SameSite=${this.sameSite}`;return this.domain&&(i+=`; domain=${this.domain}`),this.secure&&(i+="; Secure"),i}}const c="__mycookies_storage_test__";function l(e){try{window.localStorage.setItem(c,"1");const e=window.localStorage.getItem(c);if(window.localStorage.removeItem(c),"1"===e)return new r}catch{}return new a(e)}function d(e){const t=(null==e?void 0:e.storage)??l(),o=new n,r=new s;return new i(t,o,r)}const u=["analytics_storage","ad_storage","ad_user_data","ad_personalization"],h={analytics:["analytics_storage"],marketing:["ad_storage","ad_user_data","ad_personalization"]};class m{constructor(e){t(this,"name","google-consent-mode"),t(this,"categoryMapping"),t(this,"consentMode"),t(this,"waitForUpdate"),t(this,"reverseMap"),t(this,"lastParamState",null),this.categoryMapping=(null==e?void 0:e.categoryMapping)??{...h},this.consentMode=(null==e?void 0:e.consentMode)??"basic",void 0!==(null==e?void 0:e.waitForUpdate)?this.waitForUpdate=e.waitForUpdate:"basic"===this.consentMode?this.waitForUpdate=500:this.waitForUpdate=void 0,this.validateMapping(),this.reverseMap=this.buildReverseMap()}init(e){if("undefined"==typeof window)return;this.validateStateCategories(e);const t=this.resolveGtag();if(null===t)return;const o=this.buildAllDenied(),i={...o};void 0!==this.waitForUpdate&&(i.wait_for_update=this.waitForUpdate),t("consent","default",i);const n=this.mapStateToParams(e);this.lastParamState=n,this.paramsEqual(o,n)||t("consent","update",{...n})}updateConsent(e){if("undefined"==typeof window)return;const t=this.resolveGtag();if(null===t)return;const o=this.mapStateToParams(e);if(null!==this.lastParamState&&this.paramsEqual(this.lastParamState,o))return;this.lastParamState=o;t("consent","update",{...o})}resolveGtag(){const e=window;if("function"==typeof e.gtag)return e.gtag;if(Array.isArray(e.dataLayer)){const t=e.dataLayer,o=(e,o,i)=>{t.push([e,o,i])};return e.gtag=o,o}return console.warn("[MyCookies] GoogleConsentModeProvider: neither window.gtag nor window.dataLayer found. Google Tag Manager must be loaded for consent signals to work."),null}mapStateToParams(e){const t={};for(const o of u){const i=this.reverseMap.get(o);if(i&&0!==i.length){const n=i.every(t=>!0===e[t]);t[o]=n?"granted":"denied"}else t[o]="denied"}return t}buildReverseMap(){const e=new Map;for(const[t,o]of Object.entries(this.categoryMapping))for(const i of o){const o=e.get(i)??[];o.push(t),e.set(i,o)}return e}validateMapping(){const e=new Set;for(const[t,o]of Object.entries(this.categoryMapping)){if(!Array.isArray(o)||0===o.length)throw new Error(`[MyCookies] GoogleConsentModeProvider: category "${t}" has an empty mapping array`);for(const i of o){if(!u.includes(i))throw new Error(`[MyCookies] GoogleConsentModeProvider: unknown Google consent parameter "${i}" in mapping for category "${t}". Valid parameters: ${u.join(", ")}`);e.add(i)}}for(const t of u)if(!e.has(t))throw new Error(`[MyCookies] GoogleConsentModeProvider: Google consent parameter "${t}" is not covered by any category in the mapping. All 4 parameters must be mapped.`)}validateStateCategories(e){for(const t of Object.keys(this.categoryMapping))if(!(t in e))throw new Error(`[MyCookies] GoogleConsentModeProvider: mapped category "${t}" not found in consent state. Available categories: ${Object.keys(e).join(", ")}`)}buildAllDenied(){const e={};for(const t of u)e[t]="denied";return e}paramsEqual(e,t){for(const o of u)if(e[o]!==t[o])return!1;return!0}}const g={INVALID_SUBSCRIPTION_ID:"INVALID_SUBSCRIPTION_ID",FETCH_FAILED:"FETCH_FAILED",FETCH_TIMEOUT:"FETCH_TIMEOUT",HTTP_NOT_FOUND:"HTTP_NOT_FOUND",HTTP_FORBIDDEN:"HTTP_FORBIDDEN",HTTP_ERROR:"HTTP_ERROR",MALFORMED_RESPONSE:"MALFORMED_RESPONSE",CRYPTO_UNAVAILABLE:"CRYPTO_UNAVAILABLE",UNKNOWN_KEY_ID:"UNKNOWN_KEY_ID",SIGNATURE_INVALID:"SIGNATURE_INVALID",DOMAIN_UNAUTHORIZED:"DOMAIN_UNAUTHORIZED"};class p extends Error{constructor(e,o){super(o),t(this,"code"),this.name="ConfigError",this.code=e}}const y=new Map([["mycookies-key-v1",{kid:"mycookies-key-v1",jwk:{kty:"EC",crv:"P-256",x:"ALnbo6MOBq2wWi3keDxDS2FTLwfsqnWZRns2dFRT6Ac",y:"A19Kb_qZr4Ux5_IynCq0SIVi6UAFpynKtMj6CN8DNNg",ext:!0}}]]);function f(){return void 0!==globalThis.crypto&&void 0!==globalThis.crypto.subtle}async function b(e,t,o){const i=function(e){const t=y.get(e);if(t)return{...t,jwk:{...t.jwk}}}(o);if(!i)throw new p(g.UNKNOWN_KEY_ID,`Unknown key ID: "${o}"`);const n=await globalThis.crypto.subtle.importKey("jwk",i.jwk,{name:"ECDSA",namedCurve:"P-256"},!1,["verify"]),s=function(e){const t=atob(e),o=new Uint8Array(t.length);for(let i=0;i<t.length;i++)o[i]=t.charCodeAt(i);return o.buffer}(t),r=(new TextEncoder).encode(e);return globalThis.crypto.subtle.verify({name:"ECDSA",hash:"SHA-256"},n,s,r)}function v(e,t){const o=e.toLowerCase();for(const i of t){const e=i.toLowerCase();if(e===o)return!0;if(e.startsWith("*.")){const t=e.slice(2);if(o===t)return!0;if(o.endsWith("."+t))return!0}}return!1}let k=null;function w(){var e,t;if("function"==typeof(null==(e=globalThis.crypto)?void 0:e.randomUUID))return globalThis.crypto.randomUUID();if("function"==typeof(null==(t=globalThis.crypto)?void 0:t.getRandomValues)){const e=new Uint8Array(16);globalThis.crypto.getRandomValues(e),e[6]=15&e[6]|64,e[8]=63&e[8]|128;const t=Array.from(e,e=>e.toString(16).padStart(2,"0")).join("");return`${t.slice(0,8)}-${t.slice(8,12)}-${t.slice(12,16)}-${t.slice(16,20)}-${t.slice(20)}`}return"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,e=>{const t=16*Math.random()|0;return("x"===e?t:3&t|8).toString(16)})}const x=/^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;async function C(e){try{if(!x.test(e.subscriptionId))return S(g.INVALID_SUBSCRIPTION_ID,`Invalid subscriptionId format: "${e.subscriptionId}"`);const t=e.timeoutMs??5e3,o={"X-Request-Id":w(),"X-Session-Id":(null===k&&(k=w()),k),"X-Client-Version":Z},i=await async function(e,t,o){const i=new AbortController,n=setTimeout(()=>i.abort(),t);try{return await globalThis.fetch(e,{signal:i.signal,cache:"no-store",headers:o})}catch(s){if(s instanceof DOMException&&"AbortError"===s.name)throw new p(g.FETCH_TIMEOUT,`Request timed out after ${t}ms`);throw new p(g.FETCH_FAILED,`Fetch failed: ${String(s)}`)}finally{clearTimeout(n)}}(`https://api.mycookies.ws/v1/config/${e.subscriptionId}`,t,o);if(!i.ok)return function(e){if(404===e)return S(g.HTTP_NOT_FOUND,"Subscription configuration not found (404)");if(403===e)return S(g.HTTP_FORBIDDEN,"Access forbidden (403)");return S(g.HTTP_ERROR,`HTTP error: ${e}`)}(i.status);const n=await async function(e){let t;try{t=await e.json()}catch{throw new p(g.MALFORMED_RESPONSE,"Response is not valid JSON")}if(!function(e){if("object"!=typeof e||null===e)return!1;const t=e;return"string"==typeof t.payload&&"string"==typeof t.signature&&"string"==typeof t.kid}(t))throw new p(g.MALFORMED_RESPONSE,"Response does not match expected shape (payload, signature, kid)");return t}(i);if(!f())return S(g.CRYPTO_UNAVAILABLE,"Web Crypto API (crypto.subtle) is not available in this environment");const s=await async function(e){try{return await b(e.payload,e.signature,e.kid)}catch(t){if(t instanceof p)throw t;throw new p(g.SIGNATURE_INVALID,`Signature verification error: ${String(t)}`)}}(n);if(!s)return S(g.SIGNATURE_INVALID,"Signature verification failed");const r=function(e){let t;try{t=JSON.parse(e)}catch{throw new p(g.MALFORMED_RESPONSE,"Payload is not valid JSON")}if(!function(e){if("object"!=typeof e||null===e)return!1;const t=e;return Array.isArray(t.categories)&&"object"==typeof t.labels&&null!==t.labels&&"object"==typeof t.descriptions&&null!==t.descriptions&&Array.isArray(t.allowedDomains)&&"object"==typeof t.branding&&null!==t.branding&&Array.isArray(t.requiredCategories)&&"string"==typeof t.tier}(t))throw new p(g.MALFORMED_RESPONSE,"Payload does not match expected RemoteConfigPayload shape");return t}(n.payload),a=e.hostname??function(){if(void 0!==globalThis.location)return globalThis.location.hostname;return""}();return v(a,r.allowedDomains)?{ok:!0,payload:r,envelope:n}:S(g.DOMAIN_UNAUTHORIZED,`Domain "${a}" is not authorized for subscription "${e.subscriptionId}"`)}catch(t){return t instanceof p?{ok:!1,error:t}:S(g.FETCH_FAILED,`Unexpected error: ${String(t)}`)}}function S(e,t){return{ok:!1,error:new p(e,t)}}function E(e){try{const t=JSON.parse(e);if("object"!=typeof t||null===t)return null;const o=t;return Array.isArray(o.categories)&&Array.isArray(o.allowedDomains)?t:null}catch{return null}}class _{constructor(e,o){t(this,"storage"),t(this,"ttlMs"),this.storage=e,this.ttlMs=(null==o?void 0:o.ttlMs)??864e5}async get(e,t){const o=this.loadEntry(e);return o?Date.now()-o.cachedAt>this.ttlMs?null:this.verify(e,o,t):null}async getStale(e,t){const o=this.loadEntry(e);return o?this.verify(e,o,t):null}set(e,t){const o={envelope:t,cachedAt:Date.now()};this.storage.set(this.key(e),o)}clear(e){this.storage.clear(this.key(e))}has(e){return null!==this.loadEntry(e)}getUnverified(e){const t=this.loadEntry(e);return t?E(t.envelope.payload):null}key(e){return`_mycookies_config_v1_${e}`}loadEntry(e){return this.storage.get(this.key(e))}async verify(e,t,o){if(!f())return this.clear(e),null;try{if(!(await b(t.envelope.payload,t.envelope.signature,t.envelope.kid)))return this.clear(e),null}catch{return this.clear(e),null}const i=E(t.envelope.payload);return i&&v(o,i.allowedDomains)?{ok:!0,payload:i,envelope:t.envelope}:(this.clear(e),null)}}async function M(e){const{subscriptionId:t,timeoutMs:o,onError:i}=e,n=void 0!==globalThis.location?globalThis.location.hostname:"",s=function(){try{return new _(new r)}catch{return null}}();if(s){const e=await s.getStale(t,n);if(e){return await s.get(t,n)||function(e,t,o){const i=void 0!==globalThis.location?globalThis.location.hostname:void 0;C({subscriptionId:e,timeoutMs:t,hostname:i}).then(t=>{t.ok&&o.set(e,t.envelope)}).catch(()=>{})}(t,o,s),{ok:!0,payload:e.payload,envelope:e.envelope,cache:s}}}const a=await C({subscriptionId:t,timeoutMs:o,hostname:n||void 0});if(a.ok)return s&&s.set(t,a.envelope),{ok:!0,payload:a.payload,envelope:a.envelope,cache:s};throw i&&i(a.error),a.error}class A{constructor(){t(this,"entries",new Map)}enqueue(e){const t=this.entries.get(e.category);t?t.push(e):this.entries.set(e.category,[e])}dequeueByCategory(e){const t=this.entries.get(e);return t?(this.entries.delete(e),t):[]}getAll(){const e=[];for(const t of this.entries.values())e.push(...t);return e}getByCategory(e){return void 0===e?this.getAll():this.entries.get(e)??[]}clear(){this.entries.clear()}}const I="data-mycookies-category";class T{constructor(e,o){t(this,"engine"),t(this,"config"),t(this,"pendingQueue",new A),t(this,"activatedScripts",[]),t(this,"deferredScripts",[]),t(this,"previousState",{}),t(this,"observer",null),t(this,"unsubscribeConsent",null),t(this,"_active",!1),this.engine=e,this.config={observe:(null==o?void 0:o.observe)??!0,scanExisting:(null==o?void 0:o.scanExisting)??!0,nonce:(null==o?void 0:o.nonce)??""}}start(){if(!this._active&&"undefined"!=typeof document){this._active=!0;try{this.previousState=this.engine.getConsentState()}catch{this.previousState={}}this.unsubscribeConsent=this.engine.onConsentChange(e=>{this.handleConsentChange(e)}),this.config.scanExisting&&this.scanExistingScripts(),this.config.observe&&this.setupObserver()}}destroy(){this.observer&&(this.observer.disconnect(),this.observer=null),this.unsubscribeConsent&&(this.unsubscribeConsent(),this.unsubscribeConsent=null);for(const e of this.deferredScripts)e.reject(new Error("ScriptManager destroyed"));this.deferredScripts.length=0,this.pendingQueue.clear(),this.activatedScripts.length=0,this.previousState={},this._active=!1}loadScript(e,t,o){if(!e||0===e.trim().length)return Promise.reject(new Error("loadScript requires a non-empty src"));const i={element:document.createElement("script"),category:t,status:"pending",src:e,inline:!1};return this.engine.hasConsent(t)?this.injectExternalScript(i,null==o?void 0:o.nonce):new Promise((e,t)=>{this.deferredScripts.push({script:i,nonce:null==o?void 0:o.nonce,resolve:e,reject:t})})}getManagedScripts(e){return[...this.pendingQueue.getByCategory(e),...e?this.deferredScripts.filter(t=>t.script.category===e).map(e=>e.script):this.deferredScripts.map(e=>e.script),...e?this.activatedScripts.filter(t=>t.category===e):[...this.activatedScripts]]}get active(){return this._active}scanExistingScripts(){const e=document.querySelectorAll('script[type="text/plain"][data-mycookies-category]');for(const t of e)this.processScriptElement(t)}setupObserver(){this.observer=new MutationObserver(e=>{for(const t of e)for(const e of t.addedNodes)this.isManagedScriptElement(e)&&this.processScriptElement(e)}),this.observer.observe(document.documentElement,{childList:!0,subtree:!0})}isManagedScriptElement(e){return e.nodeType===Node.ELEMENT_NODE&&"SCRIPT"===e.tagName&&"text/plain"===e.getAttribute("type")&&e.hasAttribute(I)}processScriptElement(e){var t;const o=e.getAttribute(I);if(!o)return;const i=e.getAttribute("src")??void 0,n=!i;if(n&&!(null==(t=e.textContent)?void 0:t.trim()))return void console.warn(`[MyCookies] ScriptManager: empty inline script for category "${o}" — skipped`);const s={element:e,category:o,status:"pending",src:i,inline:n};let r=!1;try{r=this.engine.hasConsent(o)}catch{}r?this.activateScript(s):this.pendingQueue.enqueue(s)}handleConsentChange(e){const t=this.previousState;this.previousState={...e};for(const o of Object.keys(e))!0===e[o]&&!0!==t[o]&&(this.activatePendingForCategory(o),this.resolveDeferredForCategory(o));for(const o of Object.keys(t))!0===t[o]&&!0!==e[o]&&this.revokeCategory(o)}activatePendingForCategory(e){const t=this.pendingQueue.dequeueByCategory(e);for(const o of t)this.activateScript(o)}resolveDeferredForCategory(e){const t=[];for(const o of this.deferredScripts)o.script.category===e?this.injectExternalScript(o.script,o.nonce).then(o.resolve).catch(o.reject):t.push(o);this.deferredScripts.length=0,this.deferredScripts.push(...t)}activateScript(e){try{e.inline?this.activateInlineScript(e):this.activateExternalScript(e)}catch(t){e.status="error";const o=t instanceof Error?t:new Error(String(t));this.emitError(e.category,o,e.element,e.src)}}activateInlineScript(e){var t,o;const i=document.createElement("script");i.type="text/javascript",i.textContent=e.element.textContent,this.copyAttributes(e.element,i);const n=this.resolveNonce(e.element);n&&(i.nonce=n),null==(t=e.element.parentNode)||t.insertBefore(i,e.element.nextSibling),null==(o=e.element.parentNode)||o.removeChild(e.element),e.element=i,e.status="activated",this.activatedScripts.push(e),this.emitActivated(e)}activateExternalScript(e){var t,o;const i=document.createElement("script");i.type="text/javascript",i.src=e.src,this.copyAttributes(e.element,i);const n=this.resolveNonce(e.element);n&&(i.nonce=n),null==(t=e.element.parentNode)||t.insertBefore(i,e.element.nextSibling),null==(o=e.element.parentNode)||o.removeChild(e.element),e.element=i,e.status="activated",this.activatedScripts.push(e),this.emitActivated(e)}injectExternalScript(e,t){return new Promise((o,i)=>{try{const n=document.createElement("script");n.type="text/javascript",n.src=e.src;const s=t??e.element.nonce??e.element.getAttribute("nonce")??(this.config.nonce||void 0);s&&(n.nonce=s),n.onload=()=>{e.element=n,e.status="activated",this.activatedScripts.push(e),this.emitActivated(e),o(n)},n.onerror=()=>{e.status="error";const t=new Error(`Failed to load script: ${e.src}`);this.emitError(e.category,t,n,e.src),i(t)},document.head.appendChild(n)}catch(n){e.status="error";const t=n instanceof Error?n:new Error(String(n));this.emitError(e.category,t,e.element,e.src),i(t)}})}revokeCategory(e){const t=[];for(const o of this.activatedScripts)o.category===e&&"activated"===o.status&&(o.status="blocked",o.element.setAttribute("data-mycookies-blocked","true"),t.push(o.element));t.length>0&&this.emitRevoked(e,t)}copyAttributes(e,t){const o=new Set(["type","src","nonce",I]);for(const i of e.attributes)o.has(i.name)||i.name.toLowerCase().startsWith("on")||t.setAttribute(i.name,i.value)}resolveNonce(e){const t=e.nonce||e.getAttribute("nonce");return t||(this.config.nonce?this.config.nonce:void 0)}emitActivated(e){const t={type:"script:activated",element:e.element,category:e.category,src:e.src,inline:e.inline};try{this.engine.getEventBus().emitChannel("script:activated",t)}catch(o){console.error("[MyCookies] ScriptManager: failed to emit script:activated event:",o)}}emitRevoked(e,t){const o={type:"script:revoked",category:e,elements:t};try{this.engine.getEventBus().emitChannel("script:revoked",o)}catch(i){console.error("[MyCookies] ScriptManager: failed to emit script:revoked event:",i)}}emitError(e,t,o,i){const n={type:"script:error",category:e,error:t,element:o,src:i};try{this.engine.getEventBus().emitChannel("script:error",n)}catch(s){console.error("[MyCookies] ScriptManager: failed to emit script:error event:",s)}}}function N(e,t,o){const i={scriptManager:null,consentLogger:null};return function(e,t,o){if(!1===o)return;if(!(null==t?void 0:t.enabled))return;try{const i={consentMode:t.consentMode,categoryMapping:t.categoryMapping};void 0!==t.waitForUpdate&&(i.waitForUpdate=t.waitForUpdate),void 0!==o&&(void 0!==o.consentMode&&(i.consentMode=o.consentMode),void 0!==o.categoryMapping&&(i.categoryMapping=o.categoryMapping),void 0!==o.waitForUpdate&&(i.waitForUpdate=o.waitForUpdate)),void 0!==i.consentMode&&"basic"!==i.consentMode&&"advanced"!==i.consentMode&&(console.warn(`[MyCookies] Invalid consentMode "${String(i.consentMode)}" from remote config. Falling back to "basic".`),i.consentMode="basic");const n=new m(i);e.registerProvider(n)}catch(i){console.warn("[MyCookies] Failed to auto-register GoogleConsentModeProvider from remote config:",i instanceof Error?i.message:i)}}(e,null==t?void 0:t.googleConsentMode,null==o?void 0:o.googleConsentMode),i.scriptManager=function(e,t,o){if(!1===o)return null;if(!(null==t?void 0:t.enabled))return null;try{const i={};void 0!==t.observe&&(i.observe=t.observe),void 0!==t.scanExisting&&(i.scanExisting=t.scanExisting),void 0!==o&&(void 0!==o.observe&&(i.observe=o.observe),void 0!==o.scanExisting&&(i.scanExisting=o.scanExisting),void 0!==o.nonce&&(i.nonce=o.nonce));const n=new T(e,i);return n.start(),n}catch(i){return console.warn("[MyCookies] Failed to auto-start ScriptManager from remote config:",i instanceof Error?i.message:i),null}}(e,null==t?void 0:t.scriptManager,null==o?void 0:o.scriptManager),i}const D=9e5;class R{constructor(e){var o;t(this,"subscriptionId"),t(this,"cache"),t(this,"intervalMs"),t(this,"timeoutMs"),t(this,"hostname"),t(this,"timerId",null),t(this,"lastPollAt",0),t(this,"destroyed",!1),t(this,"started",!1),t(this,"handleVisibilityChange",()=>{if(!this.destroyed&&"undefined"!=typeof document)if(document.hidden)null!==this.timerId&&(clearTimeout(this.timerId),this.timerId=null);else{const e=Date.now()-this.lastPollAt;e>=this.intervalMs?this.pollAndSchedule():this.scheduleNext(this.intervalMs-e)}}),this.subscriptionId=e.subscriptionId,this.cache=e.cache,this.intervalMs=(o=e.intervalMs??D,!Number.isFinite(o)||o<6e4?D:o),this.timeoutMs=e.timeoutMs??5e3,this.hostname=e.hostname}start(){this.destroyed||this.started||(this.started=!0,this.lastPollAt=Date.now(),"undefined"!=typeof document&&"function"==typeof document.addEventListener&&document.addEventListener("visibilitychange",this.handleVisibilityChange),this.scheduleNext(this.intervalMs))}destroy(){this.destroyed||(this.destroyed=!0,null!==this.timerId&&(clearTimeout(this.timerId),this.timerId=null),"undefined"!=typeof document&&"function"==typeof document.removeEventListener&&document.removeEventListener("visibilitychange",this.handleVisibilityChange))}get active(){return this.started&&!this.destroyed}scheduleNext(e){this.timerId=setTimeout(()=>{this.pollAndSchedule()},e)}async pollAndSchedule(){this.timerId=null,this.destroyed||(await this.poll(),this.destroyed||this.scheduleNext(this.intervalMs))}async poll(){try{const e=this.hostname??(void 0!==globalThis.location?globalThis.location.hostname:void 0),t=await C({subscriptionId:this.subscriptionId,timeoutMs:this.timeoutMs,hostname:e});t.ok?this.cache.set(this.subscriptionId,t.envelope):console.warn(`[MyCookies] Config poll failed (${t.error.code}): ${t.error.message}`)}catch(e){console.warn("[MyCookies] Config poll error:",e instanceof Error?e.message:e)}this.lastPollAt=Date.now()}}function O(e,t,o,i,n){if(!1===(null==i?void 0:i.enabled))return null;if(!1===(null==o?void 0:o.enabled))return null;if(!t)return null;const s=(null==i?void 0:i.intervalMs)??(null==o?void 0:o.intervalMs)??void 0,r=new R({subscriptionId:e,cache:t,intervalMs:s,timeoutMs:n});return r.start(),r}const L="_mycookies_visitor_v1";class P{constructor(e){t(this,"options"),t(this,"unsubscribe",null),this.options=e}start(e){let t=!1;this.unsubscribe=e.onConsentChange(e=>{t&&this.sendEvent(e)}),t=!0}destroy(){var e;null==(e=this.unsubscribe)||e.call(this),this.unsubscribe=null}getOrCreateVisitorId(){try{const e=window.localStorage.getItem(L);if(e)return e;const t=`anon-${w().replace(/-/g,"").slice(0,8)}`;return window.localStorage.setItem(L,t),t}catch{return`anon-${w().replace(/-/g,"").slice(0,8)}`}}determineAction(e){const{categories:t,requiredCategories:o}=this.options,i=t.filter(e=>!o.includes(e));if(0===i.length)return"save_preferences";if(i.every(t=>!0===e[t]))return"accept_all";return i.every(t=>!0!==e[t])?"reject_all":"save_preferences"}sendEvent(e){const{categories:t,configSignature:o}=this.options,i={visitorId:this.getOrCreateVisitorId(),action:this.determineAction(e),granted:t.filter(t=>!0===e[t]),denied:t.filter(t=>!0!==e[t]),timestamp:(new Date).toISOString(),screenWidth:window.screen.width,screenHeight:window.screen.height,locale:navigator.language,timezone:Intl.DateTimeFormat().resolvedOptions().timeZone,pageUrl:window.location.href};o&&(i.configSignature=o);const n=`https://api.mycookies.ws/v1/consent-events/${this.options.subscriptionId}`;fetch(n,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(i)}).then(e=>{e.ok||e.json().then(e=>{if("object"==typeof e&&null!==e&&"error"in e&&"object"==typeof e.error){const t=e.error;console.warn(`[MyCookies] Consent event rejected: ${t.code}`)}}).catch(()=>{})}).catch(()=>{})}}function F(e,t,o,i){if(!o.consentLogging)return null;try{const n=new P({subscriptionId:t,categories:o.categories,requiredCategories:o.requiredCategories,configSignature:i});return n.start(e),n}catch(n){return console.warn("[MyCookies] Failed to start ConsentLogger:",n instanceof Error?n.message:n),null}}const U=["a[href]","button:not([disabled])","input:not([disabled])","select:not([disabled])","textarea:not([disabled])",'[tabindex]:not([tabindex="-1"])'].join(", ");function j(e){return Array.from(e.querySelectorAll(U))}function $(e=document){const t=e.activeElement;return(null==t?void 0:t.shadowRoot)?$(t.shadowRoot):t}function B(e,t){const o=o=>{var i;if("Escape"===o.key)return void(null==(i=null==t?void 0:t.onEscape)||i.call(t));if("Tab"!==o.key)return;const n=j(e);if(0===n.length)return void o.preventDefault();const s=n[0],r=n[n.length-1],a=$();o.shiftKey?a===s&&(o.preventDefault(),r.focus()):a===r&&(o.preventDefault(),s.focus())};e.addEventListener("keydown",o);const i=j(e);return i.length>0&&i[0].focus(),()=>{e.removeEventListener("keydown",o)}}function z(e="modal"){const t=document.createElement("div");return t.className=`mc-backdrop mc-backdrop--${e}`,"modal"===e&&t.setAttribute("data-action","close-modal"),t}function H(e,t,o,i){const n=document.createElement("button");n.className="mc-toggle"+(t?" mc-toggle--on":""),n.setAttribute("role","switch"),n.setAttribute("aria-checked",String(t)),n.setAttribute("aria-labelledby",i),n.setAttribute("data-action","toggle"),n.setAttribute("data-category",e),o&&n.setAttribute("disabled","");const s=document.createElement("span");s.className="mc-toggle__track",n.appendChild(s);const r=document.createElement("span");return r.className="mc-toggle__knob",n.appendChild(r),n}function V(){const e=document.createElement("div");return e.className="mc-tier-badge",e.textContent="Powered by MyCookies",e}function q(e,t,o){const i=document.createElement("button");return i.className=o,i.setAttribute("data-action",t),i.textContent=e,i}function G(e,t){return{...e,categories:t.categories,categoryLabels:{...e.categoryLabels,...t.labels},categoryDescriptions:{...e.categoryDescriptions,...t.descriptions},position:t.branding.position,requiredCategories:t.requiredCategories,tier:t.tier,poweredBy:t.branding.poweredBy,theme:e.theme??t.branding.theme,customCssUrl:e.customCssUrl??t.branding.customCssUrl,scrollLock:t.branding.scrollLock??e.scrollLock}}class W{constructor(e){t(this,"shadowHost"),t(this,"shadowRoot"),t(this,"engine"),t(this,"config"),t(this,"_onDestroy",[]),t(this,"_wiredScriptManager",null),t(this,"_wiredPoller",null),t(this,"currentView","banner"),t(this,"unsubscribe",null),t(this,"deactivateFocusTrap",null),t(this,"modalTriggerSource",null),t(this,"savedBodyOverflow",null),t(this,"savedBodyPaddingRight",null),t(this,"handleClick",e=>{const t=e.target.closest("[data-action]");if(t){const e=t.getAttribute("data-action");e&&this.handleAction(e,t)}}),t(this,"handleExternalConsentChange",e=>{}),this.config=e,e.engine?this.engine=e.engine:(this.engine=d(),this.engine.init({subscriptionId:e.subscriptionId,categories:e.categories})),this.shadowHost=document.createElement("div"),this.shadowHost.setAttribute("data-mycookies-widget",""),this.shadowRoot=this.shadowHost.attachShadow({mode:"open"}),"light"!==e.theme&&"dark"!==e.theme||this.shadowHost.setAttribute("data-theme",e.theme);const o=document.createElement("style");if(o.textContent=':host{--mycookies-bg: #ffffff;--mycookies-text: #1a1a2e;--mycookies-text-secondary: #6b7280;--mycookies-accent: #2563eb;--mycookies-border: #e5e7eb;--mycookies-btn-primary-bg: #1a1a2e;--mycookies-btn-primary-text: #ffffff;--mycookies-btn-secondary-bg: transparent;--mycookies-btn-secondary-text: #1a1a2e;--mycookies-btn-secondary-border: #e5e7eb;--mycookies-toggle-bg: #d1d5db;--mycookies-toggle-bg-on: #2563eb;--mycookies-toggle-knob: #ffffff;--mycookies-backdrop: rgba(0, 0, 0, .4);--mycookies-backdrop-blur: 4px;--mycookies-shadow: 0 -2px 16px rgba(0, 0, 0, .1);--mycookies-shadow-modal: 0 4px 24px rgba(0, 0, 0, .15);--mycookies-fab-shadow: 0 2px 8px rgba(0, 0, 0, .2);--mycookies-focus-ring: #2563eb;--mycookies-font-family: system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;--mycookies-font-size-sm: .875rem;--mycookies-font-size-base: 1rem;--mycookies-font-size-lg: 1.125rem;--mycookies-spacing-xs: .5rem;--mycookies-spacing-sm: .75rem;--mycookies-spacing-md: 1rem;--mycookies-spacing-lg: 1.5rem;--mycookies-radius-sm: .375rem;--mycookies-radius-md: .5rem;--mycookies-radius-lg: .75rem;--mycookies-radius-full: 9999px}@media(prefers-color-scheme:dark){:host{--mycookies-bg: #1a1a2e;--mycookies-text: #e8e8e8;--mycookies-text-secondary: #9ca3af;--mycookies-accent: #3b82f6;--mycookies-border: #374151;--mycookies-btn-primary-bg: #e8e8e8;--mycookies-btn-primary-text: #1a1a2e;--mycookies-btn-secondary-bg: transparent;--mycookies-btn-secondary-text: #e8e8e8;--mycookies-btn-secondary-border: #374151;--mycookies-toggle-bg: #4b5563;--mycookies-toggle-bg-on: #3b82f6;--mycookies-toggle-knob: #ffffff;--mycookies-backdrop: rgba(0, 0, 0, .6);--mycookies-shadow: 0 -2px 16px rgba(0, 0, 0, .3);--mycookies-shadow-modal: 0 4px 24px rgba(0, 0, 0, .4);--mycookies-fab-shadow: 0 2px 8px rgba(0, 0, 0, .4);--mycookies-focus-ring: #3b82f6}}:host([data-theme="light"]){--mycookies-bg: #ffffff;--mycookies-text: #1a1a2e;--mycookies-text-secondary: #6b7280;--mycookies-accent: #2563eb;--mycookies-border: #e5e7eb;--mycookies-btn-primary-bg: #1a1a2e;--mycookies-btn-primary-text: #ffffff;--mycookies-btn-secondary-bg: transparent;--mycookies-btn-secondary-text: #1a1a2e;--mycookies-btn-secondary-border: #e5e7eb;--mycookies-toggle-bg: #d1d5db;--mycookies-toggle-bg-on: #2563eb;--mycookies-toggle-knob: #ffffff;--mycookies-backdrop: rgba(0, 0, 0, .4);--mycookies-shadow: 0 -2px 16px rgba(0, 0, 0, .1);--mycookies-shadow-modal: 0 4px 24px rgba(0, 0, 0, .15);--mycookies-fab-shadow: 0 2px 8px rgba(0, 0, 0, .2);--mycookies-focus-ring: #2563eb}:host([data-theme="dark"]){--mycookies-bg: #1a1a2e;--mycookies-text: #e8e8e8;--mycookies-text-secondary: #9ca3af;--mycookies-accent: #3b82f6;--mycookies-border: #374151;--mycookies-btn-primary-bg: #e8e8e8;--mycookies-btn-primary-text: #1a1a2e;--mycookies-btn-secondary-bg: transparent;--mycookies-btn-secondary-text: #e8e8e8;--mycookies-btn-secondary-border: #374151;--mycookies-toggle-bg: #4b5563;--mycookies-toggle-bg-on: #3b82f6;--mycookies-toggle-knob: #ffffff;--mycookies-backdrop: rgba(0, 0, 0, .6);--mycookies-shadow: 0 -2px 16px rgba(0, 0, 0, .3);--mycookies-shadow-modal: 0 4px 24px rgba(0, 0, 0, .4);--mycookies-fab-shadow: 0 2px 8px rgba(0, 0, 0, .4);--mycookies-focus-ring: #3b82f6}:host,*,*:before,*:after{box-sizing:border-box}:host{font-size:16px;font-family:var(--mycookies-font-family);line-height:1.5;color:var(--mycookies-text)}*:focus-visible{outline:2px solid var(--mycookies-focus-ring);outline-offset:2px}.mc-banner{position:fixed;left:0;right:0;z-index:10000;display:flex;flex-direction:column;justify-content:space-between;gap:var(--mycookies-spacing-md);padding:var(--mycookies-spacing-lg);background:var(--mycookies-bg);box-shadow:var(--mycookies-shadow)}.mc-banner--top{top:0;border-bottom:1px solid var(--mycookies-border)}.mc-banner--bottom{bottom:0;border-top:1px solid var(--mycookies-border)}.mc-banner__content{display:flex;flex-direction:column;gap:var(--mycookies-spacing-sm)}.mc-banner__text{margin:0;font-size:var(--mycookies-font-size-sm);line-height:1.5;color:var(--mycookies-text)}.mc-banner__actions{display:flex;flex-direction:column;gap:var(--mycookies-spacing-xs)}.mc-btn{display:inline-flex;align-items:center;justify-content:center;min-height:44px;padding:var(--mycookies-spacing-xs) var(--mycookies-spacing-md);font-size:var(--mycookies-font-size-sm);font-family:var(--mycookies-font-family);font-weight:600;line-height:1.5;border-radius:var(--mycookies-radius-md);cursor:pointer;transition:opacity .15s ease,box-shadow .15s ease;white-space:nowrap;text-decoration:none;border:none}.mc-btn:hover{opacity:.9}.mc-btn:active{opacity:.8}.mc-btn--primary{background:var(--mycookies-btn-primary-bg);color:var(--mycookies-btn-primary-text)}.mc-btn--secondary{background:var(--mycookies-btn-secondary-bg);color:var(--mycookies-btn-secondary-text);border:1px solid var(--mycookies-btn-secondary-border)}.mc-btn--text{background:transparent;color:var(--mycookies-text-secondary);border:none}.mc-btn--text:hover{color:var(--mycookies-text);opacity:1}.mc-btn--full{width:100%}.mc-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;background:var(--mycookies-backdrop);backdrop-filter:blur(var(--mycookies-backdrop-blur));-webkit-backdrop-filter:blur(var(--mycookies-backdrop-blur))}.mc-backdrop--banner{z-index:9999}.mc-backdrop--modal{z-index:10001}.mc-modal{position:fixed;top:0;right:0;bottom:0;left:0;z-index:10002;display:flex;flex-direction:column;background:var(--mycookies-bg);box-shadow:var(--mycookies-shadow-modal)}.mc-modal__header{display:flex;align-items:center;justify-content:space-between;padding:var(--mycookies-spacing-md) var(--mycookies-spacing-lg);border-bottom:1px solid var(--mycookies-border)}.mc-modal__title{margin:0;font-size:var(--mycookies-font-size-lg);font-weight:700;color:var(--mycookies-text)}.mc-modal__close{display:inline-flex;align-items:center;justify-content:center;padding:var(--mycookies-spacing-xs);background:transparent;border:none;border-radius:var(--mycookies-radius-sm);cursor:pointer;color:var(--mycookies-text-secondary);transition:color .15s ease}.mc-modal__close:hover{color:var(--mycookies-text)}.mc-modal__body{flex:1;overflow-y:auto;padding:var(--mycookies-spacing-lg)}.mc-modal__footer{display:flex;align-items:center;justify-content:flex-end;gap:var(--mycookies-spacing-xs);padding:var(--mycookies-spacing-md) var(--mycookies-spacing-lg);border-top:1px solid var(--mycookies-border)}.mc-modal__footer .mc-tier-badge{margin-left:auto;padding:0}.mc-category{display:flex;align-items:flex-start;justify-content:space-between;gap:var(--mycookies-spacing-md);padding:var(--mycookies-spacing-sm) 0;border-bottom:1px solid var(--mycookies-border)}.mc-category:last-child{border-bottom:none}.mc-category__info{flex:1;min-width:0}.mc-category__name{display:block;font-size:var(--mycookies-font-size-sm);font-weight:600;color:var(--mycookies-text)}.mc-category__desc{display:block;margin-top:.25rem;font-size:var(--mycookies-font-size-sm);color:var(--mycookies-text-secondary)}.mc-toggle{position:relative;flex-shrink:0;cursor:pointer;background:none;border:none;padding:0}.mc-toggle:disabled{cursor:not-allowed;opacity:.5}.mc-toggle__track{display:block;width:44px;height:24px;border-radius:var(--mycookies-radius-full);background:var(--mycookies-toggle-bg);transition:background .2s ease}.mc-toggle--on .mc-toggle__track{background:var(--mycookies-toggle-bg-on)}.mc-toggle__knob{position:absolute;top:2px;left:2px;width:20px;height:20px;border-radius:var(--mycookies-radius-full);background:var(--mycookies-toggle-knob);transition:transform .2s ease;box-shadow:0 1px 3px #0000001a}.mc-toggle--on .mc-toggle__knob{transform:translate(20px)}.mc-fab{position:fixed;z-index:10000;display:inline-flex;align-items:center;justify-content:center;width:48px;height:48px;padding:0;border:none;border-radius:var(--mycookies-radius-full);background:var(--mycookies-btn-primary-bg);color:var(--mycookies-btn-primary-text);box-shadow:var(--mycookies-fab-shadow);cursor:pointer;transition:opacity .15s ease,box-shadow .15s ease}.mc-fab:hover{opacity:.9}.mc-fab--bottom-left{bottom:var(--mycookies-spacing-lg);left:var(--mycookies-spacing-lg)}.mc-fab--bottom-right{bottom:var(--mycookies-spacing-lg);right:var(--mycookies-spacing-lg)}.mc-tier-badge{padding:var(--mycookies-spacing-xs) 0;font-size:.75rem;color:var(--mycookies-text-secondary);text-align:center}@media(min-width:640px){.mc-modal{inset:auto;top:50%;left:50%;transform:translate(-50%,-50%);width:calc(100% - 2 * var(--mycookies-spacing-lg));max-width:560px;max-height:85vh;border:1px solid var(--mycookies-border);border-radius:var(--mycookies-radius-lg)}}@media(min-width:768px){.mc-banner{display:grid;grid-template-columns:1fr auto;grid-template-rows:auto auto;gap:0 var(--mycookies-spacing-md)}.mc-banner__content{grid-column:1;min-width:0}.mc-banner__actions{grid-column:2;grid-row:1 / -1;align-self:center;flex-direction:row;align-items:center;gap:var(--mycookies-spacing-sm)}.mc-btn--full{width:auto}.mc-banner>.mc-tier-badge{grid-column:1;margin-top:var(--mycookies-spacing-xs);text-align:left}}',this.shadowRoot.appendChild(o),e.customCssUrl){const t=document.createElement("link");t.rel="stylesheet",t.href=e.customCssUrl,this.shadowRoot.appendChild(t)}this.shadowRoot.addEventListener("click",this.handleClick),this.unsubscribe=this.engine.onConsentChange(this.handleExternalConsentChange),this.mount(()=>{const e=this.engine.hasStoredConsent()?"idle":"banner";this.show(e)})}static async createWithRemoteConfig(e){var t,o;try{const i=await M({subscriptionId:e.subscriptionId,timeoutMs:null==(t=e.remote)?void 0:t.timeoutMs,onError:null==(o=e.remote)?void 0:o.onError});return W.buildFromPayload(e,i.payload,i.cache,i.envelope.signature)}catch(i){if(!e.categories||0===e.categories.length)throw i;return new W(e)}}static buildFromPayload(e,t,o=null,i){var n,s;const r=G(e,t);if(0===r.categories.length){const t=new p(g.MALFORMED_RESPONSE,"Remote configuration contains no consent categories");if((null==(n=e.remote)?void 0:n.onError)&&e.remote.onError(t),e.categories.length>0)return new W(e);throw t}const a=d(),c=N(a,t.integrations,void 0);a.init({subscriptionId:e.subscriptionId,categories:r.categories,expirationDays:t.consentExpirationDays});const l=F(a,e.subscriptionId,t,i),u=new W({...r,engine:a});if(c.scriptManager){const e=c.scriptManager;u._wiredScriptManager=e,u._addDestroyHook(()=>e.destroy())}if(l){const e=l;u._addDestroyHook(()=>e.destroy())}const h=O(e.subscriptionId,o,t.polling,void 0,null==(s=e.remote)?void 0:s.timeoutMs);return h&&(u._wiredPoller=h,u._addDestroyHook(()=>h.destroy())),u}_addDestroyHook(e){this._onDestroy.push(e)}destroy(){this.shadowRoot.removeEventListener("click",this.handleClick),"banner"!==this.currentView&&"modal"!==this.currentView||this.unlockScroll(),this.deactivateFocusTrap&&(this.deactivateFocusTrap(),this.deactivateFocusTrap=null),this.unsubscribe&&(this.unsubscribe(),this.unsubscribe=null);for(const e of this._onDestroy)try{e()}catch{}this.shadowHost.remove()}showPreferences(){this.show("modal")}getEngine(){return this.engine}mount(e){document.body?(document.body.appendChild(this.shadowHost),e()):document.addEventListener("DOMContentLoaded",()=>{document.body.appendChild(this.shadowHost),e()})}show(e){switch(this.deactivateFocusTrap&&(this.deactivateFocusTrap(),this.deactivateFocusTrap=null),"idle"===e&&this.unlockScroll(),this.clearContent(),this.currentView=e,e){case"banner":this.lockScroll(),this.renderBannerView();break;case"modal":this.lockScroll(),this.renderModalView();break;case"idle":this.renderIdleView()}}renderBannerView(){const e=z("banner");this.shadowRoot.appendChild(e);const t=function(e,t){const o=document.createElement("div");o.className=`mc-banner mc-banner--${t}`,o.setAttribute("role","region"),o.setAttribute("aria-label","Cookie consent");const i=document.createElement("div");i.className="mc-banner__content";const n=document.createElement("p");n.className="mc-banner__text",n.textContent=e.text??"We use cookies to improve your experience. Choose your cookie preferences.",i.appendChild(n);const s=document.createElement("div");s.className="mc-banner__actions",s.setAttribute("role","group"),s.setAttribute("aria-label","Consent choices");const r=q(e.acceptLabel??"Accept All","accept-all","mc-btn mc-btn--primary mc-btn--full");s.appendChild(r);const a=q(e.rejectLabel??"Reject All","reject-all","mc-btn mc-btn--text mc-btn--full");s.appendChild(a);const c=q(e.customizeLabel??"Customize","customize","mc-btn mc-btn--secondary mc-btn--full");return s.appendChild(c),o.appendChild(i),o.appendChild(s),o}(this.config.banner??{},this.config.position??"bottom");if(this.shadowRoot.appendChild(t),"free"===this.config.tier||!0===this.config.poweredBy){const e=V();t.appendChild(e)}}renderModalView(){const e=z("modal");this.shadowRoot.appendChild(e);const t=this.buildCategoryDisplayInfo(),o=this.engine.getConsentState(),i=function(e,t,o){const i=document.createElement("div");i.className="mc-modal",i.setAttribute("role","dialog"),i.setAttribute("aria-modal","true"),i.setAttribute("aria-labelledby","mc-modal-title");const n=document.createElement("div");n.className="mc-modal__header";const s=document.createElement("h2");s.className="mc-modal__title",s.id="mc-modal-title",s.textContent=e.title??"Cookie Preferences",n.appendChild(s);const r=document.createElement("button");r.className="mc-modal__close",r.setAttribute("data-action","close-modal"),r.setAttribute("aria-label","Close cookie preferences"),r.innerHTML='<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><line x1="5" y1="5" x2="15" y2="15"/><line x1="15" y1="5" x2="5" y2="15"/></svg>',n.appendChild(r),i.appendChild(n);const a=document.createElement("div");a.className="mc-modal__body";for(const d of t){const e=document.createElement("div");e.className="mc-category";const t=document.createElement("div");t.className="mc-category__info";const i=`mc-cat-${d.key}`,n=document.createElement("span");n.className="mc-category__name",n.id=i,n.textContent=d.label,t.appendChild(n);const s=document.createElement("span");s.className="mc-category__desc",s.textContent=d.description,t.appendChild(s),e.appendChild(t);const r=!0===d.required,c=!!r||!0===o[d.key],l=H(d.key,c,r,i);r&&l.setAttribute("aria-disabled","true"),e.appendChild(l),a.appendChild(e)}i.appendChild(a);const c=document.createElement("div");c.className="mc-modal__footer";const l=q(e.saveLabel??"Save Preferences","save-preferences","mc-btn mc-btn--primary");return c.appendChild(l),i.appendChild(c),i}(this.config.modal??{},t,o);if("free"===this.config.tier||!0===this.config.poweredBy){const e=i.querySelector(".mc-modal__footer");if(e){const t=V();e.appendChild(t)}}this.shadowRoot.appendChild(i),this.deactivateFocusTrap=B(i,{onEscape:()=>this.handleAction("close-modal")})}renderIdleView(){const e=function(e){const t=document.createElement("button"),o=e.position??"bottom-right";return t.className=`mc-fab mc-fab--${o}`,t.setAttribute("data-action","open-modal"),t.setAttribute("aria-label",e.ariaLabel??"Cookie preferences"),t.innerHTML='<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M10.343 3.94c.09-.542.56-.94 1.11-.94h1.093c.55 0 1.02.398 1.11.94l.149.894c.07.424.384.764.78.93.398.164.855.142 1.205-.108l.737-.527a1.125 1.125 0 0 1 1.45.12l.773.774c.39.389.44 1.002.12 1.45l-.527.737c-.25.35-.272.806-.107 1.204.165.397.505.71.93.78l.893.15c.543.09.94.559.94 1.109v1.094c0 .55-.397 1.02-.94 1.11l-.894.149c-.424.07-.764.383-.929.78-.165.398-.143.854.107 1.204l.527.738c.32.447.269 1.06-.12 1.45l-.774.773a1.125 1.125 0 0 1-1.449.12l-.738-.527c-.35-.25-.806-.272-1.203-.107-.398.165-.71.505-.781.929l-.149.894c-.09.542-.56.94-1.11.94h-1.094c-.55 0-1.019-.398-1.11-.94l-.148-.894c-.071-.424-.384-.764-.781-.93-.398-.164-.854-.142-1.204.108l-.738.527c-.447.32-1.06.269-1.45-.12l-.773-.774a1.125 1.125 0 0 1-.12-1.45l.527-.737c.25-.35.272-.806.108-1.204-.165-.397-.506-.71-.93-.78l-.894-.15c-.542-.09-.94-.56-.94-1.109v-1.094c0-.55.398-1.02.94-1.11l.894-.149c.424-.07.765-.383.93-.78.165-.398.143-.854-.108-1.204l-.526-.738a1.125 1.125 0 0 1 .12-1.45l.773-.773a1.125 1.125 0 0 1 1.45-.12l.737.527c.35.25.807.272 1.204.107.397-.165.71-.505.78-.929l.15-.894Z"/><path d="M15 12a3 3 0 1 1-6 0 3 3 0 0 1 6 0Z"/></svg>',t}(this.config.floatingButton??{});this.shadowRoot.appendChild(e)}handleAction(e,t){switch(e){case"accept-all":{const e=this.buildAllState(!0);this.engine.updateConsent(e),this.show("idle");break}case"reject-all":{const e=this.buildAllState(!1);this.engine.updateConsent(e),this.show("idle");break}case"customize":this.modalTriggerSource="customize",this.show("modal");break;case"save-preferences":{const e=this.getToggleStates();this.engine.updateConsent(e),this.show("idle");break}case"close-modal":this.engine.hasStoredConsent()?this.show("idle"):this.show("banner"),this.restoreFocusAfterModalClose(),this.modalTriggerSource=null;break;case"open-modal":this.modalTriggerSource="fab",this.show("modal");break;case"toggle":this.handleToggle(t)}}restoreFocusAfterModalClose(){if("customize"===this.modalTriggerSource){const e=this.shadowRoot.querySelector('[data-action="customize"]');null==e||e.focus()}else if("fab"===this.modalTriggerSource){const e=this.shadowRoot.querySelector('[data-action="open-modal"]');null==e||e.focus()}}handleToggle(e){if(!e)return;if(e.hasAttribute("disabled"))return;e.classList.contains("mc-toggle--on")?(e.classList.remove("mc-toggle--on"),e.setAttribute("aria-checked","false")):(e.classList.add("mc-toggle--on"),e.setAttribute("aria-checked","true"))}getToggleStates(){const e={},t=this.shadowRoot.querySelectorAll('[data-action="toggle"]');for(const i of t){const t=i.getAttribute("data-category");t&&(e[t]=i.classList.contains("mc-toggle--on"))}const o=this.config.requiredCategories??[];for(const i of o)e[i]=!0;return e}buildAllState(e){const t={};for(const o of this.config.categories)t[o]=e;return t}buildCategoryDisplayInfo(){const e=this.config.requiredCategories??[];return this.config.categories.map(t=>{var o,i;return{key:t,label:(null==(o=this.config.categoryLabels)?void 0:o[t])??t.charAt(0).toUpperCase()+t.slice(1),description:(null==(i=this.config.categoryDescriptions)?void 0:i[t])??"",required:e.includes(t)}})}clearContent(){const e=Array.from(this.shadowRoot.childNodes);for(const t of e)if(t instanceof HTMLElement){const e=t.tagName.toLowerCase();"style"!==e&&"link"!==e&&t.remove()}}lockScroll(){if(!1===this.config.scrollLock)return;if(this.config.onScrollLockChange)return void this.config.onScrollLockChange(!0);if(null!==this.savedBodyOverflow)return;const e=window.innerWidth-document.documentElement.clientWidth;if(this.savedBodyOverflow=document.documentElement.style.overflow,this.savedBodyPaddingRight=document.documentElement.style.paddingRight,document.documentElement.style.overflow="hidden",e>0){const t=parseFloat(getComputedStyle(document.documentElement).paddingRight)||0;document.documentElement.style.paddingRight=`${t+e}px`}}unlockScroll(){!1!==this.config.scrollLock&&(this.config.onScrollLockChange?this.config.onScrollLockChange(!1):(null!==this.savedBodyOverflow&&(document.documentElement.style.overflow=this.savedBodyOverflow,this.savedBodyOverflow=null),null!==this.savedBodyPaddingRight&&(document.documentElement.style.paddingRight=this.savedBodyPaddingRight,this.savedBodyPaddingRight=null)))}}const K=/^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;function J(e){if(!K.test(e))throw new Error(`Invalid subscriptionId format: "${e}". Expected a valid UUID v4.`)}const Z="0.0.0";exports.ConfigCache=_,exports.ConfigError=p,exports.ConfigErrorCode=g,exports.ConfigPoller=R,exports.ConsentEngine=i,exports.ConsentLogger=P,exports.CookieStorageAdapter=a,exports.GoogleConsentModeProvider=m,exports.LocalStorageAdapter=r,exports.ScriptManager=T,exports.VERSION=Z,exports.WidgetController=W,exports.createConsentEngine=d,exports.createValidatedEngine=async function(e){var t,o,i;J(e.subscriptionId);const n=await M({subscriptionId:e.subscriptionId,timeoutMs:null==(t=e.remote)?void 0:t.timeoutMs,onError:null==(o=e.remote)?void 0:o.onError}),s=d({storage:e.storage}),r=N(s,n.payload.integrations,void 0);return s.init({subscriptionId:e.subscriptionId,categories:n.payload.categories,expirationDays:n.payload.consentExpirationDays}),r.consentLogger=F(s,e.subscriptionId,n.payload,n.envelope.signature),{engine:s,integrations:r,poller:O(e.subscriptionId,n.cache,n.payload.polling,e.polling,null==(i=e.remote)?void 0:i.timeoutMs)}},exports.createWidget=async function(e){var t,o,i,n;J(e.subscriptionId);const s=await M({subscriptionId:e.subscriptionId,timeoutMs:null==(t=e.remote)?void 0:t.timeoutMs,onError:null==(o=e.remote)?void 0:o.onError}),r=O(e.subscriptionId,s.cache,s.payload.polling,e.polling,null==(i=e.remote)?void 0:i.timeoutMs);if(0===s.payload.categories.length){const t=new p(g.MALFORMED_RESPONSE,"Remote configuration contains no consent categories");throw(null==(n=e.remote)?void 0:n.onError)&&e.remote.onError(t),t}let a=e.engine,c=null,l=null;if(!a){a=d({storage:e.storage});c=N(a,s.payload.integrations,e.integrations).scriptManager,a.init({subscriptionId:e.subscriptionId,categories:s.payload.categories,expirationDays:s.payload.consentExpirationDays}),l=F(a,e.subscriptionId,s.payload,s.envelope.signature)}const u=G({subscriptionId:e.subscriptionId,categories:[],banner:e.banner,modal:e.modal,floatingButton:e.floatingButton,theme:e.theme,customCssUrl:e.customCssUrl,scrollLock:e.scrollLock,onScrollLockChange:e.onScrollLockChange,engine:a},s.payload),h=new W(u);if(c){const e=c;h._addDestroyHook(()=>e.destroy())}if(l){const e=l;h._addDestroyHook(()=>e.destroy())}return r&&h._addDestroyHook(()=>r.destroy()),h},exports.detectStorage=l,exports.isCryptoAvailable=f,exports.isDomainAuthorized=v,exports.mergeRemoteConfig=G,exports.resolveConfig=C,exports.validateSubscriptionUuid=J;
package/dist/index.d.ts CHANGED
@@ -196,6 +196,12 @@ export declare interface ConsentConfig {
196
196
  subscriptionId: string;
197
197
  /** List of consent categories the tenant uses */
198
198
  categories: ConsentCategory[];
199
+ /**
200
+ * Number of days after which stored consent is considered expired.
201
+ * Absent or undefined falls back to the engine's built-in 365-day default.
202
+ * Must be sourced from the signed remote config payload — never from user input.
203
+ */
204
+ expirationDays?: number;
199
205
  }
200
206
 
201
207
  /**
@@ -763,6 +769,14 @@ export declare interface RemoteConfigPayload {
763
769
  * framework (e.g. 'gdpr') to the subscription in the portal.
764
770
  */
765
771
  consentLogging?: boolean;
772
+ /**
773
+ * Number of days after which stored consent is considered expired and the
774
+ * consent banner is shown again. Determined server-side by the legal framework
775
+ * configured for the subscription (e.g. 365 for GDPR).
776
+ *
777
+ * Absent from the payload means the client falls back to the 365-day default.
778
+ */
779
+ consentExpirationDays?: number;
766
780
  }
767
781
 
768
782
  /** Signed envelope wrapping the config payload */
package/dist/index.es.js CHANGED
@@ -2,6 +2,7 @@ var __defProp = Object.defineProperty;
2
2
  var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
3
3
  var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
4
4
  const STORAGE_KEY_PREFIX = "_mycookies_consent_v1_";
5
+ const CONSENT_EXPIRATION_DEFAULT_DAYS = 365;
5
6
  class ConsentEngine {
6
7
  constructor(storage, eventBus, providerRegistry) {
7
8
  __publicField(this, "config", null);
@@ -26,8 +27,14 @@ class ConsentEngine {
26
27
  this.validateConfig(config);
27
28
  const storageKey = STORAGE_KEY_PREFIX + config.subscriptionId;
28
29
  const envelope = this.storage.get(storageKey);
30
+ const expirationMs = (config.expirationDays ?? CONSENT_EXPIRATION_DEFAULT_DAYS) * 24 * 60 * 60 * 1e3;
29
31
  if (envelope !== null && this.isValidEnvelope(envelope)) {
30
- this.state = this.buildStateFromStored(config.categories, envelope.state);
32
+ if (Date.now() - envelope.updatedAt > expirationMs) {
33
+ this.storage.clear(storageKey);
34
+ this.state = this.buildDefaultState(config.categories);
35
+ } else {
36
+ this.state = this.buildStateFromStored(config.categories, envelope.state);
37
+ }
31
38
  } else {
32
39
  this.state = this.buildDefaultState(config.categories);
33
40
  }
@@ -2120,7 +2127,8 @@ class WidgetController {
2120
2127
  const wired = wireIntegrations(engine, payload.integrations, void 0);
2121
2128
  engine.init({
2122
2129
  subscriptionId: config.subscriptionId,
2123
- categories: mergedConfig.categories
2130
+ categories: mergedConfig.categories,
2131
+ expirationDays: payload.consentExpirationDays
2124
2132
  });
2125
2133
  const consentLogger = wireConsentLogger(engine, config.subscriptionId, payload, configSignature);
2126
2134
  const controller = new WidgetController({ ...mergedConfig, engine });
@@ -2446,7 +2454,8 @@ async function createWidget(options) {
2446
2454
  wiredScriptManager = wired.scriptManager;
2447
2455
  engine.init({
2448
2456
  subscriptionId: options.subscriptionId,
2449
- categories: result.payload.categories
2457
+ categories: result.payload.categories,
2458
+ expirationDays: result.payload.consentExpirationDays
2450
2459
  });
2451
2460
  wiredConsentLogger = wireConsentLogger(
2452
2461
  engine,
@@ -2495,7 +2504,8 @@ async function createValidatedEngine(options) {
2495
2504
  const integrations = wireIntegrations(engine, result.payload.integrations, void 0);
2496
2505
  engine.init({
2497
2506
  subscriptionId: options.subscriptionId,
2498
- categories: result.payload.categories
2507
+ categories: result.payload.categories,
2508
+ expirationDays: result.payload.consentExpirationDays
2499
2509
  });
2500
2510
  integrations.consentLogger = wireConsentLogger(
2501
2511
  engine,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mycookies/widget",
3
- "version": "0.2.1",
3
+ "version": "0.2.2",
4
4
  "type": "module",
5
5
  "description": "Privacy-first cookie consent client library with embeddable widget and headless SDK from My Cookies service.",
6
6
  "license": "UNLICENSED",