@cookieyes/core 0.2.0 → 0.4.0

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.
package/README.md CHANGED
@@ -192,16 +192,90 @@ methods (`acceptAll()`, `rejectAll()`, `acceptSelected(cats)`, `updateCategory(c
192
192
  > `overrides.regulation` alias still works) and defaults to `"DEFAULT"`. The core engine does not
193
193
  > perform IP-based geo-detection.
194
194
 
195
+ ## Reacting to consent changes
196
+
197
+ To run your own code when a visitor grants or withdraws consent, use
198
+ `consentStore.on(type, listener, options?)`:
199
+
200
+ ```ts
201
+ const { consentStore } = initCookieYes({ mode: "cookie-only" });
202
+
203
+ // "change" fires only when a category actually differs — the right place to
204
+ // (re)load a script, so a re-confirm of the same choices doesn't run it again.
205
+ const off = consentStore.on("change", ({ changedCategories }) => {
206
+ if (changedCategories.includes("analytics")) loadAnalytics();
207
+ });
208
+
209
+ // "save" fires on every save, even an unchanged re-confirm.
210
+ consentStore.on("save", () => toast("Preferences saved"));
211
+
212
+ off(); // stop listening when you're done
213
+ ```
214
+
215
+ - The listener fires **once immediately** with the current state
216
+ (`isInitial: true`), so a late listener isn't blind to earlier choices.
217
+ - Pass `{ category: "analytics" }` to only hear about one category.
218
+ - Payload: `{ categories, changedCategories, isInitial }`.
219
+
220
+ This is the recommended way to react to consent. The paths below still work but
221
+ aren't the primary one.
222
+
223
+ ## Translations & language
224
+
225
+ For a framework-less custom UI, `consentStore` carries the active language and
226
+ lets you switch it live (no reload):
227
+
228
+ ```ts
229
+ const { consentStore } = initCookieYes({
230
+ mode: "cookie-only",
231
+ i18n: { messages: { fr } }, // languages you support; each may be partial
232
+ });
233
+
234
+ consentStore.translations.acceptAll; // text for the active language
235
+ consentStore.getLanguageInfo(); // { language, direction, languages }
236
+
237
+ consentStore.subscribe(() => render()); // re-render on consent OR language change
238
+ await consentStore.setLanguage("fr"); // switch live; loads via i18n.loadLanguage if needed
239
+ ```
240
+
241
+ Missing text falls back to English; custom categories translate by id (see the
242
+ [configuration guide](https://github.com/cookieyes/cookieyes/blob/main/docs/configuration.md)).
243
+ In React, use the `useTranslations()` / `useLanguage()` hooks instead.
244
+
245
+ ## Region-based regulation (geo-detection)
246
+
247
+ Optionally pick the regulation from the visitor's region. Fully optional; a manual
248
+ `regulation` always wins.
249
+
250
+ ```ts
251
+ const { consentStore } = initCookieYes({
252
+ mode: "cookie-only",
253
+ region: {
254
+ // `detect` is YOUR function — return the visitor's region, however you get it (sync).
255
+ detect: () => myRegion, // "US-CA" | "DE" | undefined
256
+ map: { "US-CA": "CCPA", DE: "GDPR" }, // you own the mapping
257
+ honorGpc: true, // default; browser "do not sell" signal → CCPA
258
+ },
259
+ });
260
+
261
+ consentStore.getRegion(); // { region, regulation, source, confidence }
262
+ ```
263
+
264
+ `detect` runs synchronously — you return a region you already have (server-injected value, your
265
+ own lookup done beforehand, etc.). Unknown/failed detection → the strictest regulation
266
+ (default `GDPR`), never a skipped banner. In self-hosted mode the detected region is included on
267
+ the consent-log payload.
268
+
195
269
  ## Low-level / advanced API
196
270
 
197
271
  You shouldn't need these for a typical integration — each exists for a
198
- specific narrower situation than `consentStore.subscribe`:
272
+ specific narrower situation than `consentStore.on` / `consentStore.subscribe`:
199
273
 
200
274
  | API | Use when |
201
275
  |---|---|
202
- | `subscribeToConsentChanges(listener)` (on `consentStore.getState()`) | You only care about *saved* consent decisions (accept/reject/save), not every transient toggle or dialog open/close that `subscribe` also reports. |
276
+ | `subscribeToConsentChanges(listener)` (on `consentStore.getState()`) | Predates `consentStore.on`; fires on saved changes but without the `change`/`save` split, the `isInitial` flag, or per-category filtering. Prefer `on`. |
203
277
  | `onConsentReady` (config option) | You need a one-time callback right after the initial state is known — e.g. conditionally loading analytics on first load — rather than an ongoing subscription. |
204
- | `onConsentUpdate` (config option) | Like `subscribeToConsentChanges`, scoped to saved changes only, but registered once at config time instead of dynamically after mount. Prefer `subscribeToConsentChanges` unless you specifically need a config-time callback. |
278
+ | `onConsentUpdate` (config option) | A saved-changes callback registered once at config time instead of dynamically after mount. Prefer `consentStore.on` unless you specifically need a config-time callback. |
205
279
  | `createConsentManager(config)` | Bypasses `consentStore` entirely for direct access to the manager: `acceptAll()`, `rejectAll()`, `acceptSelected(cats)`, `updateCategory(cat, val)`, `savePreferences()`, `resetConsent()`, `showPreferences()`, `hidePreferences()`, `subscribe(fn)`, `registerScript(entry)`. `config` (`ConsentConfig`) accepts `regulation`, `colorScheme`, `theme`, `apiUrl`, `apiKey`, `backend`, `reloadOnRevoke`, `onConsentReady`, `onConsentUpdate`. |
206
280
  | `parseCookie` / `serializeCookie` | Reading or writing the raw `cookieyes-consent` cookie directly — e.g. in a Next.js Server Component or route handler, where no live runtime or React hooks are available. |
207
281
 
@@ -209,24 +283,36 @@ specific narrower situation than `consentStore.subscribe`:
209
283
 
210
284
  When a visitor revokes consent, the SDK stops tracking **without reloading the
211
285
  page** — nothing they were doing (form input, scroll position, an open dialog)
212
- is lost. There are three layers:
286
+ is lost.
287
+
288
+ > **Gating vs. stopping.** The cleanest way to handle a third-party script is to
289
+ > **gate** it — never load it until its category is granted — with the
290
+ > `integrations` option and a preset from
291
+ > [`@cookieyes/scripts`](https://github.com/cookieyes/cookieyes/tree/main/sdk/scripts).
292
+ > The layers below are for scripts that are *already loaded* (first-party
293
+ > vendors, your own tags) and need to be stopped when consent is withdrawn.
294
+
295
+ There are three layers:
213
296
 
214
297
  1. **Network blocking** (`networkBlocker` / `blockNetwork`) — intercepts
215
298
  `fetch`, `XMLHttpRequest`, **and `navigator.sendBeacon`** to blocked domains,
216
299
  in real time, for as long as the page is open. `sendBeacon` matters because
217
300
  GA4/Meta use it for exit/unload tracking that fetch/XHR interception misses.
218
- 2. **Integration stop-handlers** (`integrations`) — call a vendor's own
301
+ 2. **Built-in stop-handlers** (`builtInIntegrations`) — call a vendor's own
219
302
  documented "stop" API on revoke, and resume it on re-accept:
220
303
 
221
304
  ```ts
222
305
  getOrCreateConsentRuntime({
223
306
  mode: "cookie-only",
224
- integrations: [
307
+ builtInIntegrations: [
225
308
  { vendor: "meta" }, // fbq('consent','revoke'|'grant')
226
309
  ],
227
310
  });
228
311
  ```
229
312
 
313
+ > `builtInIntegrations` was previously called `integrations`; that name now
314
+ > refers to the gated presets from `@cookieyes/scripts` (see the note above).
315
+
230
316
  > **Google Analytics & Tag Manager are handled automatically** — you don't
231
317
  > list them here. The SDK broadcasts Google Consent Mode v2 whenever a
232
318
  > `dataLayer` is present (see [Google Consent Mode](#google-consent-mode-v2)
@@ -247,7 +333,7 @@ is lost. There are three layers:
247
333
 
248
334
  | Vendor | Runtime stop | How |
249
335
  |--------|-------------|-----|
250
- | **Google Analytics 4 / Tag Manager** | ✅ automatic | Consent Mode v2 broadcast — no `integrations` entry needed (see [below](#google-consent-mode-v2)). |
336
+ | **Google Analytics 4 / Tag Manager** | ✅ automatic | Consent Mode v2 broadcast — no `builtInIntegrations` entry needed (see [below](#google-consent-mode-v2)). |
251
337
  | **Meta Pixel** | ✅ clean | `fbq('consent', 'revoke')` / `'grant'` |
252
338
  | TikTok Pixel | ⚠️ reload | No runtime stop we could confidently verify; modelled as reload-only. |
253
339
  | LinkedIn Insight Tag | ⚠️ reload | No documented runtime opt-out after load. |
@@ -258,6 +344,11 @@ is lost. There are three layers:
258
344
  never continues tracking them silently. Any of them can be upgraded to a clean
259
345
  stop later (in `resolveBuiltInIntegration`) once a real runtime API is confirmed.
260
346
 
347
+ > Better still, **gate** the vendor instead of stopping it after the fact:
348
+ > [`@cookieyes/scripts`](https://github.com/cookieyes/cookieyes/tree/main/sdk/scripts)
349
+ > ships a Segment preset (`segment()`) that never loads until consent and is
350
+ > removed on revoke — so there's nothing to reload.
351
+
261
352
  ### Reload notice
262
353
 
263
354
  If a revoked tool has no clean runtime stop, the manager computes
@@ -348,7 +439,7 @@ visitor actually agreed to.
348
439
  If a Google `dataLayer` is present on the page, the SDK **broadcasts** all seven
349
440
  Consent Mode v2 signals — on load and on every consent change — for every
350
441
  visitor. This is what governs Google Analytics 4 and Tag Manager; you do **not**
351
- register them under `integrations`.
442
+ register them under `builtInIntegrations`.
352
443
 
353
444
  Each signal is `granted` when any granted category maps to it (via its `gcm`
354
445
  field), otherwise `denied`. `security_storage` is always `granted`. The built-in
package/dist/index.cjs CHANGED
@@ -1,2 +1,2 @@
1
- "use strict";const e="cookieyes-consent",t=new Set(["consentid","consent","action","tax","lastRenewedDate"]);function o(e){const o={categories:{}};for(const n of e.split(",")){const e=n.indexOf(":");if(-1===e)continue;const r=n.slice(0,e).trim(),s=n.slice(e+1).trim();t.has(r)?o[r]=s:r.length>0&&(o.categories[r]=s)}return o}function n(e){const t=[`consentid:${e.consentId}`,"consent:"+(e.hasActed?"yes":"no"),"action:"+(e.hasActed?"yes":"no")];e.taxonomyHash&&t.push(`tax:${e.taxonomyHash}`);for(const[o,n]of Object.entries(e.categories))t.push(`${o}:${n?"yes":"no"}`);return t.push(`lastRenewedDate:${e.lastRenewed??Date.now()}`),t.join(",")}function r(t){if("undefined"==typeof document)return;const o=encodeURIComponent(n(t));document.cookie=`${e}=${o}; max-age=31536000; path=/; SameSite=Lax`}function s(){"undefined"!=typeof document&&(document.cookie=`${e}=; max-age=0; path=/`)}function a(){const e=new Uint8Array(32);if("undefined"!=typeof crypto&&crypto.getRandomValues)crypto.getRandomValues(e);else for(let t=0;t<e.length;t++)e[t]=Math.floor(256*Math.random());return btoa(String.fromCharCode(...e)).replace(/\+/g,"-").replace(/\//g,"_").replace(/=/g,"").slice(0,44)}function i(e,t,o){const n="CCPA"===t,r={};for(const e of o.ids)r[e]=!!o.requiredIds.has(e)||n;return{consentId:e,hasActed:!1,categories:r,regulation:t,taxonomyHash:o.taxonomyHash}}const c=[{id:"necessary",required:!0},{id:"functional",gcm:["functionality_storage","personalization_storage"]},{id:"analytics",gcm:["analytics_storage"]},{id:"performance"},{id:"advertisement",gcm:["ad_storage","ad_user_data","ad_personalization"]}];function d(e){let t=2166136261;for(let o=0;o<e.length;o++)t^=e.charCodeAt(o),t=Math.imul(t,16777619);return(t>>>0).toString(36)}function l(e,t){const o=e.map(e=>e.id),n=new Set(e.filter(e=>e.required).map(e=>e.id)),r=e.map(e=>`${e.id}:${e.required?1:0}:${(e.gcm??[]).join("+")}`).join("|");return{list:e,ids:o,requiredIds:n,taxonomyHash:d(r),isDefault:t}}function u(e){if(!e||0===e.length)return l(c,!0);const o=function(e){const o=e.map(e=>e.id);return o.some(e=>"string"!=typeof e||0===e.length)?"every category needs a non-empty string id":o.some(e=>e.includes(",")||e.includes(":"))?"category ids must not contain ',' or ':'":new Set(o).size!==o.length?"category ids must be unique":o.some(e=>t.has(e))?`category ids must not be one of the reserved keys: ${[...t].join(", ")}`:e.some(e=>!0===e.required)?null:"at least one category must be marked { required: true }"}(e);return o?("undefined"!=typeof console&&console.warn(`[cookieyes] Invalid categories config (${o}). Falling back to the default five (necessary, functional, analytics, performance, advertisement).`),l(c,!0)):l(e,!1)}function f(e){"undefined"!=typeof console&&console.warn(e)}function g(e){const t={mode:e.mode},o=e.overrides?.regulation;return void 0!==e.regulation?(t.regulation=e.regulation,void 0!==o&&f("[CookieYes] Received both `regulation` and the deprecated `overrides.regulation`. Using the top-level `regulation` and ignoring `overrides`. Drop the `overrides` object — it is deprecated and will be removed after three release cycles.")):void 0!==o&&(t.regulation=o),void 0!==e.colorScheme&&(t.colorScheme=e.colorScheme),void 0!==e.theme&&(t.theme=e.theme),void 0!==e.i18n&&(t.i18n=e.i18n),void 0!==e.consentCategories&&(t.consentCategories=e.consentCategories),void 0!==e.categories&&(t.categories=e.categories),void 0!==e.networkBlocker&&(t.networkBlocker=e.networkBlocker),void 0!==e.reloadOnRevoke&&(t.reloadOnRevoke=e.reloadOnRevoke),void 0!==e.integrations&&(t.integrations=e.integrations),void 0!==e.customStopHandlers&&(t.customStopHandlers=e.customStopHandlers),void 0!==e.onConsentReady&&(t.onConsentReady=e.onConsentReady),void 0!==e.onConsentUpdate&&(t.onConsentUpdate=e.onConsentUpdate),"self-hosted"===e.mode&&(void 0!==e.apiKey&&(t.apiKey=e.apiKey),void 0!==e.backend&&(t.backend=e.backend),void 0!==e.apiUrl?(t.apiUrl=e.apiUrl,void 0!==e.backendURL&&f("[CookieYes] Received both `apiUrl` and the deprecated `backendURL`. Using `apiUrl` and ignoring `backendURL`. Rename `backendURL` to `apiUrl` — the alias is deprecated and will be removed after three release cycles.")):void 0!==e.backendURL&&(t.apiUrl=e.backendURL)),t}let p=!1;function h(){p||(p=!0,"undefined"!=typeof console&&console.warn('[cookieyes] mode: "offline" has been renamed to "cookie-only". Both do exactly the same thing, but "offline" is deprecated and will be removed in 3 releases. Update to .mode("cookie-only") (or { mode: "cookie-only" }).'))}const y=["ad_storage","ad_user_data","ad_personalization","analytics_storage","functionality_storage","personalization_storage","security_storage"];function m(e,t){const o={};for(const e of y)o[e]="denied";o.security_storage="granted";for(const n of e.list)if(n.gcm&&0!==n.gcm.length&&t[n.id])for(const e of n.gcm)o[e]="granted";return o}function w(e,t){if("undefined"==typeof window||!Array.isArray(window.dataLayer))return;const o=m(e,t),n=window.dataLayer;if(!n)return;!function(){n.push(arguments)}("consent","update",o)}const v={bannerTitle:"We value your privacy",bannerDescription:"We use cookies to enhance your browsing experience, serve personalised ads or content, and analyse our traffic. By clicking “Accept All”, you consent to our use of cookies.",acceptAll:"Accept All",rejectAll:"Reject All",managePreferences:"Customise",savePreferences:"Save My Preferences",doNotSell:"Do Not Sell or Share My Personal Information",ccpaDescription:"This website or its third-party tools process personal data. You can opt out of the sale of your personal information by clicking on the “Do Not Sell or Share My Personal Information” link.",accept:"Accept",poweredBy:"Powered by CookieYes",preferencesTitle:"Customise Consent Preferences",preferencesIntro:"We use cookies to help you navigate efficiently and perform certain functions. You will find detailed information about all cookies under each consent category below.",categories:{necessary:{label:"Necessary",description:"Necessary cookies are required to enable the basic features of this site, such as providing secure log-in or adjusting your consent preferences. These cookies do not store any personally identifiable data."},functional:{label:"Functional",description:"Functional cookies help perform certain functionalities like sharing the content of the website on social media platforms, collecting feedback, and other third-party features."},analytics:{label:"Analytics",description:"Analytical cookies are used to understand how visitors interact with the website. These cookies help provide information on metrics such as the number of visitors, bounce rate, traffic source, etc."},performance:{label:"Performance",description:"Performance cookies are used to understand and analyse the key performance indexes of the website which helps in delivering a better user experience for the visitors."},advertisement:{label:"Advertisement",description:"Advertisement cookies are used to provide visitors with customised advertisements based on the pages you visited previously and to analyse the effectiveness of the ad campaigns."}},optOut:{title:"Opt-out Preferences",description:'We use third-party cookies that help us analyse how you use this website, store your preferences, and provide the content and advertisements that are relevant to you. However, you can opt out of these cookies by checking "Do Not Sell or Share My Personal Information" and clicking the "Save My Preferences" button. Once you opt out, you can opt in again at any time by unchecking "Do Not Sell or Share My Personal Information" and clicking the "Save My Preferences" button.',cancel:"Cancel",successText:"Your opt-out preference has been honored.",successCountdown:"Banner closes automatically in {seconds} s..."},reloadNotice:{message:"Some tracking on this page can only be fully stopped by reloading. Reload to apply your change, or dismiss to keep browsing.",reloadButton:"Reload page",dismissButton:"Dismiss"}};const k=new Map,b=new Map;function C(e,t){if(document.getElementById(e))return;const o=document.createElement("script");o.id=e,o.src=t.src,o.async=!0,t.onLoad&&o.addEventListener("load",t.onLoad,{once:!0}),document.head.appendChild(o),b.set(e,o)}function R(e){return"needsReload"in e&&!0===e.needsReload}function S(e){switch(e.vendor){case"meta":return{id:"meta",category:e.category??"advertisement",stop:()=>window.fbq?.("consent","revoke"),resume:()=>window.fbq?.("consent","grant")};case"tiktok":return{id:"tiktok",category:e.category??"advertisement",needsReload:!0};case"linkedin":return{id:"linkedin",category:e.category??"advertisement",needsReload:!0};case"hotjar":return{id:"hotjar",category:e.category??"analytics",needsReload:!0};case"segment":return{id:"segment",category:e.category??"analytics",needsReload:!0}}}const x=new Map,U=new Set,A=new Set;function B(e){x.set(e.id,e)}function I(e){const t=[];for(const o of x.values()){const n=!0!==e[o.category];if(R(o))n?A.has(o.id)&&(t.push(o.id),A.delete(o.id)):A.add(o.id);else if(n){if(!U.has(o.id))try{o.stop(),U.add(o.id)}catch{t.push(o.id)}}else if(U.has(o.id)){U.delete(o.id);try{o.resume?.()}catch{}}}return{reloadRequiredBy:t}}function H(e){return{consentId:e.consentId,categories:e.categories,regulation:e.regulation,domain:"undefined"!=typeof window?window.location.hostname:"unknown"}}function O(t){const n=new Set,c=u(t.categories);let d,l,f,g=!1;function p(e){const t={};for(const o of c.ids)t[o]=!!c.requiredIds.has(o)||e(o);return t}let h=[],y=!1;for(const e of t.integrations??[])B(S(e));for(const e of t.customStopHandlers??[])B(e);const m=function(){if("undefined"==typeof document)return null;const t=document.cookie.split(";");for(const n of t){const t=n.trim(),r=t.indexOf("=");if(-1!==r&&t.slice(0,r).trim()===e){const e=t.slice(r+1).trim();return o(decodeURIComponent(e))}}return null}(),v=t.regulation??"DEFAULT",O=m?.tax,P=O===c.taxonomyHash,L=null!=m&&(P||void 0===O&&c.isDefault);if(null!=m&&L)d=function(e,t,o){const n={};for(const t of o.ids)n[t]=!!o.requiredIds.has(t)||"yes"===e.categories[t];return{consentId:e.consentid??a(),hasActed:"yes"===e.action,categories:n,regulation:t,lastRenewed:e.lastRenewedDate?Number(e.lastRenewedDate):void 0,taxonomyHash:e.tax}}(m,v,c);else{const e=m?.consentid??a();d=i(e,v,c),null!=m&&s(),"CCPA"===d.regulation&&r(d)}function _(){const e={consentId:d.consentId,hasActed:d.hasActed,categories:{...d.categories},regulation:d.regulation,lastRenewed:d.lastRenewed,taxonomyHash:d.taxonomyHash};for(const t of n)t(e)}function q(){!function(e){if("undefined"!=typeof document)for(const[t,o]of k)!0===e[o.category]&&(b.has(t)||C(t,o))}(f)}function M(){if(d={...d,hasActed:!0,lastRenewed:Date.now()},r(d),t.backend)try{Promise.resolve(t.backend.persist(H(d))).catch(()=>{})}catch{}else t.apiUrl&&async function(e,t,o){const n=H(o),r={"Content-Type":"application/json"};t&&(r.Authorization=`Bearer ${t}`);try{await fetch(e,{method:"POST",headers:r,body:JSON.stringify(n),keepalive:!0})}catch{}}(t.apiUrl,t.apiKey,d);let e=!1;for(const t of c.ids)if(l[t]&&!d.categories[t]){e=!0;break}l={...d.categories},f={...d.categories},q();const{reloadRequiredBy:o}=I(f);var n;((n=o).length!==h.length||n.some((e,t)=>e!==h[t]))&&(h=n,y=!1),w(c,f),_(),t.onConsentUpdate?.(d),e&&t.reloadOnRevoke&&"undefined"!=typeof window&&window.location.reload()}d={...d,taxonomyHash:c.taxonomyHash},l={...d.categories},f={...d.categories},Promise.resolve().then(()=>t.onConsentReady?.(d));const $={get consentId(){return d.consentId},get hasActed(){return d.hasActed},get categories(){return{...d.categories}},get committedCategories(){return{...f}},get regulation(){return d.regulation},get lastRenewed(){return d.lastRenewed},get taxonomyHash(){return d.taxonomyHash},get isPreferencesOpen(){return g},acceptAll(){d={...d,categories:p(()=>!0)},g=!1,M()},rejectAll(){d={...d,categories:p(()=>!1)},g=!1,M()},acceptSelected(e){d={...d,categories:p(t=>e.includes(t))},g=!1,M()},updateCategory(e,t){c.requiredIds.has(e)||c.ids.includes(e)&&(d={...d,categories:{...d.categories,[e]:t}},_())},savePreferences(){g=!1,M()},resetConsent(){s();const e=a();d=i(e,d.regulation,c),f={...d.categories},l={...d.categories},g=!1,I(f),w(c,f),h=[],y=!1,_()},showPreferences(){g=!0,_()},hidePreferences(){g=!1,_()},subscribe:e=>(n.add(e),()=>n.delete(e)),registerScript(e){!function(e){k.set(e.id,e)}(e),q()},get reloadNotice(){return{required:h.length>0&&!y,reasons:[...h]}},dismissReloadNotice(){y||(y=!0,_())}};return q(),function(e){for(const t of x.values()){const o=!0!==e[t.category];if(R(t))o?A.delete(t.id):A.add(t.id);else try{o?(t.stop(),U.add(t.id)):(U.delete(t.id),t.resume?.())}catch{}}}(d.categories),w(c,d.categories),$}function P(e,t,o,n){let r;try{const e="undefined"!=typeof window?window.location.href:"http://localhost";r=new URL(t,e)}catch{return null}const s=r.hostname.toLowerCase(),a=r.pathname+r.search,i=o.toUpperCase();for(const t of e){const e=t.domain.toLowerCase();if((s===e||s.endsWith("."+e))&&((!t.pathIncludes||a.includes(t.pathIncludes))&&(!t.methods||t.methods.map(e=>e.toUpperCase()).includes(i))&&!n(t.category)))return t}return null}let L=null;function _(e,t){if("undefined"==typeof window)return()=>{};if(L)return()=>{};if(!e.rules.length)return()=>{};const o={originalFetch:window.fetch,originalXhrOpen:XMLHttpRequest.prototype.open,originalXhrSend:XMLHttpRequest.prototype.send,originalSendBeacon:"undefined"!=typeof navigator&&"function"==typeof navigator.sendBeacon?navigator.sendBeacon:void 0};L=o;const n=!1!==e.logBlockedRequests;function r(t){n&&console.warn(`[cookieyes] blocked ${t.method} ${t.url} (rule "${t.rule.id}", category: ${t.rule.category})`),e.onRequestBlocked?.(t)}if(window.fetch=function(n,s){let a="",i=s?.method??"GET";"string"==typeof n?a=n:n instanceof URL?a=n.toString():(a=n.url,i=s?.method??n.method);const c=P(e.rules,a,i,t);return c?(r({rule:c,url:a,method:i}),Promise.reject(new TypeError(`Blocked by consent (rule: ${c.id}, category: ${c.category})`))):o.originalFetch.call(window,n,s)},XMLHttpRequest.prototype.open=function(e,t,...n){return this._cyUrl=t.toString(),this._cyMethod=e,o.originalXhrOpen.apply(this,[e,t,...n])},XMLHttpRequest.prototype.send=function(n){const s=this._cyUrl??"",a=this._cyMethod??"GET",i=P(e.rules,s,a,t);return i?(r({rule:i,url:s,method:a}),void this.abort()):o.originalXhrSend.call(this,n)},o.originalSendBeacon){const n=o.originalSendBeacon;navigator.sendBeacon=function(o,s){const a=P(e.rules,o.toString(),"POST",t);return a?(r({rule:a,url:o.toString(),method:"POST"}),!0):n.call(navigator,o,s)}}return q}function q(){L&&("undefined"!=typeof window&&(window.fetch=L.originalFetch,XMLHttpRequest.prototype.open=L.originalXhrOpen,XMLHttpRequest.prototype.send=L.originalXhrSend,L.originalSendBeacon&&(navigator.sendBeacon=L.originalSendBeacon)),L=null)}let M=null;function $(e){if(M)return M;"offline"===e.mode&&h();const t=g(e),o=new Set,n=t.onConsentUpdate,r={};"self-hosted"===t.mode&&(t.backend?r.backend=t.backend:t.apiUrl&&(r.apiUrl=t.apiUrl)),t.apiKey&&(r.apiKey=t.apiKey),t.regulation&&(r.regulation=t.regulation),t.colorScheme&&(r.colorScheme=t.colorScheme),t.theme&&(r.theme=t.theme),t.reloadOnRevoke&&(r.reloadOnRevoke=t.reloadOnRevoke),t.integrations&&(r.integrations=t.integrations),t.customStopHandlers&&(r.customStopHandlers=t.customStopHandlers),t.categories&&(r.categories=t.categories),t.onConsentReady&&(r.onConsentReady=t.onConsentReady),r.onConsentUpdate=e=>{n?.(e);const t=function(e){const t=[],o=[];for(const n of Object.keys(e))e[n]?t.push(n):o.push(n);return{allowedCategories:t,deniedCategories:o}}(e.categories);for(const e of o)e(t)};const s=O(r);function a(){const e=s.categories;return{consentId:s.consentId,hasActed:s.hasActed,categories:e,consents:e,committedConsents:s.committedCategories,regulation:s.regulation,lastRenewed:s.lastRenewed,taxonomyHash:s.taxonomyHash,activeUI:s.isPreferencesOpen?"dialog":s.hasActed?null:"banner",has:e=>!0===s.committedCategories[e],saveConsents:async e=>{"all"===e?s.acceptAll():"necessary"===e?s.rejectAll():s.acceptSelected(e)},setConsent:(e,t)=>s.updateCategory(e,t),subscribeToConsentChanges:e=>(o.add(e),()=>{o.delete(e)})}}const i={subscribe:e=>s.subscribe(()=>e(a())),getState:a};return t.networkBlocker&&t.networkBlocker.rules.length>0&&_(t.networkBlocker,e=>!0===s.committedCategories[e]),M={consentManager:s,consentStore:i},M}exports.DEFAULT_CATEGORIES=c,exports._clearStopHandlers=function(){x.clear(),U.clear(),A.clear()},exports._normalizeConfig=g,exports._resetOfflineModeWarning=function(){p=!1},exports._warnOfflineModeDeprecated=h,exports.broadcastGoogleConsent=w,exports.computeGoogleConsent=m,exports.createConsentManager=O,exports.defaultTranslations=v,exports.generateConsentId=a,exports.getOrCreateConsentRuntime=$,exports.initCookieYes=function(e){return $(e)},exports.installNetworkBlocker=_,exports.parseCookie=o,exports.registerStopHandler=B,exports.resetConsentRuntime=function(){M=null},exports.resolveBuiltInIntegration=S,exports.resolveCategories=u,exports.resolveTranslations=function(e){const t=e?.messages??{},o=e?.detectBrowserLanguage??!0,n=[];e?.locale&&n.push(e.locale),o&&"undefined"!=typeof navigator&&navigator.language&&n.push(navigator.language);for(const e of n){const o=e.split("-")[0]?.toLowerCase()??"",n=t[e]??(o?t[o]:void 0);if(n)return n}return t.en??v},exports.serializeCookie=n,exports.uninstallNetworkBlocker=q;
1
+ "use strict";const e="cookieyes-consent",t=new Set(["consentid","consent","action","tax","lastRenewedDate"]);function o(e){const o={categories:{}};for(const n of e.split(",")){const e=n.indexOf(":");if(-1===e)continue;const r=n.slice(0,e).trim(),i=n.slice(e+1).trim();t.has(r)?o[r]=i:r.length>0&&(o.categories[r]=i)}return o}function n(e){const t=[`consentid:${e.consentId}`,"consent:"+(e.hasActed?"yes":"no"),"action:"+(e.hasActed?"yes":"no")];e.taxonomyHash&&t.push(`tax:${e.taxonomyHash}`);for(const[o,n]of Object.entries(e.categories))t.push(`${o}:${n?"yes":"no"}`);return t.push(`lastRenewedDate:${e.lastRenewed??Date.now()}`),t.join(",")}function r(t){for(const n of t.split(";")){const t=n.trim(),r=t.indexOf("=");if(-1===r)continue;if(t.slice(0,r).trim()!==e)continue;const i=t.slice(r+1).trim();try{return o(decodeURIComponent(i))}catch{return null}}return null}function i(t){if("undefined"==typeof document)return;const o=encodeURIComponent(n(t));document.cookie=`${e}=${o}; max-age=31536000; path=/; SameSite=Lax`}function s(){"undefined"!=typeof document&&(document.cookie=`${e}=; max-age=0; path=/`)}function a(){const e=new Uint8Array(32);if("undefined"!=typeof crypto&&crypto.getRandomValues)crypto.getRandomValues(e);else for(let t=0;t<e.length;t++)e[t]=Math.floor(256*Math.random());return btoa(String.fromCharCode(...e)).replace(/\+/g,"-").replace(/\//g,"_").replace(/=/g,"").slice(0,44)}function c(e,t,o){const n={};for(const t of o.ids)n[t]=!!o.requiredIds.has(t)||"yes"===e.categories[t];return{consentId:e.consentid??a(),hasActed:"yes"===e.action,categories:n,regulation:t,lastRenewed:e.lastRenewedDate?Number(e.lastRenewedDate):void 0,taxonomyHash:e.tax}}function d(e,t,o){const n="CCPA"===t,r={};for(const e of o.ids)r[e]=!!o.requiredIds.has(e)||n;return{consentId:e,hasActed:!1,categories:r,regulation:t,taxonomyHash:o.taxonomyHash}}const l=[{id:"necessary",required:!0},{id:"functional",gcm:["functionality_storage","personalization_storage"]},{id:"analytics",gcm:["analytics_storage"]},{id:"performance"},{id:"advertisement",gcm:["ad_storage","ad_user_data","ad_personalization"]}];function u(e){let t=2166136261;for(let o=0;o<e.length;o++)t^=e.charCodeAt(o),t=Math.imul(t,16777619);return(t>>>0).toString(36)}function g(e,t){const o=e.map(e=>e.id),n=new Set(e.filter(e=>e.required).map(e=>e.id)),r=e.map(e=>`${e.id}:${e.required?1:0}:${(e.gcm??[]).join("+")}`).join("|");return{list:e,ids:o,requiredIds:n,taxonomyHash:u(r),isDefault:t}}function f(e){if(!e||0===e.length)return g(l,!0);const o=function(e){const o=e.map(e=>e.id);return o.some(e=>"string"!=typeof e||0===e.length)?"every category needs a non-empty string id":o.some(e=>e.includes(",")||e.includes(":"))?"category ids must not contain ',' or ':'":new Set(o).size!==o.length?"category ids must be unique":o.some(e=>t.has(e))?`category ids must not be one of the reserved keys: ${[...t].join(", ")}`:e.some(e=>!0===e.required)?null:"at least one category must be marked { required: true }"}(e);return o?("undefined"!=typeof console&&console.warn(`[cookieyes] Invalid categories config (${o}). Falling back to the default five (necessary, functional, analytics, performance, advertisement).`),g(l,!0)):g(e,!1)}function p(e){"undefined"!=typeof console&&console.warn(e)}function h(e){const t={mode:e.mode},o=e.overrides?.regulation;return void 0!==e.regulation?(t.regulation=e.regulation,void 0!==o&&p("[CookieYes] Received both `regulation` and the deprecated `overrides.regulation`. Using the top-level `regulation` and ignoring `overrides`. Drop the `overrides` object — it is deprecated and will be removed after three release cycles.")):void 0!==o&&(t.regulation=o),void 0!==e.region&&(t.region=e.region),void 0!==e.colorScheme&&(t.colorScheme=e.colorScheme),void 0!==e.theme&&(t.theme=e.theme),void 0!==e.i18n&&(t.i18n=e.i18n),void 0!==e.consentCategories&&(t.consentCategories=e.consentCategories),void 0!==e.categories&&(t.categories=e.categories),void 0!==e.networkBlocker&&(t.networkBlocker=e.networkBlocker),void 0!==e.reloadOnRevoke&&(t.reloadOnRevoke=e.reloadOnRevoke),void 0!==e.googleConsentMatch&&(t.googleConsentMatch=e.googleConsentMatch),void 0!==e.integrations&&(t.integrations=e.integrations),void 0!==e.builtInIntegrations&&(t.builtInIntegrations=e.builtInIntegrations),void 0!==e.customStopHandlers&&(t.customStopHandlers=e.customStopHandlers),void 0!==e.onConsentReady&&(t.onConsentReady=e.onConsentReady),void 0!==e.onConsentUpdate&&(t.onConsentUpdate=e.onConsentUpdate),"self-hosted"===e.mode&&(void 0!==e.apiKey&&(t.apiKey=e.apiKey),void 0!==e.backend&&(t.backend=e.backend),void 0!==e.apiUrl?(t.apiUrl=e.apiUrl,void 0!==e.backendURL&&p("[CookieYes] Received both `apiUrl` and the deprecated `backendURL`. Using `apiUrl` and ignoring `backendURL`. Rename `backendURL` to `apiUrl` — the alias is deprecated and will be removed after three release cycles.")):void 0!==e.backendURL&&(t.apiUrl=e.backendURL)),t}let y=!1;function m(){y||(y=!0,"undefined"!=typeof console&&console.warn('[cookieyes] mode: "offline" has been renamed to "cookie-only". Both do exactly the same thing, but "offline" is deprecated and will be removed in 3 releases. Update to .mode("cookie-only") (or { mode: "cookie-only" }).'))}let v=!1;function w(){v||(v=!0,"undefined"!=typeof console&&console.warn("[cookieyes] `builtInIntegrations` (formerly the `integrations` field) is deprecated and will be removed in a future release. Use the `integrations` field with a preset from `@cookieyes/scripts` instead."))}function k(e){const t={save:new Set,change:new Set};let o={...e()};function n(e,t,o){try{e.listener(o)}catch(e){"undefined"!=typeof console&&console.error(`[cookieyes] a consent "${t}" listener threw; others are unaffected:`,e)}}function r(e,o){for(const r of[...t[e]])r.category&&!o.changedCategories.includes(r.category)||n(r,e,o)}return{on(o,r,i){const s=i?.category?{listener:r,category:i.category}:{listener:r};return t[o].add(s),n(s,o,{categories:{...e()},changedCategories:[],isInitial:!0}),()=>{t[o].delete(s)}},push(e){const t={...e},n=[];for(const e of Object.keys(t))o[e]!==t[e]&&n.push(e);o=t,r("save",{categories:t,changedCategories:n,isInitial:!1}),n.length>0&&r("change",{categories:t,changedCategories:n,isInitial:!1})}}}function b(e){"undefined"!=typeof console&&console.warn(`[cookieyes] ${e}`)}const C=["ad_storage","ad_user_data","ad_personalization","analytics_storage","functionality_storage","personalization_storage","security_storage"];function x(e,t,o="any"){const n={};for(const r of C){if("security_storage"===r){n[r]="granted";continue}const i=e.list.filter(e=>e.gcm?.includes(r));if(0===i.length){n[r]="denied";continue}const s="all"===o?i.every(e=>!0===t[e.id]):i.some(e=>!0===t[e.id]);n[r]=s?"granted":"denied"}return n}function R(e,t,o="any"){if("undefined"==typeof window||!Array.isArray(window.dataLayer))return;const n=x(e,t,o),r=window.dataLayer;if(!r)return;!function(){r.push(arguments)}("consent","update",n)}const S={bannerTitle:"We value your privacy",bannerDescription:"We use cookies to enhance your browsing experience, serve personalised ads or content, and analyse our traffic. By clicking “Accept All”, you consent to our use of cookies.",acceptAll:"Accept All",rejectAll:"Reject All",managePreferences:"Customise",savePreferences:"Save My Preferences",doNotSell:"Do Not Sell or Share My Personal Information",ccpaDescription:"This website or its third-party tools process personal data. You can opt out of the sale of your personal information by clicking on the “Do Not Sell or Share My Personal Information” link.",accept:"Accept",poweredBy:"Powered by CookieYes",preferencesTitle:"Customise Consent Preferences",preferencesIntro:"We use cookies to help you navigate efficiently and perform certain functions. You will find detailed information about all cookies under each consent category below.",categories:{necessary:{label:"Necessary",description:"Necessary cookies are required to enable the basic features of this site, such as providing secure log-in or adjusting your consent preferences. These cookies do not store any personally identifiable data."},functional:{label:"Functional",description:"Functional cookies help perform certain functionalities like sharing the content of the website on social media platforms, collecting feedback, and other third-party features."},analytics:{label:"Analytics",description:"Analytical cookies are used to understand how visitors interact with the website. These cookies help provide information on metrics such as the number of visitors, bounce rate, traffic source, etc."},performance:{label:"Performance",description:"Performance cookies are used to understand and analyse the key performance indexes of the website which helps in delivering a better user experience for the visitors."},advertisement:{label:"Advertisement",description:"Advertisement cookies are used to provide visitors with customised advertisements based on the pages you visited previously and to analyse the effectiveness of the ad campaigns."}},optOut:{title:"Opt-out Preferences",description:'We use third-party cookies that help us analyse how you use this website, store your preferences, and provide the content and advertisements that are relevant to you. However, you can opt out of these cookies by checking "Do Not Sell or Share My Personal Information" and clicking the "Save My Preferences" button. Once you opt out, you can opt in again at any time by unchecking "Do Not Sell or Share My Personal Information" and clicking the "Save My Preferences" button.',cancel:"Cancel",successText:"Your opt-out preference has been honored.",successCountdown:"Banner closes automatically in {seconds} s..."},reloadNotice:{message:"Some tracking on this page can only be fully stopped by reloading. Reload to apply your change, or dismiss to keep browsing.",reloadButton:"Reload page",dismissButton:"Dismiss"}},I=new Set(["ar","he","fa","ur","ps","sd","yi","dv"]);function A(e){return e.split("-")[0]?.toLowerCase()??""}function O(e){return I.has(A(e))?"rtl":"ltr"}function U(e,t){if(!t)return e;const o={...e};for(const[n,r]of Object.entries(t)){if(null==r)continue;const t=e[n],i="object"==typeof r&&!Array.isArray(r)&&"object"==typeof t&&null!=t;o[n]=i?U(t,r):r}return o}function $(e){const t=e?.messages??{},o=[];e?.locale&&o.push(e.locale),(e?.detectBrowserLanguage??1)&&"undefined"!=typeof navigator&&navigator.language&&o.push(navigator.language);for(const e of o){if(t[e])return e;const o=A(e);if(o&&t[o])return o}return"en"}function L(e,t){const o=new Set(e);for(const e of t)o.has(e)&&M(`"${e}" is configured as both a script integration and a built-in integration — remove one to avoid loading it twice (e.g. double-counted events).`)}function H(e,t){const o=new Set(t);for(const t of e){if("afterConsent"!==t.load)continue;const e=t.category,n=Array.isArray(e)?e:[e];if(0!==n.length)for(const e of n)o.has(e)||M(`integration "${t.id}" is gated on category "${e}", which isn't in your configured categories — it will never load. Pass a category that exists (e.g. segment({ category: "…" })), or add it to your taxonomy.`);else M(`integration "${t.id}" has an empty category list — it will never load. Give it at least one category that exists in your taxonomy.`)}}function M(e,t){"undefined"!=typeof console&&(void 0!==t?console.error(`[cookieyes] ${e}`,t):console.warn(`[cookieyes] ${e}`))}function P(e,t){const o=Array.isArray(e.category)?e.category:[e.category];return 0!==o.length&&("any"===e.match?o.some(e=>t.granted(e)):o.every(e=>t.granted(e)))}function B(e,t){const o=[],n=new Set;let r=!1;for(const t of e){const e=t;"string"!=typeof e.vendor||"function"==typeof e.setup?1===t.version?n.has(t.id)?M(`integration "${t.id}" is registered more than once; skipping the duplicate.`):(n.add(t.id),o.push({integration:t,status:"idle",everLoaded:!1,loading:!1,control:void 0,subs:new Set,wasGranted:!1})):M(`integration "${t.id}" uses format version ${t.version}, but this build understands 1. Skipping it.`):M(`an entry in "integrations" looks like the old built-in format ({ vendor: "${e.vendor}" }). That moved to "builtInIntegrations" — move it there, or use a preset from "@cookieyes/scripts" in "integrations". Skipping it.`)}function i(e){for(const t of e.subs)try{t()}catch{}e.subs.clear()}function s(e){i(e),"active"===e.status&&(!function(e){const{integration:t,control:o}=e;try{"remove"===t.onRevoke?o?.():"silence"===t.onRevoke&&o?.silence()}catch(e){M(`integration "${t.id}" threw while being torn down.`,e)}e.control=void 0}(e),"remove"===e.integration.onRevoke?e.status="removed":"silence"===e.integration.onRevoke&&(e.status="silenced"))}function a(e){e.loading=!0,e.status="loading",Promise.resolve().then(()=>e.integration.setup(function(e){return{granted:()=>P(e.integration,t),onConsentChange:o=>{const n=t.subscribe(o);return e.subs.add(n),()=>{e.subs.delete(n)&&n()}},region:t.region}}(e))).then(t=>{e.loading=!1,e.control=t??void 0,e.everLoaded=!0,e.status="active",r?s(e):c(e)}).catch(t=>{e.loading=!1,e.status="error",i(e),M(`integration "${e.integration.id}" failed to load; will retry on the next change.`,t)})}function c(e){const{integration:o}=e,n=P(o,t);if(n&&(e.wasGranted=!0),r||e.loading)return;if("idle"===e.status||"removed"===e.status||"error"===e.status){return void((e.everLoaded?n:"immediately"===o.load||n)&&a(e))}if("keep"===o.onRevoke)return;if("remove"===o.onRevoke){if(!n&&"active"===e.status&&e.wasGranted){i(e);try{e.control?.()}catch(e){M(`integration "${o.id}" cleanup threw on revoke.`,e)}e.control=void 0,e.status="removed"}return}const s=e.control;if(n||"active"!==e.status){if(n&&"silenced"===e.status){try{s?.resume()}catch(e){M(`integration "${o.id}" resume() threw.`,e)}e.status="active"}}else{try{s?.silence()}catch(e){M(`integration "${o.id}" silence() threw.`,e)}e.status="silenced"}}function d(){for(const e of o)c(e)}const l=t.subscribe(d);return d(),{status:()=>{const e={};for(const t of o)e[t.integration.id]=t.status;return e},list:()=>o.map(e=>({id:e.integration.id,category:e.integration.category,load:e.integration.load,onRevoke:e.integration.onRevoke,status:e.status})),stop:()=>{if(!r){r=!0,l();for(const e of o)s(e)}}}}function _(e,t){const o={...e?.messages},n=e?.loadLanguage,r=new Set;let i=$(e),s=l(i),a=u();function c(e){return o[e]??o[A(e)]}function d(e){return"en"===A(e)||void 0!==c(e)}function l(e){return U(S,c(e))}function u(){return{language:i,direction:O(i),languages:Array.from(new Set(["en",...Object.keys(o)]))}}function g(e){i=e,s=l(e),a=u(),t()}function f(e,t){r.has(e)||"undefined"==typeof console||(r.add(e),console.warn(`[cookieyes] no translations for language "${e}"; staying on "${i}". Add it to i18n.messages or provide i18n.loadLanguage.`,t??""))}function p(e){return d(e)?(g(e),Promise.resolve()):n?Promise.resolve().then(()=>n(e)).then(t=>{o[e]=t,g(e)}).catch(t=>f(e,t)):(f(e),Promise.resolve())}return n&&e?.locale&&!d(e.locale)&&"undefined"!=typeof window&&p(e.locale),{getTranslations:()=>s,getLanguageInfo:()=>a,setLanguage:p,getCategoryText:function(e){return c(i)?.categories?.[e]}}}const T=new Map,D=new Map;function q(e,t){if(document.getElementById(e))return;const o=document.createElement("script");o.id=e,o.src=t.src,o.async=!0,t.onLoad&&o.addEventListener("load",t.onLoad,{once:!0}),document.head.appendChild(o),D.set(e,o)}function j(e){return"needsReload"in e&&!0===e.needsReload}function N(e){switch(e.vendor){case"meta":return{id:"meta",category:e.category??"advertisement",stop:()=>window.fbq?.("consent","revoke"),resume:()=>window.fbq?.("consent","grant")};case"tiktok":return{id:"tiktok",category:e.category??"advertisement",needsReload:!0};case"linkedin":return{id:"linkedin",category:e.category??"advertisement",needsReload:!0};case"hotjar":return{id:"hotjar",category:e.category??"analytics",needsReload:!0};case"segment":return{id:"segment",category:e.category??"analytics",needsReload:!0}}}const E=new Map,G=new Set,F=new Set;function X(e){E.set(e.id,e)}function z(e){const t=[];for(const o of E.values()){const n=!0!==e[o.category];if(j(o))n?F.has(o.id)&&(t.push(o.id),F.delete(o.id)):F.add(o.id);else if(n){if(!G.has(o.id))try{o.stop(),G.add(o.id)}catch{t.push(o.id)}}else if(G.has(o.id)){G.delete(o.id);try{o.resume?.()}catch{}}}return{reloadRequiredBy:t}}function K(e,t){const o={consentId:e.consentId,categories:e.categories,regulation:e.regulation,domain:"undefined"!=typeof window?window.location.hostname:"unknown"};return t&&(o.region=t),o}function W(e){const t=new Set,o=f(e.categories),n=e.googleConsentMatch??"any";let l;void 0===e.googleConsentMatch&&function(e){const t=new Map;for(const o of e.list)for(const e of o.gcm??[]){let n=t.get(e);n||(n=new Set,t.set(e,n)),n.add(o.id)}for(const[e,o]of t)o.size<=1||b(`categories ${[...o].map(e=>JSON.stringify(e)).join(", ")} all map to the Google signal "${e}", which is a single on/off — this mapping is lossy. Set \`googleConsentMatch: "all"\` to grant it only when all are granted, or "any" (default) to grant it when any is.`)}(o);let u,g,p=!1;function h(e){const t={};for(const n of o.ids)t[n]=!!o.requiredIds.has(n)||e(n);return t}let y=[],m=!1;for(const t of e.integrations??[])X(N(t));for(const t of e.customStopHandlers??[])X(t);const v="undefined"==typeof document?null:r(document.cookie),w=e.regulation??"DEFAULT",k=v?.tax,C=k===o.taxonomyHash,x=null!=v&&(C||void 0===k&&o.isDefault);if(null!=v&&x)l=c(v,w,o);else{const e=v?.consentid??a();l=d(e,w,o),null!=v&&s(),"CCPA"===l.regulation&&i(l)}function S(){const e={consentId:l.consentId,hasActed:l.hasActed,categories:{...l.categories},regulation:l.regulation,lastRenewed:l.lastRenewed,taxonomyHash:l.taxonomyHash};for(const o of t)o(e)}function I(){!function(e){if("undefined"!=typeof document)for(const[t,o]of T)!0===e[o.category]&&(D.has(t)||q(t,o))}(g)}function A(){l={...l,hasActed:!0,lastRenewed:Date.now()},i(l);let t=!1;for(const e of o.ids)if(u[e]&&!l.categories[e]){t=!0;break}if(u={...l.categories},g={...l.categories},S(),e.onConsentUpdate?.(l),e.backend)try{Promise.resolve(e.backend.persist(K(l,e.region))).catch(()=>{})}catch{}else e.apiUrl&&async function(e,t,o,n){const r=K(o,n),i={"Content-Type":"application/json"};t&&(i.Authorization=`Bearer ${t}`);try{await fetch(e,{method:"POST",headers:i,body:JSON.stringify(r),keepalive:!0})}catch{}}(e.apiUrl,e.apiKey,l,e.region);try{I()}catch{}let r=!1;try{const{reloadRequiredBy:e}=z(g);r=function(e){const t=e.length!==y.length||e.some((e,t)=>e!==y[t]);return t&&(y=e,m=!1),t}(e)}catch{}try{R(o,g,n)}catch{}r&&S(),t&&e.reloadOnRevoke&&"undefined"!=typeof window&&window.location.reload()}l={...l,taxonomyHash:o.taxonomyHash},e.gpcOptOut&&!l.hasActed&&(l={...l,categories:h(()=>!1)},i(l)),u={...l.categories},g={...l.categories},Promise.resolve().then(()=>e.onConsentReady?.(l));const O={get consentId(){return l.consentId},get hasActed(){return l.hasActed},get categories(){return{...l.categories}},get committedCategories(){return{...g}},get regulation(){return l.regulation},get lastRenewed(){return l.lastRenewed},get taxonomyHash(){return l.taxonomyHash},get isPreferencesOpen(){return p},acceptAll(){l={...l,categories:h(()=>!0)},p=!1,A()},rejectAll(){l={...l,categories:h(()=>!1)},p=!1,A()},acceptSelected(e){l={...l,categories:h(t=>e.includes(t))},p=!1,A()},updateCategory(e,t){o.requiredIds.has(e)||o.ids.includes(e)&&(l={...l,categories:{...l.categories,[e]:t}},S())},savePreferences(){p=!1,A()},resetConsent(){s();const e=a();l=d(e,l.regulation,o),g={...l.categories},u={...l.categories},p=!1,z(g),R(o,g,n),y=[],m=!1,S()},showPreferences(){p=!0,S()},hidePreferences(){p=!1,S()},subscribe:e=>(t.add(e),()=>t.delete(e)),registerScript(e){!function(e){T.set(e.id,e)}(e),I()},get reloadNotice(){return{required:y.length>0&&!m,reasons:[...y]}},dismissReloadNotice(){m||(m=!0,S())}};I();try{!function(e){for(const t of E.values()){const o=!0!==e[t.category];if(j(t))o?F.delete(t.id):F.add(t.id);else try{o?(t.stop(),G.add(t.id)):(G.delete(t.id),t.resume?.())}catch{}}}(l.categories)}catch{}try{R(o,l.categories,n)}catch{}return O}function Y(e,t,o,n){let r;try{const e="undefined"!=typeof window?window.location.href:"http://localhost";r=new URL(t,e)}catch{return null}const i=r.hostname.toLowerCase(),s=r.pathname+r.search,a=o.toUpperCase();for(const t of e){const e=t.domain.toLowerCase();if((i===e||i.endsWith("."+e))&&((!t.pathIncludes||s.includes(t.pathIncludes))&&(!t.methods||t.methods.map(e=>e.toUpperCase()).includes(a))&&!n(t.category)))return t}return null}let V=null;function J(e,t){if("undefined"==typeof window)return()=>{};if(V)return()=>{};if(!e.rules.length)return()=>{};const o={originalFetch:window.fetch,originalXhrOpen:XMLHttpRequest.prototype.open,originalXhrSend:XMLHttpRequest.prototype.send,originalSendBeacon:"undefined"!=typeof navigator&&"function"==typeof navigator.sendBeacon?navigator.sendBeacon:void 0};V=o;const n=!1!==e.logBlockedRequests;function r(t){n&&console.warn(`[cookieyes] blocked ${t.method} ${t.url} (rule "${t.rule.id}", category: ${t.rule.category})`),e.onRequestBlocked?.(t)}if(window.fetch=function(n,i){let s="",a=i?.method??"GET";"string"==typeof n?s=n:n instanceof URL?s=n.toString():(s=n.url,a=i?.method??n.method);const c=Y(e.rules,s,a,t);return c?(r({rule:c,url:s,method:a}),Promise.reject(new TypeError(`Blocked by consent (rule: ${c.id}, category: ${c.category})`))):o.originalFetch.call(window,n,i)},XMLHttpRequest.prototype.open=function(e,t,...n){return this._cyUrl=t.toString(),this._cyMethod=e,o.originalXhrOpen.apply(this,[e,t,...n])},XMLHttpRequest.prototype.send=function(n){const i=this._cyUrl??"",s=this._cyMethod??"GET",a=Y(e.rules,i,s,t);return a?(r({rule:a,url:i,method:s}),void this.abort()):o.originalXhrSend.call(this,n)},o.originalSendBeacon){const n=o.originalSendBeacon;navigator.sendBeacon=function(o,i){const s=Y(e.rules,o.toString(),"POST",t);return s?(r({rule:s,url:o.toString(),method:"POST"}),!0):n.call(navigator,o,i)}}return Q}function Q(){V&&("undefined"!=typeof window&&(window.fetch=V.originalFetch,XMLHttpRequest.prototype.open=V.originalXhrOpen,XMLHttpRequest.prototype.send=V.originalXhrSend,V.originalSendBeacon&&(navigator.sendBeacon=V.originalSendBeacon)),V=null)}const Z=[{country:"x-vercel-ip-country",region:"x-vercel-ip-country-region"},{country:"cf-ipcountry"}];function ee(){return"undefined"!=typeof navigator&&!0===navigator.globalPrivacyControl}function te(e,t){const o=e.strictest??"GDPR";if(t)return e.detect&&"undefined"!=typeof console&&console.warn("[cookieyes] `regulation` is set manually, so region detection is ignored. Remove one of them to clear the conflict."),{region:void 0,regulation:t,source:"manual",confidence:"high"};const n=e.detect?.(),r=n?function(e,t){if(e)return e[t]??e[t.split("-")[0]??""]}(e.map,n):void 0;return{region:n,regulation:r??o,source:r?"detected":"strictest",confidence:r?"high":"low"}}function oe(e,t){"undefined"!=typeof console&&console.info("[cookieyes] region detection",{region:e.region,regulation:e.regulation,source:e.source,confidence:e.confidence,gpcOptOut:t})}let ne=null,re=null;function ie(e){if(ne)return ne;"offline"===e.mode&&m();const t=h(e),o=new Set,n=t.onConsentUpdate;let r;const i=t.region?te(t.region,t.regulation):{region:void 0,regulation:t.regulation??"DEFAULT",source:"manual",confidence:"high"},s={};"self-hosted"===t.mode&&(t.backend?s.backend=t.backend:t.apiUrl&&(s.apiUrl=t.apiUrl)),t.apiKey&&(s.apiKey=t.apiKey),s.regulation=i.regulation,i.region&&(s.region=i.region);const a=(c=i.regulation,d=t.region,"CCPA"===c&&(d?.honorGpc??!0)&&ee());var c,d;a&&(s.gpcOptOut=!0),t.region?.debug&&oe(i,a),t.colorScheme&&(s.colorScheme=t.colorScheme),t.theme&&(s.theme=t.theme),t.reloadOnRevoke&&(s.reloadOnRevoke=t.reloadOnRevoke),t.googleConsentMatch&&(s.googleConsentMatch=t.googleConsentMatch),t.builtInIntegrations&&t.builtInIntegrations.length>0&&(w(),s.integrations=t.builtInIntegrations),t.customStopHandlers&&(s.customStopHandlers=t.customStopHandlers),t.categories&&(s.categories=t.categories),t.onConsentReady&&(s.onConsentReady=t.onConsentReady),s.onConsentUpdate=e=>{n?.(e),r.push(e.categories);const t=function(e){const t=[],o=[];for(const n of Object.keys(e))e[n]?t.push(n):o.push(n);return{allowedCategories:t,deniedCategories:o}}(e.categories);for(const e of o)e(t)};const l=W(s);r=k(()=>l.committedCategories);const u=f(t.categories),g=new Set;function p(){const e=v();for(const t of g)t(e)}l.subscribe(p);const y=_(t.i18n,p);function v(){const e=l.categories;return{consentId:l.consentId,hasActed:l.hasActed,categories:e,consents:e,committedConsents:l.committedCategories,regulation:l.regulation,lastRenewed:l.lastRenewed,taxonomyHash:l.taxonomyHash,activeUI:l.isPreferencesOpen?"dialog":l.hasActed?null:"banner",has:e=>!0===l.committedCategories[e],saveConsents:async e=>{"all"===e?l.acceptAll():"necessary"===e?l.rejectAll():l.acceptSelected(e)},setConsent:(e,t)=>l.updateCategory(e,t),subscribeToConsentChanges:e=>(o.add(e),()=>{o.delete(e)})}}const b={subscribe:e=>(g.add(e),()=>{g.delete(e)}),getState:v,on:(e,t,o)=>r.on(e,t,o),get translations(){return y.getTranslations()},getLanguageInfo:y.getLanguageInfo,setLanguage:y.setLanguage,getCategoryText:y.getCategoryText,categories:u,getRegion:()=>i};return t.networkBlocker&&t.networkBlocker.rules.length>0&&J(t.networkBlocker,e=>!0===l.committedCategories[e]),t.integrations&&t.integrations.length>0&&(L(t.integrations.map(e=>e.id),(t.builtInIntegrations??[]).map(e=>e.vendor)),H(t.integrations,u.ids),re=B(t.integrations,{granted:e=>!0===l.committedCategories[e],subscribe:e=>l.subscribe(()=>e()),region:i})),ne={consentManager:l,consentStore:b,getIntegrations:()=>re?.list()??[]},ne}exports.CORE_VERSION="0.4.0",exports.DEFAULT_CATEGORIES=l,exports.INTEGRATION_FORMAT_VERSION=1,exports._clearScriptRegistry=function(){if("undefined"!=typeof document)for(const e of D.values())e.remove();T.clear(),D.clear()},exports._clearStopHandlers=function(){E.clear(),G.clear(),F.clear()},exports._logRegionDecision=oe,exports._normalizeConfig=h,exports._resetBuiltInIntegrationsWarning=function(){v=!1},exports._resetOfflineModeWarning=function(){y=!1},exports._warnBuiltInIntegrationsDeprecated=w,exports._warnOfflineModeDeprecated=m,exports.broadcastGoogleConsent=R,exports.computeGoogleConsent=x,exports.createConsentEmitter=k,exports.createConsentManager=W,exports.createLanguageController=_,exports.defaultTranslations=S,exports.generateConsentId=a,exports.getOrCreateConsentRuntime=ie,exports.getTextDirection=O,exports.initCookieYes=function(e){return ie(e)},exports.installNetworkBlocker=J,exports.mergeTranslations=U,exports.parseCookie=o,exports.parseCookieHeader=r,exports.pickLanguage=$,exports.primaryOf=A,exports.readGpc=ee,exports.readServerConsent=function(e,t={}){if("string"!=typeof e||0===e.length)return null;const o=r(e);if(null==o)return null;const n=f(t.categories),i=o.tax;if(!(i===n.taxonomyHash||void 0===i&&n.isDefault))return null;const s=c(o,t.regulation??"DEFAULT",n);return s.hasActed?{...s,taxonomyHash:n.taxonomyHash}:null},exports.regionFromHeaders=function(e,t){if(t?.header)return e.get(t.header)||void 0;for(const{country:t,region:o}of Z){const n=e.get(t);if(!n)continue;const r=o?e.get(o):void 0;return r?`${n}-${r}`:n}},exports.registerStopHandler=X,exports.resetConsentRuntime=function(){re?.stop(),re=null,ne=null},exports.resolveBuiltInIntegration=N,exports.resolveCategories=f,exports.resolveRegion=te,exports.resolveTranslations=function(e){const t=e?.messages??{},o=$(e);return U(S,t[o]??t[A(o)])},exports.runIntegrations=B,exports.serializeCookie=n,exports.uninstallNetworkBlocker=Q,exports.warnOverlappingVendors=L,exports.warnUnknownCategories=H;
2
2
  //# sourceMappingURL=index.cjs.map