PageSourceSearch

https://www.karkinos.in/wp-content/plugins/cookie-law-info/lite/frontend/js/script.js?ver=3.5.5

js karkinos.in collected 2026-09-24 11:12:28 UTC 59,499 bytes, 1,695 lines download raw bytes

1/**
2 * WordPress localize object mapped to a constant.
3 */
4const _ckyStore = window._ckyConfig;
5const _ckyStyle = window._ckyStyles;
6
7_ckyStore._backupNodes = [];
8_ckyStore._resetConsentID = false;
9_ckyStore._bannerState = false;
10_ckyStore._preferenceOriginTag = false;
11_ckyStore._optoutSuccessCountdownInterval = null;
12_ckyStore._optoutSuccessAutoCloseTimer = null;
13_ckyStore._optoutSuccessSubtextTemplate = "";
14
15const CKY_OPTOUT_SUCCESS_DISMISS_MS = 15000;
16const CKY_OPTOUT_SUCCESS_SECONDS = 15;
17
18window.cookieyes = window.cookieyes || {};
19const ref = window.cookieyes;
20ref._ckyConsentStore = new Map();
21
22ref._ckyGetCookieMap = function () {
23    const cookieMap = {};
24    try {
25        document.cookie.split(";").map((cookie) => {
26            const [key, value] = cookie.split("=");
27            if (!key) return;
28            cookieMap[key.trim()] = value;
29            return value;
30        });
31    } catch (error) { }
32    return cookieMap;
33};
34
35const currentCookieMap = ref._ckyGetCookieMap();
36ref._ckyGetFromStore = function (key) {
37    return ref._ckyConsentStore.get(key) || "";
38};
39
40ref._ckySetInStore = function (key, value) {
41    ref._ckyConsentStore.set(key, value);
42    let cookieStringArray = [];
43    for (const [key, value] of ref._ckyConsentStore) {
44        cookieStringArray.push(`${key}:${value}`);
45    }
46    const scriptExpiry =
47        _ckyStore && _ckyStore._expiry
48            ? _ckyStore._expiry
49            : 365;
50    ref._ckySetCookie(
51        "cookieyes-consent",
52        cookieStringArray.join(","),
53        scriptExpiry
54    );
55};
56
57const cookieyesConsentMap = (currentCookieMap["cookieyes-consent"] || "")
58    .split(",")
59    .reduce((prev, curr) => {
60        if (!curr) return prev;
61        const [key, value] = curr.split(":");
62        prev[key] = value;
63        return prev;
64    }, {});
65["consentid", "consent", "action"]
66    .concat(_ckyStore._categories.map(({ slug }) => slug))
67    .map((item) =>
68        ref._ckyConsentStore.set(item, cookieyesConsentMap[item] || "")
69    );
70
71
72/**
73 * Get the value of cookie by it's name.
74 * 
75 * @param {string} name Name of the cookie
76 * @returns {string}
77 */
78ref._ckyGetCookie = function (name) {
79    const value = new RegExp(`${name}=([^;]+)`).exec(document.cookie);
80    return value && Array.isArray(value) && value[1] ? unescape(value[1]) : null;
81}
82
83/**
84 * Set a cookie on document.cookie object.
85 * 
86 * @param {*} name Name of the cookie.
87 * @param {*} value Value to be set.
88 * @param {*} days Expiry in days.
89 * @param {*} domain Cookie domain.
90 */
91ref._ckySetCookie = function (name, value, days = 0, domain = _ckyStore._rootDomain) {
92    const date = new Date();
93    if (!!domain) {
94        domain = `domain=${domain}`;
95    }
96    const toSetTime =
97        days === 0 ? 0 : date.setTime(date.getTime() + days * 24 * 60 * 60 * 1000);
98    document.cookie = `${name}=${value}; expires=${new Date(
99        toSetTime
100    ).toUTCString()}; path=/;${domain}; SameSite=Strict;`;
101}
102
103function _ckySetConsentID() {
104    const cookieyesID = ref._ckyGetFromStore("consentid");
105    if (cookieyesID) return;
106    const consentID = ref._ckyRandomString(32);
107    ref._ckySetInStore("consentid", consentID);
108    _ckyStore._resetConsentID = true;
109}
110
111const _revisitCkyConsent = function () {
112    const type = _ckyGetType();
113    if (type === 'classic') {
114        _ckyShowBanner();
115    }
116    _ckySetPreferenceAction();
117    _ckyToggleRevisit();
118};
119/**
120 * Search an element by it's data-cky-tag attribute
121 * 
122 * @param {string} tag data-cky-tag of an element. 
123 * @returns {object}
124 */
125function _ckyGetElementByTag(tag) {
126    const item = document.querySelector('[data-cky-tag=' + tag + ']');
127    return item ? item : false;
128}
129
130function _ckyEscapeRegex(literal) {
131    return literal.replace(/[.*+?^${}()[\]\\]/g, "\\$&");
132}
133
134/**
135 * Bind click event to banner elements.
136 * 
137 * @param {string} tag data-cky-tag of the element
138 * @param {function} fn callback function
139 */
140function _ckyAttachListener(selector, fn) {
141    const item = _ckyFindElement(selector);
142    item && item.addEventListener("click", fn);
143}
144
145function _ckyClassAdd() {
146    return _ckyClassAction("add", ...arguments);
147}
148
149function _ckyClassRemove() {
150    return _ckyClassAction("remove", ...arguments);
151}
152
153function _ckyClassToggle() {
154    return _ckyClassAction("toggle", ...arguments);
155}
156
157function _ckyClassAction(action, selector, className, forParent = true) {
158    const item = _ckyFindElement(selector, forParent);
159    return item && item.classList[action](className);
160}
161
162function _ckyFindElement(selector, forParent) {
163    let createdSelector = selector;
164    switch (true) {
165        case selector.startsWith("="):
166            createdSelector = `[data-cky-tag="${selector.substring(1)}"]`;
167            break;
168        default:
169            break;
170    }
171    const element = document.querySelector(createdSelector);
172    if (!element || (forParent && !element.parentElement)) return null;
173    return forParent ? element.parentElement : element;
174}
175/**
176 * Remove an element from the DOM.
177 * 
178 * @param {string} tag data-cky-tag of the element.
179 */
180function _ckyRemoveElement(tag) {
181    const item = _ckyGetElementByTag(tag);
182    item && item.remove();
183}
184
185function _ckyFireEvent(responseCategories) {
186    const consentUpdate = new CustomEvent("cookieyes_consent_update", {
187        detail: responseCategories
188    });
189    document.dispatchEvent(consentUpdate);
190}
191
192/**
193 * Remove styles by it's id.
194 */
195function _ckyRemoveStyles() {
196    const item = document.getElementById('cky-style-inline');
197    item && item.remove();
198}
199
200/**
201 * Generate a random string for logging purposes.
202 * 
203 * @param {integer} length Length of the string to be generated.
204 * @returns 
205 */
206ref._ckyRandomString = function (length, allChars = true) {
207    const chars = `${allChars ? `0123456789` : ""
208        }ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghiklmnopqrstuvwxyz`;
209    const response = [];
210    for (let i = 0; i < length; i++)
211        response.push(chars[Math.floor(Math.random() * chars.length)]);
212    if (!allChars) return response.join("");
213    return btoa(response.join("")).replace(/\=+$/, "");
214}
215
216/**
217 * Remove banner if necessary.
218 */
219function _ckyRemoveBanner() {
220    _ckyHideBanner();
221    if (_ckyStore._bannerConfig.config.revisitConsent.status === true) {
222        _ckyShowRevisit();
223    }
224}
225
226/**
227 * Initialize the plugin front-end operations.
228 * 
229 * @returns {boolean}
230 */
231function _ckyInitOperations() {
232    _ckyAttachNoticeStyles();
233    _ckyAttachShortCodeStyles();
234    _ckyRenderBanner();
235    _ckySetShowMoreLess();
236    if (!ref._ckyGetFromStore("action") || _ckyPreviewEnabled()) {
237        _ckyShowBanner();
238        _ckySetInitialState();
239        _ckySetConsentID();
240    } else {
241        _ckyRemoveBanner();
242    }
243}
244function _ckyPreviewEnabled() {
245    let params = (new URL(document.location)).searchParams;
246    return params.get("cky_preview") && params.get("cky_preview") === 'true';
247}
248function _ckyToggleAriaExpandStatus(selector, forceDefault = null) {
249    const element = _ckyFindElement(selector);
250
251    if (!element) return;
252
253    if (element.classList.contains('cky-accordion-btn')) {
254        const accordionItem = element.closest('.cky-accordion');
255        if (accordionItem) {
256            const accordionBody = accordionItem.querySelector('.cky-accordion-body');
257            if (accordionBody) {
258                // Generate unique ID for the accordion body if it doesn't have one
259                let bodyId = accordionBody.id;
260                if (!bodyId) {
261                    bodyId = `ckyDetailCategory${accordionItem.id.replace('ckyDetailCategory', '')}Body`;
262                    accordionBody.id = bodyId;
263                }
264                // Always set aria-controls - the relationship is permanent
265                element.setAttribute("aria-controls", bodyId);
266            }
267        }
268    }
269
270    const currentExpanded = element.getAttribute("aria-expanded");
271    const newExpandedValue = forceDefault || (currentExpanded === "true" ? "false" : "true");
272    element.setAttribute("aria-expanded", newExpandedValue);
273}
274/**
275 * Sets the initial state of the plugin.
276 */
277function _ckySetInitialState() {
278    const activeLaw = _ckyGetLaw()
279    ref._ckySetInStore("consent", "no");
280    const ccpaCheckBoxValue = _ckyFindCheckBoxValue();
281    const responseCategories = { accepted: [], rejected: [] };
282    let valueToSet = "yes";
283    for (const category of _ckyStore._categories) {
284        if (
285            (activeLaw === "gdpr" &&
286                !category.isNecessary &&
287                !category.defaultConsent[activeLaw]) ||
288            (activeLaw === "ccpa" &&
289                ccpaCheckBoxValue &&
290                !category.defaultConsent.ccpa)
291        ) {
292            valueToSet = "no";
293        }
294        if (valueToSet === "no") responseCategories.rejected.push(category.slug);
295        else responseCategories.accepted.push(category.slug);
296        ref._ckySetInStore(`${category.slug}`, valueToSet);
297    }
298    _ckyUnblock();
299    _ckyFireEvent(responseCategories);
300}
301
302/**
303 * Add a class based on the banner type and position. Eg: 'cky-banner-top'
304 * 
305 * @returns {boolean}
306 */
307function _ckyAddPositionClass() {
308    const notice = _ckyGetElementByTag('notice');
309    if (!notice) return false;
310    const container = notice.closest('.cky-consent-container');
311    if (!container) return false;
312    
313    container.setAttribute("aria-label", "We value your privacy");
314    container.setAttribute("role", "region");
315    
316    const type = _ckyStore._bannerConfig.settings.type;
317    let position = _ckyStore._bannerConfig.settings.position;
318    let bannerType = type;
319    if (bannerType === 'popup') {
320        position = 'center';
321    }
322    bannerType = (_ckyGetPtype() === "pushdown") ? 'classic' : bannerType;
323    const noticeClass = `cky-${bannerType}-${position}`;
324    container.classList.add(noticeClass);
325    const revisitConsent = _ckyGetElementByTag('revisit-consent');
326    if (!revisitConsent) return false;
327    const revisitPosition = 'cky-revisit-' + _ckyStore._bannerConfig.config.revisitConsent.position;
328    revisitConsent.classList.add(revisitPosition);
329}
330
331/**
332 * Add a class based on the preference center type and position. Eg: 'cky-sidebar-left'
333 * 
334 * @returns {boolean}
335 */
336function _ckyAddPreferenceCenterClass() {
337    const detail = _ckyGetLaw() === 'ccpa' ? _ckyGetElementByTag("optout-popup") : _ckyGetElementByTag("detail");
338    if (!detail) return false;
339    const modal = detail.closest('.cky-modal');
340    if (!modal) return false;
341    if (_ckyGetPtype() !== "pushdown" && _ckyGetPtype() !== "popup") {
342        const pType = _ckyStore._bannerConfig.settings.preferenceCenterType;
343        const modalClass = `cky-${pType}`;
344        modal.classList.add(modalClass);
345    }
346
347    // Ensure ARIA attributes are always present on the preference center div
348    const preferenceCenter = modal.querySelector('.cky-preference-center');
349    if (preferenceCenter) {
350        const preferenceCenterId = _ckyGetLaw() === 'ccpa' ? 'ckyOptoutPreferenceCenter' : 'ckyPreferenceCenter';
351        preferenceCenter.setAttribute('id', preferenceCenterId);
352        preferenceCenter.setAttribute('role', 'dialog');
353        preferenceCenter.setAttribute('aria-modal', 'true');
354        const ariaLabel = _ckyGetLaw() === 'ccpa' ? 'Opt-out Preferences' : 'Customise Consent Preferences';
355        preferenceCenter.setAttribute('aria-label', ariaLabel);
356    }
357}
358
359/**
360 * Initialize the plugin operations.
361 */
362async function _ckyInit() {
363    try {
364        _ckyInitOperations();
365        _ckyRemoveAllDeadCookies();
366        _ckyWatchBannerElement();
367    } catch (err) {
368        console.error(err);
369    }
370}
371
372/**
373 * Domready event, alternative to jQuery(document).ready() function
374 * 
375 * @param {function} callback 
376 * @returns 
377 */
378function _ckyDomReady(callback) {
379    if (typeof document === 'undefined') {
380        return;
381    }
382    if (document.readyState === 'complete' || /** DOMContentLoaded + Images/Styles/etc loaded, so we call directly. */
383        document.readyState === 'interactive' /** DOMContentLoaded fires at this point, so we call directly. */
384    ) {
385        return void callback();
386    } /** DOMContentLoaded has not fired yet, delay callback until then. */
387    document.addEventListener('DOMContentLoaded', callback);
388}
389
390/**
391 * Callback function to Domready event.
392 */
393_ckyDomReady(async function () {
394    try {
395        await _ckyInit();
396    } catch (err) {
397        console.error(err);
398    }
399});
400
401/**
402 * Register event handler for all the action elements.
403 */
404function _ckyRegisterListeners() {
405    for (const { slug } of _ckyStore._categories) {
406        _ckyAttachListener('detail-category-title', () =>
407            document
408                .getElementById(`ckyCategory${slug}`)
409                .classList.toggle("cky-tab-active")
410        );
411    }
412    _ckyAttachListener("=settings-button", () => _ckySetPreferenceAction('settings-button'));
413    _ckyAttachListener("=detail-close", () => _ckyHidePreferenceCenter());
414    _ckyAttachListener("=optout-cancel-button", () => _ckyHidePreferenceCenter());
415    _ckyAttachListener("=close-button", () => _ckyActionClose());
416    _ckyAttachListener("=donotsell-button", () => _ckySetPreferenceAction('donotsell-button'));
417    _ckyAttachListener("=reject-button", _ckyAcceptReject("reject"));
418    _ckyAttachListener("=accept-button", _ckyAcceptReject("all"));
419    _ckyAttachListener("=detail-accept-button", _ckyAcceptReject("all"));
420    _ckyAttachListener("=detail-save-button", _ckyAcceptReject());
421    _ckyAttachListener("=detail-category-preview-save-button", _ckyAcceptReject());
422    _ckyAttachListener("=optout-confirm-button", _ckyHandleOptoutConfirm());
423    _ckyAttachListener("=detail-reject-button", _ckyAcceptReject("reject"));
424    _ckyAttachListener("=revisit-consent", () => _revisitCkyConsent());
425    _ckyAttachListener("=optout-close", () => _ckyHandleOptoutPopupClose());
426}
427
428function _ckyAttachCategoryListeners() {
429    if (!_ckyStore._bannerConfig.config.auditTable.status) return;
430    const categoryNames = _ckyStore._categories.map(({ slug }) => slug);
431    categoryNames.map((category) => {
432        const selector = `#ckyDetailCategory${category}`;
433        const accordionButtonSelector = `${selector}  .cky-accordion-btn`;
434
435        // Set initial aria-controls and aria-expanded for accordion buttons
436        const accordionButton = document.querySelector(accordionButtonSelector);
437        if (accordionButton) {
438            const accordionItem = accordionButton.closest('.cky-accordion');
439            if (accordionItem) {
440                const accordionBody = accordionItem.querySelector('.cky-accordion-body');
441                if (accordionBody) {
442                    // Generate unique ID for the accordion body if it doesn't have one
443                    let bodyId = accordionBody.id;
444                    if (!bodyId) {
445                        bodyId = `ckyDetailCategory${accordionItem.id.replace('ckyDetailCategory', '')}Body`;
446                        accordionBody.id = bodyId;
447                    }
448                    // Always set aria-controls - the relationship is permanent
449                    accordionButton.setAttribute("aria-controls", bodyId);
450                }
451            }
452        }
453
454        _ckyToggleAriaExpandStatus(accordionButtonSelector, "false");
455        _ckyAttachListener(selector, ({ target: { id } }) => {
456            if (
457                id === `ckySwitch${category}` ||
458                !_ckyClassToggle(selector, "cky-accordion-active", false)
459            ) {
460                _ckyToggleAriaExpandStatus(accordionButtonSelector, "false");
461                return;
462            }
463            _ckyToggleAriaExpandStatus(accordionButtonSelector, "true");
464            categoryNames
465                .filter((categoryName) => categoryName !== category)
466                .map(filteredName => {
467                    _ckyClassRemove(
468                        `#ckyDetailCategory${filteredName}`,
469                        "cky-accordion-active",
470                        false
471                    );
472                    _ckyToggleAriaExpandStatus(
473                        `#ckyDetailCategory${filteredName} .cky-accordion-btn`,
474                        "false"
475                    );
476                    return filteredName;
477                });
478        });
479        return category;
480    });
481}
482/**
483 * Add support for accordion tabs on the privacy overview screen.
484 */
485function _ckyInitiAccordionTabs() {
486    document.querySelectorAll(".cky-accordion").forEach((item) => (
487        item.addEventListener('click', function (event) {
488            if (event.target.type === 'checkbox') return;
489            this.classList.toggle('cky-accordion-active');
490        })
491    ));
492}
493
494function _ckyToggleBanner(force = false) {
495    const notice = _ckyGetElementByTag('notice');
496    const container = notice && notice.closest('.cky-consent-container') || false;
497    if (container) {
498        force === true ? container.classList.add('cky-hide') : container.classList.toggle('cky-hide');
499    }
500
501}
502
503function _ckyToggleRevisit(force = false) {
504    const revisit = _ckyGetRevisit();
505    if (revisit) {
506        force === true ? _ckyRevisitHide() : revisit.classList.toggle('cky-revisit-hide');
507    }
508}
509function _ckyGetLaw() {
510    return _ckyStore._bannerConfig.settings.applicableLaw;
511}
512function _ckyGetType() {
513    return _ckyStore._bannerConfig.settings.type;
514}
515function _ckyGetPtype() {
516    if (_ckyGetType() === 'classic') {
517        return 'pushdown';
518    }
519    return _ckyStore._bannerConfig.settings.preferenceCenterType;
520}
521function _ckyGetBanner() {
522    const notice = _ckyGetElementByTag('notice');
523    const container = notice && notice.closest('.cky-consent-container') || false;
524    return container && container || false;
525}
526function _ckyHideBanner() {
527    const notice = _ckyGetBanner();
528    notice && notice.classList.add('cky-hide');
529}
530function _ckyShowBanner() {
531    const notice = _ckyGetBanner();
532    notice && notice.classList.remove('cky-hide');
533}
534function _ckyHideOverLay() {
535    const overlay = document.querySelector('.cky-overlay');
536    overlay && overlay.classList.add('cky-hide');
537}
538function _ckyShowOverLay() {
539    const overlay = document.querySelector('.cky-overlay');
540    overlay && overlay.classList.remove('cky-hide');
541}
542function _ckyToggleOverLay() {
543    const overlay = document.querySelector('.cky-overlay');
544    overlay && overlay.classList.toggle('cky-hide');
545}
546function _ckyGetPreferenceCenter() {
547    if (_ckyGetType() === 'classic') {
548        return _ckyGetBanner();
549    }
550    let element = _ckyGetLaw() === 'ccpa' ? _ckyGetElementByTag("optout-popup") : _ckyGetElementByTag("detail");
551    return element && element.closest('.cky-modal') || false;
552}
553function _ckyHidePreferenceCenter() {
554    _ckyResetOptoutSuccessMessage();
555    const element = _ckyGetPreferenceCenter();
556    element && element.classList.remove(_ckyGetPreferenceClass());
557
558    // ARIA attributes remain always present - only aria-expanded on settings button changes
559    // The modal relationship is permanent, only visibility changes
560
561    if (_ckyGetType() !== 'classic') {
562        _ckyHideOverLay();
563        if (!ref._ckyGetFromStore("action")) _ckyShowBanner();
564    } else {
565        _ckyToggleAriaExpandStatus("=settings-button", "false");
566        _ckyClassRemove("=notice", "cky-consent-bar-expand");
567    }
568    if (ref._ckyGetFromStore("action")) _ckyShowRevisit();
569    const origin = _ckyStore._preferenceOriginTag;
570    origin && _ckySetFocus(origin)
571}
572function _ckyShowPreferenceCenter() {
573    const element = _ckyGetPreferenceCenter();
574    element && element.classList.add(_ckyGetPreferenceClass());
575
576    // Ensure ARIA attributes are always present on the preference center div
577    if (element) {
578        const preferenceCenter = element.querySelector('.cky-preference-center');
579        if (preferenceCenter) {
580            const preferenceCenterId = _ckyGetLaw() === 'ccpa' ? 'ckyOptoutPreferenceCenter' : 'ckyPreferenceCenter';
581            preferenceCenter.setAttribute('id', preferenceCenterId);
582            preferenceCenter.setAttribute('role', 'dialog');
583            preferenceCenter.setAttribute('aria-modal', 'true');
584            const ariaLabel = _ckyGetLaw() === 'ccpa' ? 'Opt-out Preferences' : 'Customise Consent Preferences';
585            preferenceCenter.setAttribute('aria-label', ariaLabel);
586        }
587    }
588
589    if (_ckyGetType() !== 'classic') {
590        _ckyShowOverLay();
591        _ckyHideBanner();
592    } else {
593        _ckyToggleAriaExpandStatus("=settings-button");
594        _ckyClassAdd("=notice", "cky-consent-bar-expand");
595    }
596}
597function _ckyTogglePreferenceCenter() {
598    const element = _ckyGetPreferenceCenter();
599    if (!element) return;
600    element.classList.toggle(_ckyGetPreferenceClass());
601    if (_ckyGetPtype() !== 'pushdown') _ckyToggleOverLay();
602
603    const isOpen = element.classList.contains(_ckyGetPreferenceClass());
604    element.classList.toggle(_ckyGetPreferenceClass());
605    if (_ckyGetType() === 'classic') {
606        const preferenceCenter = element.querySelector('.cky-preference-center');
607        if (preferenceCenter) {
608            const preferenceCenterId = _ckyGetLaw() === 'ccpa' ? 'ckyOptoutPreferenceCenter' : 'ckyPreferenceCenter';
609            preferenceCenter.setAttribute('id', preferenceCenterId);
610            preferenceCenter.setAttribute('role', 'dialog');
611            preferenceCenter.setAttribute('aria-modal', 'true');
612            const ariaLabel = _ckyGetLaw() === 'ccpa' ? 'Opt-out Preferences' : 'Customise Consent Preferences';
613            preferenceCenter.setAttribute('aria-label', ariaLabel);
614        }
615        _ckyToggleAriaExpandStatus("=settings-button");
616        _ckyClassToggle("=notice", "cky-consent-bar-expand");
617    } else {
618        if (!isOpen) {
619            _ckyShowOverLay();
620            _ckyHideBanner();
621        } else {
622            _ckyHideOverLay();
623            if (!ref._ckyGetFromStore("action")) _ckyShowBanner();
624        }
625    }
626    if (ref._ckyGetFromStore("action")) _ckyShowRevisit();
627    const origin = _ckyStore._preferenceOriginTag;
628    origin && _ckySetFocus(origin)
629}
630function _ckyGetPreferenceClass() {
631    return _ckyGetPtype() === 'pushdown' ? 'cky-consent-bar-expand' : 'cky-modal-open';
632}
633
634function _ckyGetRevisit() {
635    const revisit = _ckyGetElementByTag('revisit-consent');
636    return revisit && revisit || false;
637}
638function _ckyHideRevisit() {
639    const revisit = _ckyGetRevisit();
640    revisit && revisit.classList.add('cky-revisit-hide')
641}
642function _ckyShowRevisit() {
643    const revisit = _ckyGetRevisit();
644    revisit && revisit.classList.remove('cky-revisit-hide')
645}
646function _ckySetPreferenceAction(tagName = false) {
647    _ckyStore._preferenceOriginTag = tagName;
648    if (_ckyGetType() === 'classic') {
649        _ckyTogglePreferenceCenter();
650        _ckyToggleAriaExpandStatus("=settings-button");
651    } else {
652        _ckyShowPreferenceCenter();
653    }
654}
655function _ckyGetFocusableElements(element) {
656    const wrapperElement = document.querySelector(`[data-cky-tag="${element}"]`);
657    if (!wrapperElement) return [];
658    const focussableElements = Array.from(
659        wrapperElement.querySelectorAll(
660            'a:not([disabled]), button:not([disabled]), [tabindex]:not([disabled]):not([tabindex="-1"])'
661        )
662    ).filter((element) => element.style.display !== "none");
663    if (focussableElements.length <= 0) return [];
664    return [
665        focussableElements[0],
666        focussableElements[focussableElements.length - 1],
667    ];
668}
669function _ckyLoopFocus() {
670    const activeLaw = _ckyGetLaw();
671    const bannerType = _ckyGetType();
672    if (bannerType === "classic") return;
673    if (bannerType === "popup") {
674        const [firstElementBanner, lastElementBanner] =
675            _ckyGetFocusableElements("notice");
676        _ckyAttachFocusLoop(firstElementBanner, lastElementBanner, true);
677        _ckyAttachFocusLoop(lastElementBanner, firstElementBanner);
678    }
679    const [firstElementPopup, lastElementPopup] = _ckyGetFocusableElements(
680        activeLaw === "ccpa" ? "optout-popup" : "detail"
681    );
682    _ckyAttachFocusLoop(firstElementPopup, lastElementPopup, true);
683    _ckyAttachFocusLoop(lastElementPopup, firstElementPopup);
684}
685function _ckyAttachFocusLoop(element, targetElement, isReverse = false) {
686    if (!element || !targetElement) return;
687    element.addEventListener("keydown", (event) => {
688        if (
689            event.which !== 9 ||
690            (isReverse && !event.shiftKey) ||
691            (!isReverse && event.shiftKey)
692        )
693            return;
694        event.preventDefault();
695        targetElement.focus();
696    });
697}
698
699/**
700 * Replace footer shadow with current preference center background.
701 * 
702 * @param {object} $doc Dom node.
703 * @returns 
704 */
705function _ckySetFooterShadow($doc) {
706    const footer = $doc.querySelector('[data-cky-tag="detail"] .cky-footer-shadow');
707    const preference = $doc.querySelector('[data-cky-tag="detail"]');
708    if (!footer) return;
709    const background = preference && preference.style.backgroundColor || '#ffffff';
710    footer.style.background = `linear-gradient(180deg, rgba(255, 255, 255, 0) 0%, ${background
711        } 100%)`;
712}
713
714/**
715 * Remove all the rejected cookies.
716 * 
717 * @param {object} cookies Cookies list.
718 */
719function _ckyRemoveDeadCookies({ cookies }) {
720    const currentCookieMap = ref._ckyGetCookieMap();
721    for (const { cookieID, domain } of cookies)
722        if (currentCookieMap[cookieID])
723            [domain, ""].map((cookieDomain) =>
724                ref._ckySetCookie(cookieID, "", 0, cookieDomain)
725            );
726}
727function _ckySetPreferenceCheckBoxStates(revisit = false) {
728    for (const category of _ckyStore._categories) {
729        const cookieValue = ref._ckyGetFromStore(category.slug);
730        const checked =
731            cookieValue === "yes" ||
732            (!cookieValue &&
733                category.defaultConsent[_ckyGetLaw()]) || category.isNecessary;
734
735        const disabled = category.isNecessary;
736        const shortCodeData = _ckyStore._shortCodes.find(
737            (code) => code.key === 'cky_category_toggle_label'
738        );
739        const toggleTextFormatted = shortCodeData.content.replace(
740            `[cky_preference_{{category_slug}}_title]`,
741            category.name
742        );
743        _ckySetCheckboxes(
744            category,
745            checked,
746            disabled,
747            toggleTextFormatted,
748            revisit
749        );
750        _ckySetPreferenceState(category);
751    }
752}
753
754function _ckySetCheckboxes(
755    category,
756    checked,
757    disabled,
758    formattedLabel,
759    revisit = false
760) {
761    const toggle = _ckyStore._bannerConfig.config.preferenceCenter.toggle;
762    const activeColor = toggle.states.active.styles['background-color'];
763    const inactiveColor = toggle.states.inactive.styles['background-color'];
764
765    [`ckyCategoryDirect`, `ckySwitch`].map((key) => {
766        const boxElem = document.getElementById(`${key}${category.slug}`);
767        if (!boxElem) return;
768        _ckySetCategoryToggle(
769            boxElem,
770            category,
771            revisit);
772        boxElem.checked = checked;
773        boxElem.disabled = disabled;
774        boxElem.style.backgroundColor = checked ? activeColor : inactiveColor;
775        _ckySetCheckBoxAriaLabel(boxElem, checked, formattedLabel);
776        if (revisit) return;
777        boxElem.addEventListener("change", ({ currentTarget: elem }) => {
778            const isChecked = elem.checked;
779            elem.style.backgroundColor = isChecked ? activeColor : inactiveColor;
780            _ckySetCheckBoxAriaLabel(boxElem, isChecked, formattedLabel);
781        });
782        return boxElem;
783    });
784}
785function _ckySetCategoryToggle(element, category = {}, revisit = false) {
786    if (revisit) return;
787    if (element.parentElement.getAttribute('data-cky-tag') === 'detail-category-toggle') {
788        _ckySetCategoryPreferenceToggle(element, category);
789    } else if (element.parentElement.getAttribute('data-cky-tag') === 'detail-category-preview-toggle') {
790        _ckySetCategoryPreview(element, category);
791    }
792    if (!category.isNecessary) {
793        const categoryName = category.name;
794        const categoryTitle = document.querySelector(`[data-cky-tag="detail-category-title"][aria-label="${categoryName}"]`);
795        if (categoryTitle) {
796            const toggleContainer = categoryTitle.closest('.cky-accordion-item');
797            const necessaryText = toggleContainer.querySelector('.cky-always-active');
798            necessaryText && necessaryText.remove();
799        }
800    }
801}
802function _ckySetCategoryPreferenceToggle(element, category) {
803    let toggleContainer = element.closest('.cky-accordion-item');
804    if (!toggleContainer) return;
805    const toggleSwitch = toggleContainer.querySelector('.cky-switch');
806    if (category.isNecessary) {
807        toggleSwitch && toggleSwitch.remove();
808    } else {
809        if (_ckyGetType() === 'classic' && _ckyStore._bannerConfig.config.categoryPreview.status || (category.cookies && category.cookies.length === 0)) {
810            toggleSwitch && toggleSwitch.remove();
811        }
812    }
813}
814function _ckySetPreferenceState(category) {
815    if (_ckyStore._bannerConfig.config.auditTable.status === false) {
816        const tableElement = document.querySelector(
817            `#ckyDetailCategory${category.slug} [data-cky-tag="audit-table"]`
818        );
819        tableElement && tableElement.remove();
820        const chevronElement = document.querySelector(
821            `#ckyDetailCategory${category.slug} .cky-accordion-chevron`
822        );
823        chevronElement && chevronElement.classList.add("cky-accordion-chevron-hide");
824    }
825}
826function _ckySetCategoryPreview(element, category) {
827    if ((category.cookies && category.cookies.length === 0) && !category.isNecessary)
828        element.parentElement.parentElement.remove();
829}
830
831function _ckySetCheckBoxAriaLabel(boxElem, isChecked, formattedLabel, isCCPA = false) {
832
833    if (!boxElem) return;
834    const keyName = isChecked ? "disable" : "enable";
835    const textCode = `cky_${keyName}_${isCCPA ? "optout" : "category"}_label`;
836    const shortCodeData = _ckyStore._shortCodes.find(
837        (code) => code.key === textCode
838    );
839    if (!shortCodeData) return;
840    const labelText = formattedLabel
841        .replace(/{{status}}/g, keyName)
842        .replace(`[${textCode}]`, shortCodeData.content);
843    boxElem.setAttribute("aria-label", labelText);
844}
845/**
846 * Clear opt-out success countdown timers (interval + timeout).
847 *
848 * @returns {void}
849 */
850function _ckyClearOptoutSuccessTimers() {
851    if (_ckyStore._optoutSuccessCountdownInterval) {
852        clearInterval(_ckyStore._optoutSuccessCountdownInterval);
853        _ckyStore._optoutSuccessCountdownInterval = null;
854    }
855    if (_ckyStore._optoutSuccessAutoCloseTimer) {
856        clearTimeout(_ckyStore._optoutSuccessAutoCloseTimer);
857        _ckyStore._optoutSuccessAutoCloseTimer = null;
858    }
859}
860
861function _ckyIsOptoutSuccessVisible() {
862    const el = _ckyGetElementByTag("optout-success");
863    return !!(el && !el.classList.contains("cky-hide"));
864}
865
866function _ckyDismissOptoutSuccessCountdown() {
867    _ckyRemoveBanner();
868    _ckyHidePreferenceCenter();
869    _ckyAfterConsent();
870}
871
872/**
873 * Show opt-out success UI after save, run countdown, then dismiss banner.
874 *
875 * @returns {void}
876 */
877function _ckyShowOptoutSuccessMessage() {
878    _ckyClearOptoutSuccessTimers();
879
880    const buttonWrapper = _ckyGetElementByTag("optout-buttons");
881    const successMessage = _ckyGetElementByTag("optout-success");
882    const countdownElement = _ckyGetElementByTag("optout-success-subtext");
883    const ccpaCheckbox = document.getElementById("ckyCCPAOptOut");
884
885    if (!buttonWrapper || !successMessage) {
886        _ckyDismissOptoutSuccessCountdown();
887        return;
888    }
889
890    buttonWrapper.style.display = "none";
891    successMessage.classList.remove("cky-hide");
892    successMessage.setAttribute("aria-live", "polite");
893    successMessage.focus();
894    if (ccpaCheckbox) ccpaCheckbox.disabled = true;
895    _ckyClassAdd("=optout-option", "cky-disabled", false);
896
897    const countdownTimerEl =
898        (countdownElement &&
899            countdownElement.querySelector("#ckyCountdownTimer")) ||
900        document.getElementById("ckyCountdownTimer");
901
902    let timeRemaining = CKY_OPTOUT_SUCCESS_SECONDS;
903    if (
904        countdownElement &&
905        !countdownTimerEl &&
906        !_ckyStore._optoutSuccessSubtextTemplate
907    ) {
908        _ckyStore._optoutSuccessSubtextTemplate =
909            countdownElement.textContent ||
910            `Banner closes automatically in ${CKY_OPTOUT_SUCCESS_SECONDS} s...`;
911    }
912    const template = _ckyStore._optoutSuccessSubtextTemplate;
913    const hasDigit = template && /\d+/.test(template);
914    const updateSubtext = () => {
915        if (!countdownElement) return;
916        if (countdownTimerEl) {
917            countdownTimerEl.textContent = String(timeRemaining);
918            return;
919        }
920        countdownElement.textContent = hasDigit
921            ? template.replace(/\d+/, String(timeRemaining))
922            : `Banner closes automatically in ${timeRemaining} s...`;
923    };
924    updateSubtext();
925
926    _ckyStore._optoutSuccessCountdownInterval = setInterval(() => {
927        timeRemaining -= 1;
928        if (timeRemaining >= 0) updateSubtext();
929    }, 1000);
930
931    _ckyStore._optoutSuccessAutoCloseTimer = setTimeout(
932        _ckyDismissOptoutSuccessCountdown,
933        CKY_OPTOUT_SUCCESS_DISMISS_MS
934    );
935}
936
937/**
938 * Reset opt-out success UI (timers, visibility, checkbox, subtext).
939 *
940 * @returns {void}
941 */
942function _ckyResetOptoutSuccessMessage() {
943    _ckyClearOptoutSuccessTimers();
944
945    const buttonWrapper = _ckyGetElementByTag("optout-buttons");
946    const successMessage = _ckyGetElementByTag("optout-success");
947    const countdownElement = _ckyGetElementByTag("optout-success-subtext");
948    const ccpaCheckbox = document.getElementById("ckyCCPAOptOut");
949
950    if (buttonWrapper) buttonWrapper.style.display = "";
951    if (successMessage) successMessage.classList.add("cky-hide");
952    if (ccpaCheckbox) ccpaCheckbox.disabled = false;
953    _ckyClassRemove("=optout-option", "cky-disabled", false);
954    const resetTimerEl =
955        (countdownElement &&
956            countdownElement.querySelector("#ckyCountdownTimer")) ||
957        document.getElementById("ckyCountdownTimer");
958    if (resetTimerEl) {
959        resetTimerEl.textContent = "";
960    } else if (countdownElement && _ckyStore._optoutSuccessSubtextTemplate) {
961        countdownElement.textContent = _ckyStore._optoutSuccessSubtextTemplate;
962    }
963}
964
965/**
966 * Opt-out confirm: if CCPA + opted out, save consent then show success + countdown; else normal save/close.
967 *
968 * @returns {Function} Click handler
969 */
970function _ckyHandleOptoutConfirm() {
971    return () => {
972        if (_ckyGetLaw() !== "ccpa" || !_ckyFindCheckBoxValue()) {
973            _ckyAcceptReject()();
974            return;
975        }
976        _ckyAcceptCookies();
977        _ckyShowOptoutSuccessMessage();
978    };
979}
980
981/**
982 * Opt-out popup close: dismiss countdown if success is visible, else normal close.
983 *
984 * @returns {void}
985 */
986function _ckyHandleOptoutPopupClose() {
987    if (_ckyIsOptoutSuccessVisible()) {
988        ref._ckySetInStore("action", "yes");
989        _ckyDismissOptoutSuccessCountdown();
990        return;
991    }
992    _ckyHidePreferenceCenter();
993}
994
995/**
996 * Render banner after processing.
997 */
998function _ckyRenderBanner() {
999    const template = document.getElementById('ckyBannerTemplate');
1000    const templateHtml = template.innerHTML;
1001    const doc = new DOMParser().parseFromString(templateHtml, 'text/html');
1002    _ckySetFooterShadow(doc);
1003    document.body.insertAdjacentHTML(
1004        "afterbegin",
1005        doc.body.innerHTML
1006    );
1007    if (_ckyGetType() === "classic") _ckyToggleAriaExpandStatus("=settings-button", "false");
1008    _ckySetPreferenceCheckBoxStates();
1009    _ckyAttachCategoryListeners();
1010    _ckyRegisterListeners();
1011    _ckySetCCPAOptions();
1012    _ckySetPlaceHolder();
1013    _ckyAttachReadMore();
1014    _ckyAttachShowMoreLessStyles();
1015    _ckyAttachAlwaysActiveStyles();
1016    _ckyAttachManualLinksStyles();
1017    _ckyRemoveStyles();
1018    _ckyAddPositionClass();
1019    _ckyAddRtlClass();
1020    _ckySetPoweredBy();
1021    _ckyLoopFocus();
1022    _ckyAddPreferenceCenterClass();
1023}
1024
1025/**
1026 * Accept or reject the consent based on the option.
1027 * 
1028 * @param {string} option Type of consent. 
1029 * @returns {void}
1030 */
1031function _ckyAcceptReject(option = "custom") {
1032    return () => {
1033        _ckyAcceptCookies(option);
1034        _ckyRemoveBanner();
1035        _ckyHidePreferenceCenter();
1036        _ckyAfterConsent();
1037    };
1038}
1039
1040function _ckyActionClose() {
1041    ref._ckySetInStore("action", "yes");
1042    if (_ckyIsOptoutSuccessVisible()) {
1043        _ckyDismissOptoutSuccessCountdown();
1044        return;
1045    }
1046    _ckyRemoveBanner();
1047}
1048/**
1049 * Consent accept callback.
1050 * 
1051 * @param {string} choice  Type of consent.
1052 */
1053function _ckyAcceptCookies(choice = "all") {
1054    const activeLaw = _ckyGetLaw();
1055    const ccpaCheckBoxValue = _ckyFindCheckBoxValue();
1056
1057    ref._ckySetInStore("action", "yes");
1058    if (activeLaw === 'gdpr') {
1059        ref._ckySetInStore("consent", choice === "reject" ? "no" : "yes");
1060    } else {
1061        ref._ckySetInStore("consent", ccpaCheckBoxValue ? "yes" : "no");
1062    }
1063    const responseCategories = { accepted: [], rejected: [] };
1064    for (const category of _ckyStore._categories) {
1065        let valueToSet = "no";
1066        if (activeLaw === 'gdpr') {
1067            valueToSet =
1068                !category.isNecessary &&
1069                    (choice === "reject" ||
1070                        (choice === "custom" && !_ckyFindCheckBoxValue(category.slug)))
1071                    ? "no"
1072                    : "yes";
1073        } else {
1074            valueToSet = ccpaCheckBoxValue && !category.defaultConsent.ccpa ? "no" : "yes";
1075        }
1076        ref._ckySetInStore(`${category.slug}`, valueToSet);
1077        if (valueToSet === "no") {
1078            responseCategories.rejected.push(category.slug);
1079            _ckyRemoveDeadCookies(category);
1080        } else responseCategories.accepted.push(category.slug);
1081    }
1082    _ckyUnblock();
1083    _ckyFireEvent(responseCategories);
1084}
1085function _ckySetShowMoreLess() {
1086    const activeLaw = _ckyGetLaw();
1087    const showCode = _ckyStore._shortCodes.find(
1088        (code) => code.key === "cky_show_desc"
1089    );
1090    const hideCode = _ckyStore._shortCodes.find(
1091        (code) => code.key === "cky_hide_desc"
1092    );
1093
1094    if (!showCode || !hideCode) return;
1095    const hideButtonContent = hideCode.content;
1096    const showButtonContent = showCode.content;
1097
1098    const contentLimit = window.innerWidth < 376 ? 150 : 300;
1099    const element = document.querySelector(
1100        `[data-cky-tag="${activeLaw === "gdpr" ? "detail" : "optout"}-description"]`
1101    );
1102    if (!element) return;
1103    const content = element.textContent;
1104    if (content.length < contentLimit) return;
1105    const contentHTML = element.innerHTML;
1106    const htmlDoc = new DOMParser().parseFromString(contentHTML, "text/html");
1107    const innerElements = htmlDoc.querySelectorAll("body > p");
1108    if (innerElements.length <= 1) return;
1109    let strippedContent = ``;
1110    for (let index = 0; index < innerElements.length; index++) {
1111        if (index === innerElements.length - 1) continue;
1112        const el = innerElements[index];
1113        if (`${strippedContent}${el.outerHTML}`.length > contentLimit)
1114            el.insertAdjacentHTML("beforeend", `...&nbsp;${showButtonContent}`);
1115        strippedContent = `${strippedContent}${el.outerHTML}`;
1116        if (strippedContent.length > contentLimit) break;
1117    }
1118
1119    function showMoreHandler() {
1120        element.innerHTML = `${contentHTML}${hideButtonContent}`;
1121        _ckyAttachListener("=hide-desc-button", showLessHandler);
1122        _ckyAttachShowMoreLessStyles();
1123    }
1124    function showLessHandler() {
1125        element.innerHTML = strippedContent;
1126        _ckyAttachListener("=show-desc-button", showMoreHandler);
1127        _ckyAttachShowMoreLessStyles();
1128    }
1129    showLessHandler();
1130}
1131/**
1132 * Toggle show more or less on click event.
1133 * 
1134 * @param {object} object Object containing toggle buttons and texts.
1135 * @param {*} element Target element.
1136 */
1137function _ckyToggleMoreLess(object, element) {
1138    let {
1139        currentTarget,
1140        target
1141    } = element;
1142    if (target && target.tagName.toUpperCase() !== 'BUTTON') return;
1143    const ariaExpanded = currentTarget.getAttribute('aria-expanded');
1144    const trimmed = ariaExpanded === 'false';
1145    let btn = object.btnTrim;
1146    let text = object.originalText;
1147    if (!trimmed) {
1148        btn = object.btnExpand;
1149        text = object.truncatedText;
1150    }
1151    currentTarget.innerHTML = `${text}${btn}`;
1152    currentTarget.ariaExpanded = trimmed;
1153}
1154
1155/**
1156 * Add styles to the shortcode HTML rendered outside of the banner.
1157 * 
1158 * @returns {void}
1159 */
1160function _ckyAttachShortCodeStyles() {
1161    const shortCodes = _ckyStore._tags;
1162    Array.prototype.forEach.call(shortCodes, function (shortcode) {
1163        document.querySelectorAll('[data-cky-tag=' + shortcode.tag + ']').forEach(function (item) {
1164            let styles = '';
1165            for (const key in shortcode.styles) {
1166                styles += `${key}: ${shortcode.styles[key]};`;
1167            }
1168            item.style.cssText = styles;
1169        });
1170    });
1171}
1172
1173/** Script blocker Version 2 */
1174
1175const _ckyCreateElementBackup = document.createElement;
1176document.createElement = (...args) => {
1177    const createdElement = _ckyCreateElementBackup.call(document, ...args);
1178    if (createdElement.nodeName.toLowerCase() !== "script") return createdElement;
1179    const originalSetAttribute = createdElement.setAttribute.bind(createdElement);
1180    Object.defineProperties(createdElement, {
1181        src: {
1182            get: function () {
1183                return createdElement.getAttribute("src");
1184            },
1185            set: function (value) {
1186                if (_ckyShouldChangeType(createdElement, value))
1187                    originalSetAttribute("type", "javascript/blocked");
1188                originalSetAttribute("src", value);
1189                return true;
1190            },
1191        },
1192        type: {
1193            get: function () {
1194                return createdElement.getAttribute("type");
1195            },
1196            set: function (value) {
1197                value = _ckyShouldChangeType(createdElement)
1198                    ? "javascript/blocked"
1199                    : value;
1200                originalSetAttribute("type", value);
1201                return true;
1202            },
1203        },
1204    });
1205    createdElement.setAttribute = (name, value) => {
1206        if (name === "type" || name === "src")
1207            return (createdElement[name] = value);
1208        originalSetAttribute(name, value);
1209        if (name === "data-cookieyes" && !_ckyShouldChangeType(createdElement))
1210            originalSetAttribute("type", "text/javascript");
1211    };
1212    return createdElement;
1213};
1214
1215function _ckyMutationObserver(mutations) {
1216    for (const { addedNodes } of mutations) {
1217        for (const node of addedNodes) {
1218            if (
1219                !node.src ||
1220                !node.nodeName ||
1221                !["script", "iframe"].includes(node.nodeName.toLowerCase())
1222            )
1223                continue;
1224            try {
1225                const urlToParse = node.src.startsWith("//")
1226                    ? `${window.location.protocol}${node.src}`
1227                    : node.src;
1228                const { hostname, pathname } = new URL(urlToParse);
1229                const cleanedHostname = _ckyCleanHostName(`${hostname}${pathname}`);
1230                _ckyAddProviderToList(node, cleanedHostname);
1231                if (!_ckyShouldBlockProvider(cleanedHostname)) continue;
1232                const uniqueID = ref._ckyRandomString(8, false);
1233                if (node.nodeName.toLowerCase() === "iframe")
1234                    _ckyAddPlaceholder(node, uniqueID);
1235                else {
1236                    node.type = "javascript/blocked";
1237                    const scriptEventListener = function (event) {
1238                        event.preventDefault();
1239                        node.removeEventListener(
1240                            "beforescriptexecute",
1241                            scriptEventListener
1242                        );
1243                    };
1244                    node.addEventListener("beforescriptexecute", scriptEventListener);
1245                }
1246                const position =
1247                    document.head.compareDocumentPosition(node) &
1248                        Node.DOCUMENT_POSITION_CONTAINED_BY
1249                        ? "head"
1250                        : "body";
1251                node.remove();
1252                _ckyStore._backupNodes.push({
1253                    position: position,
1254                    node: node.cloneNode(),
1255                    uniqueID,
1256                });
1257            } catch (error) {
1258            }
1259        }
1260    }
1261}
1262
1263function _ckyUnblock() {
1264    if (navigator.doNotTrack === 1) return;
1265    const ckyconsent = ref._ckyGetFromStore("consent");
1266    if (
1267        _ckyGetLaw() === "gdpr" &&
1268        (!ckyconsent || ckyconsent !== "yes")
1269    )
1270        return;
1271    _ckyStore._backupNodes = _ckyStore._backupNodes.filter(
1272        ({ position, node, uniqueID }) => {
1273            try {
1274                if (_ckyShouldBlockProvider(node.src)) return true;
1275                if (node.nodeName.toLowerCase() === "script") {
1276                    const scriptNode = document.createElement("script");
1277                    scriptNode.src = node.src;
1278                    scriptNode.type = "text/javascript";
1279                    document[position].appendChild(scriptNode);
1280                } else {
1281                    const frame = document.getElementById(uniqueID);
1282                    if (!frame) return false;
1283                    const iframe = document.createElement("iframe");
1284                    iframe.src = node.src;
1285                    iframe.width = frame.offsetWidth;
1286                    iframe.height = frame.offsetHeight;
1287                    frame.parentNode.insertBefore(iframe, frame);
1288                    frame.parentNode.removeChild(frame);
1289                }
1290                return false;
1291            } catch (error) {
1292                console.error(error);
1293                return false;
1294            }
1295        }
1296    );
1297}
1298
1299function _ckyClearListeners() {
1300    _nodeListObserver.disconnect();
1301    document.createElement = _ckyCreateElementBackup;
1302}
1303function _ckyAddProviderToList(node, cleanedHostname) {
1304    const nodeCategory =
1305        node.hasAttribute("data-cookieyes") && node.getAttribute("data-cookieyes");
1306    if (!nodeCategory) return;
1307    const categoryName = nodeCategory.replace("cookieyes-", "");
1308    for (const category of _ckyStore._categories)
1309        if (category.isNecessary && category.slug === categoryName) return;
1310    const provider = _ckyStore._providersToBlock.find(
1311        ({ re }) => re === cleanedHostname
1312    );
1313    if (!provider)
1314        _ckyStore._providersToBlock.push({
1315            re: cleanedHostname,
1316            categories: [categoryName],
1317            fullPath: false,
1318        });
1319    else if (!provider.isOverridden) {
1320        provider.categories = [categoryName];
1321        provider.isOverridden = true;
1322    } else if (!provider.categories.includes(categoryName))
1323        provider.categories.push(categoryName);
1324}
1325
1326const _nodeListObserver = new MutationObserver(_ckyMutationObserver);
1327_nodeListObserver.observe(document.documentElement, {
1328    childList: true,
1329    subtree: true,
1330});
1331function _ckyCleanHostName(name) {
1332    return name.replace(/^www./, "");
1333}
1334
1335function _ckyIsCategoryToBeBlocked(category) {
1336    const cookieValue = ref._ckyGetFromStore(category);
1337    return (
1338        cookieValue === "no" ||
1339        (!cookieValue &&
1340            _ckyStore._categories.some(
1341                (cat) => cat.slug === category && !cat.isNecessary
1342            ))
1343    );
1344}
1345
1346function _ckyShouldBlockProvider(formattedRE) {
1347    const provider = _ckyStore._providersToBlock.find(({ re }) =>
1348        new RegExp(_ckyEscapeRegex(re)).test(formattedRE)
1349    );
1350    return (
1351        provider &&
1352        provider.categories.some((category) => _ckyIsCategoryToBeBlocked(category))
1353    );
1354}
1355function _ckyShouldChangeType(element, src) {
1356    return (
1357        (element.hasAttribute("data-cookieyes") &&
1358            _ckyIsCategoryToBeBlocked(
1359                element.getAttribute("data-cookieyes").replace("cookieyes-", "")
1360            )) ||
1361        _ckyShouldBlockProvider(src ? src : element.src)
1362    );
1363}
1364
1365/**
1366 * Add readmore button to consent notice.
1367 * 
1368 * @returns void
1369 */
1370function _ckyAttachReadMore() {
1371    const readMoreButton = _ckyStore._shortCodes.find(
1372        (code) => code.key === "cky_readmore"
1373    );
1374    if (!readMoreButton.status) return;
1375    const content = readMoreButton.content;
1376    const styles = _ckyStore._bannerConfig.config.readMore.styles;
1377    const readMoreElement = document.querySelector(
1378        '[data-cky-tag="description"]'
1379    );
1380    if (!readMoreElement) return;
1381    if (readMoreElement.childNodes.length > 1) {
1382        const innerElement = document.querySelector(
1383            '[data-cky-tag="description"] p:last-child'
1384        );
1385        innerElement && innerElement.insertAdjacentHTML(
1386            "beforeend",
1387            `&nbsp;${content}`
1388        );
1389    } else {
1390        readMoreElement.insertAdjacentHTML(
1391            "beforeend",
1392            `&nbsp;${content}`
1393        );
1394    }
1395    const placeHolders = document.querySelectorAll(
1396        `[data-cky-tag="readmore-button"]`
1397    );
1398    if (placeHolders.length < 1) return;
1399    Array.from(placeHolders).forEach((placeHolder) => {
1400        for (const style in styles) {
1401            if (!styles[style]) continue;
1402            placeHolder.style[style] = styles[style];
1403        }
1404    });
1405}
1406
1407/**
1408 * Apply styles to show more/show less buttons.
1409 * 
1410 * @returns void
1411 */
1412function _ckyAttachShowMoreLessStyles() {
1413    if (!_ckyStore._bannerConfig.config.showMore || !_ckyStore._bannerConfig.config.showLess) return;
1414    
1415    const showMoreStyles = _ckyStore._bannerConfig.config.showMore.styles;
1416    const showLessStyles = _ckyStore._bannerConfig.config.showLess.styles;
1417    
1418    if (showMoreStyles) {
1419        const showMoreButtons = document.querySelectorAll('[data-cky-tag="show-desc-button"]');
1420        if (showMoreButtons.length > 0) {
1421            Array.from(showMoreButtons).forEach((button) => {
1422                for (const style in showMoreStyles) {
1423                    if (!showMoreStyles[style]) continue;
1424                    button.style[style] = showMoreStyles[style];
1425                }
1426            });
1427        }
1428    }
1429    
1430    if (showLessStyles) {
1431        const showLessButtons = document.querySelectorAll('[data-cky-tag="hide-desc-button"]');
1432        if (showLessButtons.length > 0) {
1433            Array.from(showLessButtons).forEach((button) => {
1434                for (const style in showLessStyles) {
1435                    if (!showLessStyles[style]) continue;
1436                    button.style[style] = showLessStyles[style];
1437                }
1438            });
1439        }
1440    }
1441}
1442
1443/**
1444 * Apply styles to Always Active text.
1445 * 
1446 * @returns void
1447 */
1448function _ckyAttachAlwaysActiveStyles() {
1449    if (!_ckyStore._bannerConfig.config.alwaysActive) return;
1450    
1451    const alwaysActiveStyles = _ckyStore._bannerConfig.config.alwaysActive.styles;
1452    if (!alwaysActiveStyles) return;
1453    
1454    const alwaysActiveElements = document.querySelectorAll('.cky-always-active');
1455    if (alwaysActiveElements.length < 1) return;
1456    Array.from(alwaysActiveElements).forEach((element) => {
1457        for (const style in alwaysActiveStyles) {
1458            if (!alwaysActiveStyles[style]) continue;
1459            element.style[style] = alwaysActiveStyles[style];
1460        }
1461    });
1462}
1463
1464/**
1465 * Apply styles to manually added links.
1466 * 
1467 * @returns void
1468 */
1469function _ckyAttachManualLinksStyles() {
1470    if (!_ckyStore._bannerConfig.config.manualLinks) return;
1471    
1472    const manualLinksStyles = _ckyStore._bannerConfig.config.manualLinks.styles;
1473    if (!manualLinksStyles) return;
1474    
1475    const manualLinks = document.querySelectorAll('.cky-link, a.cky-link, [data-cky-tag="detail"] a, [data-cky-tag="optout-popup"] a, [data-cky-tag="notice"] a');
1476    if (manualLinks.length < 1) return;
1477    Array.from(manualLinks).forEach((link) => {
1478        if (link.getAttribute('data-cky-tag') === 'readmore-button') return;
1479        for (const style in manualLinksStyles) {
1480            if (!manualLinksStyles[style]) continue;
1481            link.style[style] = manualLinksStyles[style];
1482        }
1483        if (manualLinksStyles.color) {
1484            link.style.textDecorationColor = manualLinksStyles.color;
1485        }
1486    });
1487}
1488
1489function _ckyAfterConsent() {
1490    if (_ckyGetLaw() === 'gdpr') _ckySetPreferenceCheckBoxStates(true);
1491
1492    if (_ckyStore._bannerConfig.behaviours.reloadBannerOnAccept === true) {
1493        window.location.reload();
1494    }
1495}
1496
1497function _ckyAttachNoticeStyles() {
1498    if (document.getElementById("cky-style") || !_ckyStyle) return;
1499    document.head.insertAdjacentHTML(
1500        "beforeend",
1501        ` <style id="cky-style">${_ckyStyle.css}</style>`
1502    );
1503}
1504
1505function _ckyFindCheckBoxValue(id = "") {
1506    const elementsToCheck = id
1507        ? [`ckySwitch`, `ckyCategoryDirect`]
1508        : [`ckyCCPAOptOut`];
1509    return elementsToCheck.some((key) => {
1510        const checkBox = document.getElementById(`${key}${id}`);
1511        return checkBox && checkBox.checked;
1512    });
1513}
1514
1515function _ckyAddPlaceholder(htmlElm, uniqueID) {
1516    const shortCodeData = _ckyStore._shortCodes.find(
1517        (code) => code.key === 'cky_video_placeholder'
1518    );
1519    const videoPlaceHolderDataCode = shortCodeData.content;
1520    const { offsetWidth, offsetHeight } = htmlElm;
1521    if (offsetWidth === 0 || offsetHeight === 0) return;
1522    htmlElm.insertAdjacentHTML(
1523        "beforebegin",
1524        `${videoPlaceHolderDataCode}`.replace("[UNIQUEID]", uniqueID)
1525    );
1526    const addedNode = document.getElementById(uniqueID);
1527    addedNode.style.width = `${offsetWidth}px`;
1528    addedNode.style.height = `${offsetHeight}px`;
1529    const innerTextElement = document.querySelector(
1530        `#${uniqueID} .video-placeholder-text-normal`
1531    );
1532    innerTextElement.style.display = "none";
1533    const youtubeID = _ckyGetYoutubeID(htmlElm.src);
1534    if (!youtubeID) return;
1535    addedNode.classList.replace(
1536        "video-placeholder-normal",
1537        "video-placeholder-youtube"
1538    );
1539    addedNode.style.backgroundImage = `linear-gradient(rgba(76,72,72,.7),rgba(76,72,72,.7)),url('https://img.youtube.com/vi/${youtubeID}/maxresdefault.jpg')`;
1540    innerTextElement.classList.replace(
1541        "video-placeholder-text-normal",
1542        "video-placeholder-text-youtube"
1543    );
1544}
1545function _ckyGetYoutubeID(src) {
1546    const match = src.match(
1547        /^.*(youtu\.be\/|v\/|u\/\w\/|embed\/|watch\?v=|\&v=)([^#\&\?]*).*/
1548    );
1549    if (match && Array.isArray(match) && match[2] && match[2].length === 11)
1550        return match[2];
1551    return false;
1552}
1553
1554function _ckySetPlaceHolder() {
1555    const status = _ckyStore._bannerConfig.config.videoPlaceholder.status;
1556    const styles = _ckyStore._bannerConfig.config.videoPlaceholder.styles;
1557    if (!status) return;
1558    if (!status) return;
1559    const placeHolders = document.querySelectorAll(
1560        `[data-cky-tag="placeholder-title"]`
1561    );
1562    if (placeHolders.length < 1) return;
1563    Array.from(placeHolders).forEach((placeHolder) => {
1564        placeHolder.style.display = "block";
1565        placeHolder.addEventListener("click", () => {
1566            if (ref._ckyGetFromStore("action")) _revisitCkyConsent();
1567        });
1568        for (const style in styles) {
1569            if (!styles[style]) continue;
1570            placeHolder.style[style] = styles[style];
1571        }
1572    });
1573}
1574function _ckyAddRtlClass() {
1575    if (!_ckyStore._rtl) return;
1576    const rtlElements = ['notice', 'detail', 'optout-popup', 'revisit-consent', 'video-placeholder']
1577    rtlElements.forEach(function (item) {
1578        _ckyGetElementByTag(item) && _ckyGetElementByTag(item).classList.add('cky-rtl');
1579    });
1580}
1581
1582function _ckySetFocus(tagName) {
1583    const element = _ckyGetElementByTag(tagName);
1584    if (!element) return;
1585    element.focus();
1586}
1587
1588function _ckySetPoweredBy() {
1589    let position = 'flex-end';
1590    ['detail-powered-by', 'optout-powered-by'].map((key) => {
1591        const element = document.querySelector(
1592            `[data-cky-tag="${key}"]`
1593        );
1594        if (!element) return;
1595        element.style.display = "flex";
1596        element.style.justifyContent = position;
1597        element.style.alignItems = "center";
1598        return element;
1599    });
1600
1601}
1602function _ckyWatchBannerElement() {
1603    document.querySelector("body").addEventListener("click", (event) => {
1604        const selector = ".cky-banner-element, .cky-banner-element *";
1605        if (
1606            event.target.matches
1607                ? event.target.matches(selector)
1608                : event.target.msMatchesSelector(selector)
1609        )
1610            _revisitCkyConsent();
1611    });
1612}
1613
1614function _ckyRemoveAllDeadCookies() {
1615    for (const category of _ckyStore._categories) {
1616        if (ref._ckyGetFromStore(category.slug) !== "yes")
1617            _ckyRemoveDeadCookies(category);
1618    }
1619}
1620
1621function _ckySetCCPAOptions() {
1622    const toggle = _ckyStore._bannerConfig.config.optOption.toggle;
1623    const activeColor = toggle.states.active.styles['background-color'];
1624    const inactiveColor = toggle.states.inactive.styles['background-color'];
1625    _ckyClassRemove("=optout-option", "cky-disabled", false);
1626    const toggleDataCode = _ckyStore._shortCodes.find(
1627        (code) => code.key === "cky_optout_toggle_label"
1628    );
1629    const optOutTitle = _ckyStore._shortCodes.find(
1630        (code) => code.key === "cky_optout_option_title"
1631    );
1632    const formattedLabel = toggleDataCode.content.replace(
1633        `[cky_optout_option_title]`,
1634        optOutTitle.content
1635    );
1636    const checked = ref._ckyGetFromStore("consent") === "yes";
1637    _ckySetCheckBoxInfo(
1638        document.getElementById(`ckyCCPAOptOut`),
1639        formattedLabel,
1640        {
1641            checked,
1642            disabled: false,
1643            addListeners: true,
1644        },
1645        { activeColor, inactiveColor },
1646        true
1647    );
1648}
1649function _ckySetCheckBoxInfo(
1650    boxElem,
1651    formattedLabel,
1652    { checked, disabled, addListeners },
1653    { activeColor, inactiveColor },
1654    isCCPA = false
1655) {
1656    if (!boxElem) return;
1657    if (isCCPA && addListeners)
1658        _ckyAttachListener("=optout-option-title", () => boxElem.click());
1659    boxElem.checked = checked;
1660    boxElem.disabled = disabled;
1661    boxElem.style.backgroundColor = checked ? activeColor : inactiveColor;
1662    _ckySetCheckBoxAriaLabel(boxElem, checked, formattedLabel, isCCPA);
1663    if (!addListeners) return;
1664    boxElem.addEventListener("change", ({ currentTarget: elem }) => {
1665        const isChecked = elem.checked;
1666        elem.style.backgroundColor = isChecked ? activeColor : inactiveColor;
1667        _ckySetCheckBoxAriaLabel(boxElem, isChecked, formattedLabel, isCCPA);
1668    });
1669}
1670
1671window.revisitCkyConsent = () => _revisitCkyConsent();
1672
1673window.getCkyConsent = function () {
1674    const cookieConsent = {
1675        activeLaw: "",
1676        categories: {},
1677        isUserActionCompleted: false,
1678        consentID: "",
1679        languageCode: ""
1680    };
1681
1682    try {
1683        cookieConsent.activeLaw = _ckyGetLaw();
1684
1685        _ckyStore._categories.forEach(category => {
1686            cookieConsent.categories[category.slug] = ref._ckyGetFromStore(category.slug) === "yes";
1687        });
1688
1689        cookieConsent.isUserActionCompleted = ref._ckyGetFromStore("action") === "yes";
1690        cookieConsent.consentID = ref._ckyGetFromStore("consentid") || "";
1691        cookieConsent.languageCode = _ckyStore._language || "";
1692    } catch (e) { }
1693
1694    return cookieConsent;
1695};

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.