PageSourceSearch

https://www.livanub.lv/app/plugins/complianz-gdpr/cookiebanner/js/complianz.js?ver=6.0.51790992520

js livanub.lv collected 2026-10-03 01:56:19 UTC 58,727 bytes, 1,909 lines download raw bytes

1'use strict';
2/**
3 * Opt in (e.g. EU):
4 * default all scripts disabled.
5 * cookie banner
6 *
7 * Opt out (e.g. US):
8 * default all scripts enabled
9 * opt out cookie banner
10 *
11 * Other regions:
12 * default all scripts enabled
13 * no banner
14 *
15 *
16 * For examples to edit the behaviour of the banner, please see https://github.com/really-Simple-Plugins/complianz-integrations
17 * */
18
19/**
20 * Create an element
21 * @param el
22 * @param content
23 * @returns {*}
24 */
25function cmplz_create_element(el, content) {
26	let obj = document.createElement(el);
27	obj.innerHtml = content;
28	return obj;
29}
30
31/**
32 * Add an event
33 * @param event
34 * @param selector
35 * @param callback
36 * @param context
37 */
38function cmplz_add_event(event, selector, callback ) {
39	document.addEventListener(event, e => {
40		if ( e.target.closest(selector) ) {
41			callback(e);
42		}
43	});
44}
45
46/**
47 * Check if the element is hidden
48 * @param el
49 * @returns {boolean}
50 */
51function cmplz_is_hidden(el) {
52	return (el.offsetParent === null)
53}
54
55function cmplz_html_decode(input) {
56	var doc = new DOMParser().parseFromString(input, "text/html");
57	return doc.documentElement.textContent;
58}
59/**
60 * If an anchor is passed for an element which may load only after an ajax call, make sure it will scroll into view.
61 */
62document.addEventListener('cmplz_manage_consent_container_loaded', function(e){
63	let url = window.location.href;
64	if ( url.indexOf('#') != -1 ) {
65		let end_pos = url.lastIndexOf("?") != -1 ? url.lastIndexOf("?") : undefined;
66		var anchor = url.substring(url.indexOf("#") + 1, end_pos);
67		const element = document.getElementById(anchor);
68		if (element) {
69			const y = element.getBoundingClientRect().top + window.pageYOffset - 200;
70			window.scrollTo({top: y, behavior: 'smooth'});
71		}
72	}
73});
74
75/**
76 * prevent caching of the WP Rest API by varnish or other caching tools
77 */
78complianz.locale = complianz.locale + '&token='+Math.random().toString(36).replace(/[^a-z]+/g, '').substr(0, 5);
79
80/**
81 * CustomEvent() polyfill
82 * https://developer.mozilla.org/en-US/docs/Web/API/CustomEvent/CustomEvent#Polyfill
83 */
84(function () {
85	if (typeof window.CustomEvent === 'function') return false;
86	function CustomEvent(event, params) {
87		params = params || { bubbles: false, cancelable: false, detail: undefined };
88		var evt = document.createEvent('CustomEvent');
89		evt.initCustomEvent(event, params.bubbles, params.cancelable, params.detail);
90		return evt;
91	}
92	CustomEvent.prototype = window.Event.prototype;
93	window.CustomEvent = CustomEvent;
94})();
95
96let cmplz_banner;//look this one up when the cookiebanner loads.
97let cmplz_banner_container = document.getElementById('cmplz-cookiebanner-container');
98let cmplz_manage_consent_button;
99let cmplz_waiting_inline_scripts = [];
100let cmplz_waiting_scripts = [];
101let cmplz_fired_scripts = [];
102let cmplz_placeholder_class_index = 0;
103let cmplz_all_scripts_hook_fired = false;
104let cmplz_consent_stored_once = false;
105let cmplz_categories = [
106	'functional',
107	'preferences',
108	'statistics',
109	'marketing',
110];
111
112/**
113 * Get a cookie by name
114 * @param name
115 * @returns {string}
116 */
117
118window.cmplz_get_cookie = function(name) {
119	if (typeof document === 'undefined') {
120		return '';
121	}
122	name = complianz.prefix+name + "=";
123	let cArr = document.cookie.split(';');
124	for (let i = 0; i < cArr.length; i++) {
125		let c = cArr[i].trim();
126		if (c.indexOf(name) == 0)
127			return c.substring(name.length, c.length);
128	}
129
130	return "";
131}
132
133/**
134 * set a cookie
135 * @param name
136 * @param value
137 * @param use_prefix
138 */
139
140window.cmplz_set_cookie = function(name, value, use_prefix) {
141	if (typeof document === 'undefined') {
142		return;
143	}
144	if (typeof use_prefix === 'undefined') {
145		use_prefix = true;
146	}
147	let secure = ";secure";
148	let date = new Date();
149	date.setTime(date.getTime() + (complianz.cookie_expiry * 24 * 60 * 60 * 1000));
150	let expires = ";expires=" + date.toGMTString();
151
152	if (window.location.protocol !== "https:") secure = '';
153
154	let domain = cmplz_get_cookie_domain();
155	if (domain.length > 0) {
156		domain = ";domain=" + domain;
157	}
158	let prefix = '';
159	if ( use_prefix ) {
160		prefix = complianz.prefix;
161	}
162	document.cookie = prefix+name + "=" + value + ";SameSite=Lax" + secure + expires + domain + ";path="+cmplz_get_cookie_path();
163}
164
165/**
166 * Check if needle occurs in the haystack
167 * @param needle
168 * @param haystack
169 * @returns {boolean}
170 */
171window.cmplz_in_array = function(needle, haystack) {
172	let length = haystack.length;
173	for(let i = 0; i < length; i++) {
174		if(haystack[i] == needle) return true;
175	}
176	return false;
177}
178
179/**
180 * Retrieve the highest level of consent that has been given
181 *
182 * */
183
184window.cmplz_highest_accepted_category = function() {
185	var consentedCategories = cmplz_accepted_categories();
186	if (cmplz_in_array( 'marketing', consentedCategories )) {
187		return 'marketing';
188	}
189
190	if (cmplz_in_array( 'statistics', consentedCategories )) {
191		return 'statistics';
192	}
193
194	if (cmplz_in_array( 'preferences', consentedCategories )) {
195		return 'preferences';
196	}
197
198	return 'functional';
199}
200
201/**
202 * Accept all categories
203 */
204window.cmplz_accept_all = function(){
205	for (var key in cmplz_categories) {
206		if ( cmplz_categories.hasOwnProperty(key) ) {
207			cmplz_set_consent(cmplz_categories[key], 'allow');
208		}
209	}
210}
211
212/**
213 * Sets all accepted categories as class in body
214 */
215
216function cmplz_set_category_as_body_class() {
217	let classList = document.body.className.split(/\s+/);
218	for (let i = 0; i < classList.length; i++) {
219		if ( classList[i].indexOf('cmplz-') !== -1 && classList[i] !== 'cmplz-document' ) {
220			document.body.classList.remove( classList[i] );
221		}
222	}
223
224	let cats = cmplz_accepted_categories();
225	for (let i in cats) {
226		if ( cats.hasOwnProperty(i) ) {
227			document.body.classList.add('cmplz-' + cats[i]);
228		}
229	}
230
231	let services = cmplz_get_all_service_consents();
232	for (let service in services) {
233		if ( services.hasOwnProperty(service) && services[service]) {
234			document.body.classList.add('cmplz-' + service);
235		}
236	}
237
238	document.body.classList.add('cmplz-' + complianz.region);
239	document.body.classList.add('cmplz-' + complianz.consenttype);
240	let event = new CustomEvent('cmplz_set_category_as_bodyclass');
241	document.dispatchEvent(event);
242}
243
244function cmplz_append_css(css){
245	let head = document.getElementsByTagName('head')[0];
246	let style = document.createElement('style');
247	style.setAttribute('type', 'text/css');
248	if (style.styleSheet) {   // IE
249		style.styleSheet.cssText = css;
250	} else {                // the world
251		style.appendChild(document.createTextNode(css));
252	}
253	head.appendChild(style);
254}
255
256function cmplz_load_css( path ) {
257	let fileref = document.createElement("link")
258	fileref.setAttribute("rel", "stylesheet")
259	fileref.setAttribute("type", "text/css")
260	fileref.setAttribute("href", path)
261	document.getElementsByTagName("head")[0].appendChild(fileref)
262}
263
264/**
265 * Run script, src or inline
266 * @param script //src or inline script
267 * @param category
268 */
269
270function cmplz_run_script( script, category, type ) {
271	let fileref = document.createElement("script");
272	fileref.setAttribute("type", "text/javascript");
273	if ( type !== 'inline' ) {
274		fileref.setAttribute("src", script);
275	} else {
276		if (typeof script !== 'string') {
277			script = script.innerHTML;
278		}
279		fileref.innerHTML = script;
280	}
281	//check if already fired
282	if ( cmplz_in_array( script, cmplz_fired_scripts) ) {
283		return;
284	}
285
286	fileref.onload = function () {
287		cmplz_maybe_run_waiting_scripts(script, category);
288		cmplz_run_after_all_scripts(category);
289	}
290
291	try {
292		document.getElementsByTagName("head")[0].appendChild(fileref);
293		cmplz_fired_scripts.push(script);
294	} catch(exception) {
295		throw "Something went wrong " + exception + " while loading "+path;
296	}
297	cmplz_run_after_all_scripts(category);
298}
299
300
301/**
302 * Check if there are waiting scripts, and if so, run them.
303 * @param script //src or inline script
304 * @param category
305 */
306
307function cmplz_maybe_run_waiting_scripts( script, category ){
308	let waitingScript = cmplz_get_waiting_script(cmplz_waiting_scripts, script);
309	if ( waitingScript ) {
310		cmplz_run_script( waitingScript, category, 'src' );
311	}
312
313	let waiting_inline_script = cmplz_get_waiting_script(cmplz_waiting_inline_scripts, script);
314	if (waiting_inline_script) {
315		cmplz_run_script(waiting_inline_script, category, 'inline');
316	}
317
318	cmplz_run_after_all_scripts(category);
319}
320
321/**
322 * Set placeholder image as background on the parent div, set notice, and handle height.
323 *
324 * */
325
326function cmplz_set_blocked_content_container() {
327	//to prevent this function to twice run on an element, we add an attribute to each element that has been processed.
328	//then skip elements with that element.
329	document.querySelectorAll('.cmplz-image').forEach(obj => {
330		if ( obj.classList.contains('cmplz-processed') ) {
331			return;
332		}
333		obj.classList.add('cmplz-processed' );
334		let service = obj.getAttribute('data-service');
335		let blocked_image_container = obj.parentElement;
336		blocked_image_container.classList.add('cmplz-blocked-content-container');
337		let curIndex = blocked_image_container.getAttribute('data-placeholder_class_index');
338		//handle browser native lazy load feature
339		if (obj.getAttribute('loading') === 'lazy' ) {
340			obj.removeAttribute('loading');
341			obj.setAttribute('deferlazy', 1);
342		}
343
344		if ( curIndex == null ) {
345			cmplz_placeholder_class_index++;
346			blocked_image_container.classList.add('cmplz-placeholder-' + cmplz_placeholder_class_index);
347			blocked_image_container.classList.add('cmplz-blocked-content-container');
348			blocked_image_container.setAttribute('data-placeholder_class_index', cmplz_placeholder_class_index);
349			//insert placeholder text
350			if ( blocked_image_container.querySelector(".cmplz-blocked-content-notice" ) == null) {
351				let placeholderText = complianz.placeholdertext;
352				if (typeof placeholderText !== 'undefined') {
353					let btn = cmplz_create_element('button', '');
354					btn.innerText = placeholderText;
355					btn.classList.add('cmplz-blocked-content-notice');
356					btn.classList.add('cmplz-accept-marketing');
357					btn.setAttribute('data-service', service );
358					btn.setAttribute('aria-label', service );
359					blocked_image_container.appendChild( btn );
360				}
361			}
362		}
363
364
365	});
366
367	document.querySelectorAll('.cmplz-placeholder-element').forEach(obj => {
368		if ( obj.classList.contains('cmplz-processed') ) {
369			return;
370		}
371		obj.classList.add('cmplz-processed' );
372		let service = obj.getAttribute('data-service');
373
374		//we set this element as container with placeholder image
375		let blocked_content_container;
376		if ( obj.classList.contains('cmplz-iframe')) {
377			//handle browser native lazy load feature
378			if ( obj.getAttribute('loading') === 'lazy' ) {
379				obj.removeAttribute('loading');
380				obj.setAttribute('deferlazy', 1);
381			}
382			blocked_content_container = obj.parentElement;
383		} else {
384			blocked_content_container = obj;
385		}
386		let curIndex = blocked_content_container.getAttribute('data-placeholder_class_index');
387		//if the blocked content container class is already added, don't add it again
388		if ( curIndex == null ) {
389			cmplz_placeholder_class_index++;
390			blocked_content_container.classList.add('cmplz-placeholder-' + cmplz_placeholder_class_index);
391			blocked_content_container.classList.add('cmplz-blocked-content-container');
392			blocked_content_container.setAttribute('data-placeholder_class_index', cmplz_placeholder_class_index);
393			//insert placeholder text
394			if ( blocked_content_container.querySelector( ".cmplz-blocked-content-notice" ) == null ) {
395				let placeholderText = complianz.placeholdertext;
396				if (typeof placeholderText !== 'undefined') {
397					let btn = cmplz_create_element('button', '');
398					btn.innerText = placeholderText;
399					btn.classList.add('cmplz-blocked-content-notice');
400					btn.classList.add('cmplz-accept-marketing');
401					btn.setAttribute('data-service', service );
402					btn.setAttribute('aria-label', service );
403					blocked_content_container.appendChild( btn );
404				}
405			}
406
407			//handle image size for video
408			let src = obj.getAttribute('data-placeholder-image');
409			if (typeof src !== 'undefined' && src.length ) {
410				src = src.replace('url(', '').replace(')', '').replace(/\"/gi, "");
411				cmplz_append_css('.cmplz-placeholder-' + cmplz_placeholder_class_index + ' {background-image: url(' + src + ') !important;}');
412				cmplz_set_blocked_content_container_aspect_ratio(obj, src, cmplz_placeholder_class_index);
413			}
414		}
415	});
416
417	/**
418	 * In some cases, like ajax loaded content, the placeholders are initialized again. In that case, the scripts may need to be fired again as well.
419	 * We're assuming that statistics scripts won't be loaded with ajax, so we only load marketing level scripts
420	 *
421	 */
422	if ( cmplz_has_consent('marketing') ) {
423		cmplz_enable_category('marketing');
424	}
425
426}
427
428/**
429 * Set the height of an image relative to the width, depending on the image widht/height aspect ratio.
430 *
431 *
432 * */
433
434function cmplz_set_blocked_content_container_aspect_ratio(container, src, placeholder_class_index) {
435	if ( container == null ) return;
436
437	//we set the first parent div as container with placeholder image
438	let blocked_content_container = container.parentElement;
439
440	//handle image size for video
441	let img = new Image();
442	img.addEventListener("load", function () {
443		let imgWidth = this.naturalWidth;
444		let imgHeight = this.naturalHeight;
445
446		//prevent division by zero.
447		if (imgWidth === 0) imgWidth = 1;
448		let w = blocked_content_container.clientWidth;
449		let h = imgHeight * (w / imgWidth);
450
451		let heightCSS = '';
452		if (src.indexOf('placeholder.jpg') === -1) {
453			heightCSS = 'height:' + h + 'px;';
454		}
455		cmplz_append_css('.cmplz-placeholder-' + placeholder_class_index + ' {' + heightCSS + '}');
456	});
457	img.src = src;
458}
459/**
460 * Keep window aspect ratio in sync when window resizes
461 * To lower the number of times this code is executed, it is done with a timeout.
462 *
463 * */
464
465var cmplzResizeTimer;
466window.addEventListener('resize', function(event) {
467	clearTimeout(cmplzResizeTimer);
468	cmplzResizeTimer = setTimeout( cmplz_set_blocked_content_container, 500);
469}, true);
470
471/**
472 * 	we run this function also on an interval, because with ajax loaded content, the placeholders would otherwise not be handled.
473 */
474if ( complianz.block_ajax_content == 1 ) {
475	setInterval(function () {
476		cmplz_set_blocked_content_container();
477	}, 2000);
478}
479
480/**
481 * Enable scripts that were blocked
482 *
483 * */
484
485function cmplz_enable_category(category, service) {
486	if ( complianz.tm_categories == 1 && category !== '') {
487		cmplz_run_tm_event(category);
488	}
489
490	service = typeof service !== 'undefined' ? service : 'do_not_match';
491	if ( category === '' ) category = 'do_not_match';
492
493	if ( category === 'functional' ) {
494		return;
495	}
496	//enable cookies for integrations
497	if ( category === 'marketing' ) {
498		cmplz_set_integrations_cookies();
499	}
500
501	//remove accept cookie notice overlay
502	document.querySelectorAll('.cmplz-blocked-content-notice.cmplz-accept-'+category+', .cmplz-blocked-content-notice[data-service='+service+']').forEach(obj => {
503		obj.parentNode.removeChild(obj);
504	});
505
506	document.querySelectorAll('[data-category='+category+'], [data-service='+service+']').forEach(obj => {
507		//if a category is activated, but this specific service is denied, skip.
508		let elementService = obj.getAttribute('data-service');
509		if ( cmplz_is_service_denied(elementService)) {
510			return;
511		}
512
513		//if native class is included, it isn't blocked, so will have run already
514		if ( obj.getAttribute('data-category') === 'functional' ) {
515			return;
516		}
517
518		if ( obj.classList.contains('cmplz-activated') ) {
519			return;
520		}
521
522		let tagName = obj.tagName;
523		if (tagName==='STYLE'){
524			obj.classList.add('cmplz-activated' );
525			let src = obj.getAttribute('data-href');
526			cmplz_load_css( src, category);
527		} else if (tagName ==='IMG'){
528			obj.classList.add('cmplz-activated' );
529			let src = obj.getAttribute('data-src-cmplz');
530			obj.setAttribute('src', src);
531			//handle browser native lazy load feature
532			if ( obj.getAttribute('data-deferlazy') ) {
533				obj.setAttribute('loading', 'lazy');
534			}
535			let blocked_content_container = obj.closest('.cmplz-blocked-content-container');
536			let cssIndex = blocked_content_container.getAttribute('data-placeholder_class_index');
537			blocked_content_container.classList.remove('cmplz-blocked-content-container');
538			blocked_content_container.classList.remove('cmplz-placeholder-' + cssIndex);
539		} else if (tagName==='IFRAME'){
540			obj.classList.add('cmplz-activated' );
541			let src = obj.getAttribute('data-src-cmplz');
542			//check if there's an autoplay value we need to pass on
543			let autoplay = cmplz_get_url_parameter(obj.getAttribute('src'), 'autoplay');
544			if ( autoplay === '1' ) src = src + '&autoplay=1';
545
546			obj.addEventListener('load', (event) => {
547				//handle browser native lazy load feature
548				if ( obj.getAttribute('data-deferlazy') ) {
549					obj.setAttribute('loading', 'lazy');
550				}
551
552				//we get the closest, not the parent, because a script could have inserted a div in the meantime.
553				let blocked_content_container = obj.closest('.cmplz-blocked-content-container');
554				let cssIndex = blocked_content_container.getAttribute('data-placeholder_class_index');
555				blocked_content_container.classList.remove('cmplz-blocked-content-container');
556				blocked_content_container.classList.remove('cmplz-placeholder-' + cssIndex);
557				obj.classList.remove('cmplz-iframe-styles');
558				obj.classList.remove('cmplz-iframe');
559				obj.classList.remove('video-wrap');
560			});
561			obj.setAttribute('src', src);
562		} else if (obj.classList.contains('cmplz-placeholder-element')) {
563			obj.classList.add('cmplz-activated' );
564			//other services, no iframe, with placeholders
565			//remove the added classes
566			let cssIndex = obj.getAttribute('data-placeholder_class_index');
567			obj.classList.remove('cmplz-blocked-content-container');
568			obj.classList.remove('cmplz-placeholder-' + cssIndex);
569		}
570
571		let details = new Object();
572		details.category = category;
573		details.service = service;
574		let event = new CustomEvent('cmplz_category_enabled', { detail: details });
575		document.dispatchEvent(event);
576	});
577
578	/**
579	 * Let's activate the scripts
580	 */
581
582		//create list of waiting scripts
583	let scriptElements = document.querySelectorAll('script[data-category='+category+'], script[data-service='+service+']');
584	scriptElements.forEach(obj => {
585		let waitfor = obj.getAttribute('data-waitfor');
586		let src = obj.getAttribute('src');
587		if ( waitfor ) {
588			if ( src ) {
589				cmplz_waiting_scripts[waitfor] = src;
590			} else if ( obj.innerText.length > 0 ) {
591				cmplz_waiting_inline_scripts[waitfor] = obj;
592			}
593		}
594	});
595
596	//scripts: set to text/javascript
597	scriptElements.forEach(obj => {
598		if ( obj.classList.contains('cmplz-activated') ) {
599			return;
600		}
601		obj.classList.add('cmplz-activated' );
602		let src = obj.getAttribute('src');
603		if ( src ) {
604			obj.setAttribute('type', 'text/javascript');
605			//check if this src or txt is in a waiting script. If so, skip.
606			if ( cmplz_is_waiting_script(cmplz_waiting_scripts, src) ) {
607				return;
608			}
609
610			if ( obj.getAttribute('data-post_scribe_id') ) {
611				let psID = '#' + obj.getAttribute('data-post_scribe_id');
612				let postScribeObj = document.querySelector(psID);
613				if ( postScribeObj ) {
614					postScribeObj.innerHtml('');
615					postscribe(psID, '<script src=' + src + '></script>');
616				}
617			} else {
618				cmplz_run_script(src, category, 'src' );
619			}
620
621		} else if (obj.innerText.length > 0 ) {
622			//check if this src or txt is in a waiting script. If so, skip.
623			if (cmplz_is_waiting_script(cmplz_waiting_inline_scripts, obj.innerText )) {
624				return;
625			}
626
627			cmplz_run_script( obj.innerText, category, 'inline' );
628		}
629	});
630
631	//fire an event so custom scripts can hook into this.
632	let details = new Object();
633	details.category = category;
634	details.categories = cmplz_accepted_categories();
635	details.services = cmplz_get_all_service_consents();
636	details.region = complianz.region;
637	let event = new CustomEvent('cmplz_enable_category', { detail: details });
638	document.dispatchEvent(event);
639
640	//if there are no blockable scripts at all, we still want to provide a hook
641	//in most cases, this script fires too early, and won't run yet. In that
642	//case it's run from the script activation callbacks.
643	cmplz_run_after_all_scripts(category);
644}
645
646
647
648/**
649 * check if the passed source has a waiting script that should be executed, and return it if so.
650 * @param waiting_scripts
651 * @param src
652 * @returns {*}
653 */
654
655function cmplz_get_waiting_script(waiting_scripts, src) {
656	for (let waitfor in waiting_scripts) {
657		if ( waiting_scripts.hasOwnProperty(waitfor)) {
658			let waitingScript;//recaptcha/api.js, waitfor="gregaptcha"
659			if (waiting_scripts.hasOwnProperty(waitfor)) {
660				waitingScript = waiting_scripts[waitfor];
661				if (typeof waitingScript !== 'string') {
662					waitingScript = waitingScript.innerText;
663				}
664				if (src.indexOf(waitfor) !== -1) {
665					let output = waiting_scripts[waitfor];
666					delete waiting_scripts[waitfor];
667					return output;
668				}
669			}
670		}
671	}
672
673	return false;
674}
675
676/**
677 * Because we need a key=>value array in javascript, the .length check for an empty array doesn't work.
678 * @param arr
679 * @returns {boolean}
680 */
681function cmplz_array_is_empty(arr) {
682	for (let key in arr) {
683		if (arr.hasOwnProperty(key)) {
684			return false;
685		}
686	}
687
688	return true;
689}
690
691/**
692 * Check if the passed src or script is waiting for another script and should not execute
693 * @param waiting_scripts
694 * @param srcOrScript
695 */
696
697function cmplz_is_waiting_script(waiting_scripts, srcOrScript) {
698	for (let waitfor in waiting_scripts) {
699		if ( waiting_scripts.hasOwnProperty(waitfor) ) {
700			let waitingScript = waiting_scripts[waitfor];
701			if (typeof waitingScript !== 'string') waitingScript = waitingScript.innerText;
702
703			if (srcOrScript.indexOf(waitingScript) !== -1 || waitingScript.indexOf(srcOrScript) !== -1) {
704				return true;
705			}
706		}
707	}
708	return false;
709}
710
711/**
712 * if all scripts have been executed, fire a hook.
713 */
714
715function cmplz_run_after_all_scripts(category) {
716	if (!cmplz_all_scripts_hook_fired && cmplz_array_is_empty(cmplz_waiting_inline_scripts) && cmplz_array_is_empty(cmplz_waiting_scripts) ) {
717		let event = new CustomEvent('cmplz_run_after_all_scripts', { detail: category });
718		document.dispatchEvent(event);
719		cmplz_all_scripts_hook_fired = true;
720	}
721}
722
723/**
724 * Fire an event in Tag Manager
725 *
726 *
727 * */
728
729let cmplz_fired_events = [];
730function cmplz_run_tm_event(category) {
731	if (cmplz_fired_events.indexOf(category) === -1) {
732		cmplz_fired_events.push(category);
733		window.dataLayer = window.dataLayer || [];
734		window.dataLayer.push({
735			'event': complianz.prefix+'event_'+category
736		});
737		let event = new CustomEvent('cmplz_tag_manager_event', { detail: category });
738		document.dispatchEvent(event);
739	}
740}
741
742window.conditionally_show_banner = function() {
743	//merge userdata with complianz data, in case a b testing is used with user specific cookie banner data
744	//objects are merged so user_data will override data in complianz object
745	complianz = cmplz_merge_object( complianz, cmplz_user_data );
746	//check if we need to redirect to another legal document, for a specific region
747	cmplz_maybe_auto_redirect();
748	cmplz_set_blocked_content_container();
749
750	/**
751	 * Integration with WordPress, tell what kind of consent type we're using, then fire an event
752	 */
753
754	window.wp_consent_type = complianz.consenttype;
755	let event = new CustomEvent('wp_consent_type_defined');
756	document.dispatchEvent( event );
757	event = new CustomEvent('cmplz_before_cookiebanner' );
758	document.dispatchEvent(event);
759	if ( complianz.forceEnableStats == 1 ) {
760		cmplz_set_consent('statistics', 'allow');
761	}
762
763	let rev_cats = cmplz_categories.reverse();
764	for (let key in rev_cats) {
765		if ( rev_cats.hasOwnProperty(key) ) {
766			let category = cmplz_categories[key];
767			if (cmplz_has_consent(category)) {
768				cmplz_enable_category(category);
769			}
770		}
771	}
772
773	if ( cmplz_exists_service_consent() ) {
774		//if any service is enabled, allow the general services also, because some services are partially 'general'
775		cmplz_enable_category('', 'general');
776		let services = cmplz_get_services_on_page();
777		for (let key in services) {
778			if ( services.hasOwnProperty(key) ) {
779				let service = services[key];
780				if (service.length == 0) continue;
781				if (cmplz_has_service_consent(service)) {
782					document.querySelectorAll('.cmplz-accept-service[data-service=' + service + ']').forEach(obj => {
783						obj.checked = true;
784					});
785
786					cmplz_enable_category('', service);
787				}
788			}
789		}
790	}
791
792	cmplz_sync_category_checkboxes();
793	cmplz_integrations_init();
794	cmplz_check_cookie_policy_id();
795	cmplz_set_up_auto_dismiss();
796
797	//if we're on the cookie policy page, we dynamically load the applicable revoke checkbox
798	cmplz_load_manage_consent_container();
799
800	event = new CustomEvent('cmplz_cookie_banner_data', { detail: complianz });
801	document.dispatchEvent(event);
802
803	//if no categories were saved before, we do it now
804	if ( cmplz_get_cookie('saved_categories') === '' ) {
805		//for Non optin/optout visitors, and DNT users, we just track the no-warning option
806		if ( complianz.consenttype !== 'optin' && complianz.consenttype !== 'optout' ) {
807			cmplz_track_status( 'no_warning' );
808		} else if ( complianz.do_not_track ) {
809			cmplz_track_status('do_not_track' );
810		}
811	}
812
813	cmplz_set_category_as_body_class();
814	//fire cats event, but do not fire a track, as we do this on exit.
815	cmplz_fire_categories_event();
816	if (!complianz.do_not_track) {
817		if (complianz.consenttype === 'optin') {
818			if (complianz.forceEnableStats) {
819				cmplz_enable_category('statistics');
820			}
821			console.log('opt-in');
822			show_cookie_banner();
823		} else if (complianz.consenttype === 'optout') {
824			console.log('opt-out');
825			show_cookie_banner();
826		} else {
827			console.log('other consent type, no cookie warning');
828			//on other consent types, all scripts are enabled by default.
829			cmplz_accept_all();
830		}
831
832	} else {
833		cmplz_track_status( 'do_not_track' );
834	}
835}
836
837/**
838 * Get list of services active on the page
839 * @returns {*[]}
840 */
841function cmplz_get_services_on_page(){
842	let services=[];
843	document.querySelectorAll('[data-service]').forEach(obj => {
844		let service = obj.getAttribute('data-service');
845		if ( services.indexOf(service)==-1 ) {
846			services.push(service);
847		}
848	});
849	return services;
850}
851
852/**
853 * Run the actual cookie warning
854 *
855 * */
856
857
858window.show_cookie_banner = function () {
859	let disableCookiebanner = complianz.disable_cookiebanner || cmplz_is_speedbot();
860	//do not show banner when manage consent area on cookie policy is visible
861	//when users use only the shortcode, the manage consent container is not active, but the dropdown cookie policy class is.
862	//when the complianz shortcode is used, the dropdown cookie policy class is loaded late because it's loaded with javascript.
863	let tmpDismissCookiebanner = false;
864	if ( document.querySelector('#cmplz-manage-consent-container') || document.querySelector('.cmplz-dropdown-cookiepolicy') ) {
865		tmpDismissCookiebanner = true;
866	}
867
868	var fragment = document.createDocumentFragment();
869	let container = document.getElementById('cmplz-cookiebanner-container');
870	if (container) {
871		fragment.appendChild(container);
872		document.body.prepend(fragment);
873	}
874
875	let link = document.createElement("link");
876	let pageLinks = complianz.page_links[complianz.region];
877	//get correct banner, based on banner_id
878	cmplz_banner = document.querySelector('.cmplz-cookiebanner.banner-'+complianz.user_banner_id+'.'+complianz.consenttype);
879	cmplz_manage_consent_button = document.querySelector('#cmplz-manage-consent .cmplz-manage-consent.manage-consent-'+complianz.user_banner_id);
880	let css_file_url = complianz.css_file.replace('type', complianz.consenttype ).replace('banner_id', complianz.user_banner_id);
881	if ( complianz.css_file.indexOf('cookiebanner/css/defaults/banner') != -1 ) {
882		console.log('Fallback default css file used. Please re-save banner settings, or check file writing permissions in uploads directory');
883	}
884	link.href = css_file_url;
885	link.type = "text/css";
886	link.rel = "stylesheet";
887	link.onload = function () {
888		if ( !disableCookiebanner ) {
889			cmplz_banner.classList.remove('cmplz-hidden');
890			cmplz_manage_consent_button.classList.remove('cmplz-hidden');
891		}
892	}
893	document.getElementsByTagName("head")[0].appendChild(link);
894	if ( cmplz_banner && !disableCookiebanner ) {
895		cmplz_banner.querySelectorAll('.cmplz-links a:not(.cmplz-external), .cmplz-buttons a:not(.cmplz-external)').forEach(obj => {
896			let docElement = obj;
897			docElement.classList.add('cmplz-hidden');
898			for (let pageType in pageLinks) {
899				if (pageLinks.hasOwnProperty(pageType) && docElement.classList.contains(pageType)) {
900					docElement.setAttribute('href', pageLinks[pageType]['url'] + docElement.getAttribute('data-relative_url'));
901					if (docElement.innerText === '{title}') {
902						docElement.innerText = cmplz_html_decode(pageLinks[pageType]['title']);
903					}
904					docElement.classList.remove('cmplz-hidden');
905				}
906			}
907		});
908
909		cmplz_set_banner_status();
910		//we don't use the setBannerStatus function here, as we don't want to save it in a cookie now.
911		if ( tmpDismissCookiebanner ) {
912			cmplz_banner.classList.remove('cmplz-show');
913			cmplz_banner.classList.add('cmplz-dismissed');
914			cmplz_manage_consent_button.classList.remove('cmplz-dismissed');
915			cmplz_manage_consent_button.classList.add('cmplz-show');
916		}
917	}
918
919	let event = new CustomEvent('cmplz_cookie_warning_loaded', {detail: complianz.region});
920	document.dispatchEvent(event);
921}
922/**
923 * Get the status of the banner: dismissed | show
924 * @returns {string}
925 */
926window.cmplz_get_banner_status = function (){
927	return cmplz_get_cookie('banner-status');
928}
929
930/**
931 * Set the banner status so it will be either shown or dismissed, and store it in a cookie.
932 * @param status (optional)
933 */
934
935window.cmplz_set_banner_status = function ( status ){
936	let prevStatus = cmplz_get_cookie('banner-status');
937	status = typeof status !== 'undefined' ? status : prevStatus;
938	if ( status !== prevStatus ) {
939		cmplz_set_cookie( 'banner-status', status );
940	}
941	if (status.length===0){
942		status = 'show';
943	}
944
945	if (status==='show') {
946		prevStatus = 'dismissed';
947	} else {
948		prevStatus = 'show';
949	}
950
951	if ( cmplz_banner && status.length>0 ) {
952		cmplz_banner.classList.remove('cmplz-'+prevStatus);
953		cmplz_banner.classList.add('cmplz-'+status );
954		if ( cmplz_manage_consent_button ) {
955			cmplz_manage_consent_button.classList.add('cmplz-'+prevStatus);
956			cmplz_manage_consent_button.classList.remove('cmplz-'+status);
957		}
958	}
959
960	if ( cmplz_banner_container && complianz.soft_cookiewall ) {
961		cmplz_banner_container.classList.remove('cmplz-'+prevStatus);
962		cmplz_banner_container.classList.add('cmplz-'+status );
963		cmplz_banner_container.classList.add('cmplz-soft-cookiewall');
964	}
965	var event = new CustomEvent('cmplz_banner_status', { detail: status });
966	document.dispatchEvent(event);
967}
968
969/**
970 * Check if current visitor is a bot
971 *
972 * @returns {boolean}
973 */
974function cmplz_is_bot(){
975	var botPattern = "(googlebot\/|Googlebot-Mobile|Googlebot-Image|Google favicon|Mediapartners-Google|bingbot|slurp|java|wget|curl|Commons-HttpClient|Python-urllib|libwww|httpunit|nutch|phpcrawl|msnbot|jyxobot|FAST-WebCrawler|FAST Enterprise Crawler|biglotron|teoma|convera|seekbot|gigablast|exabot|ngbot|ia_archiver|GingerCrawler|webmon |httrack|webcrawler|grub.org|UsineNouvelleCrawler|antibot|netresearchserver|speedy|fluffy|bibnum.bnf|findlink|msrbot|panscient|yacybot|AISearchBot|IOI|ips-agent|tagoobot|MJ12bot|dotbot|woriobot|yanga|buzzbot|mlbot|yandexbot|purebot|Linguee Bot|Voyager|CyberPatrol|voilabot|baiduspider|citeseerxbot|spbot|twengabot|postrank|turnitinbot|scribdbot|page2rss|sitebot|linkdex|Adidxbot|blekkobot|ezooms|dotbot|Mail.RU_Bot|discobot|heritrix|findthatfile|europarchive.org|NerdByNature.Bot|sistrix crawler|ahrefsbot|Aboundex|domaincrawler|wbsearchbot|summify|ccbot|edisterbot|seznambot|ec2linkfinder|gslfbot|aihitbot|intelium_bot|facebookexternalhit|yeti|RetrevoPageAnalyzer|lb-spider|sogou|lssbot|careerbot|wotbox|wocbot|ichiro|DuckDuckBot|lssrocketcrawler|drupact|webcompanycrawler|acoonbot|openindexspider|gnam gnam spider|web-archive-net.com.bot|backlinkcrawler|coccoc|integromedb|content crawler spider|toplistbot|seokicks-robot|it2media-domain-crawler|ip-web-crawler.com|siteexplorer.info|elisabot|proximic|changedetection|blexbot|arabot|WeSEE:Search|niki-bot|CrystalSemanticsBot|rogerbot|360Spider|psbot|InterfaxScanBot|Lipperhey SEO Service|CC Metadata Scaper|g00g1e.net|GrapeshotCrawler|urlappendbot|brainobot|fr-crawler|binlar|SimpleCrawler|Livelapbot|Twitterbot|cXensebot|smtbot|bnf.fr_bot|A6-Indexer|ADmantX|Facebot|Twitterbot|OrangeBot|memorybot|AdvBot|MegaIndex|SemanticScholarBot|ltx71|nerdybot|xovibot|BUbiNG|Qwantify|archive.org_bot|Applebot|TweetmemeBot|crawler4j|findxbot|SemrushBot|yoozBot|lipperhey|y!j-asr|Domain Re-Animator Bot|AddThis)";
976	var reBot = new RegExp(botPattern, 'i');
977	var userAgent = navigator.userAgent;
978	if ( reBot.test(userAgent) ) {
979		return true;
980	} else {
981		return false;
982	}
983}
984/**
985 * Check if current visitor is a speedbot
986 *
987 * @returns {boolean}
988 */
989function cmplz_is_speedbot(){
990	var userAgent = navigator.userAgent;
991	var speedBotPattern = "(GTmetrix|pingdom|pingbot|Lighthouse)";
992	var speedBot = new RegExp(speedBotPattern, 'i');
993
994	if ( speedBot.test(userAgent) ) {
995		return true;
996	} else {
997		return false;
998	}
999}
1000
1001/**
1002 * Check if there is consent for a category or service
1003 * @param category
1004 * @returns {boolean}
1005 */
1006window.cmplz_has_consent = function ( category ){
1007	if ( cmplz_is_bot() ) {
1008		return true;
1009	}
1010
1011	if ( category === 'functional' ) return true;
1012	var has_consent, value;
1013
1014	/**
1015	 * categories
1016	 */
1017	value = cmplz_get_cookie(category);
1018	if (complianz.consenttype === 'optout' && value === '') {
1019		//if it's opt out and no cookie is set we should return true
1020		has_consent = true;
1021	} else {
1022		//all other situations, return only true if value is allow
1023		has_consent = (value === 'allow');
1024	}
1025
1026	return has_consent;
1027}
1028
1029/**
1030 * Check if a service has consent
1031 * @param service
1032 * @returns {boolean|*}
1033 */
1034window.cmplz_is_service_denied = function ( service ) {
1035	//in opt out, there's no consent per service. so it's always true.
1036	if ( complianz.consenttype === 'optout' ) {
1037		return false;
1038	}
1039
1040	//Check if it's in the consented services cookie
1041	var consented_services_json = cmplz_get_cookie('consented_services');
1042	var consented_services;
1043	try {
1044		consented_services = JSON.parse(consented_services_json);
1045	} catch (e) {
1046		consented_services = {};
1047	}
1048
1049	if ( !consented_services.hasOwnProperty( service ) ){
1050		return false;
1051	} else {
1052		return !consented_services[service];
1053	}
1054}
1055
1056/**
1057 * Check if a service has consent
1058 * @param service
1059 * @returns {boolean|*}
1060 */
1061window.cmplz_has_service_consent = function ( service ) {
1062	//in opt out, there's no consent per service. so it's always true.
1063	if ( complianz.consenttype === 'optout' ) {
1064		return true;
1065	}
1066
1067	//Check if it's in the consented services cookie
1068	var consented_services_json = cmplz_get_cookie('consented_services');
1069	var consented_services;
1070	try {
1071		consented_services = JSON.parse(consented_services_json);
1072	} catch (e) {
1073		consented_services = {};
1074	}
1075
1076	if ( !consented_services.hasOwnProperty( service ) ){
1077		return false;
1078	} else {
1079		return consented_services[service];
1080	}
1081}
1082
1083/**
1084 * check if there's at least one service with consent
1085 * @returns {boolean}
1086 */
1087function cmplz_exists_service_consent(){
1088	var consented_services_json = cmplz_get_cookie('consented_services');
1089	var consented_services;
1090	try {
1091		consented_services = JSON.parse(consented_services_json);
1092		for (const key in consented_services) {
1093			if ( consented_services.hasOwnProperty(key) ) {
1094				if (consented_services[key] == true) {
1095					return true;
1096				}
1097			}
1098		}
1099	} catch (e) {
1100		return false;
1101	}
1102	return false;
1103}
1104
1105/**
1106 * Set consent for a service
1107 * @param service
1108 * @param consented
1109 */
1110function cmplz_set_service_consent( service, consented ){
1111	var consented_services_json = cmplz_get_cookie('consented_services');
1112	var consented_services;
1113	try {
1114		consented_services = JSON.parse(consented_services_json);
1115	} catch (e) {
1116		consented_services = {};
1117	}
1118	consented_services[service] = consented;
1119	cmplz_set_cookie('consented_services', JSON.stringify(consented_services) );
1120}
1121
1122/**
1123 * Remove all service consents
1124 */
1125function cmplz_clear_all_service_consents(){
1126	cmplz_set_cookie('consented_services', '');
1127}
1128
1129/**
1130 * Get all consented or denied services
1131 */
1132
1133function cmplz_get_all_service_consents(){
1134	var consented_services_json = cmplz_get_cookie('consented_services');
1135	var consented_services;
1136	try {
1137		consented_services = JSON.parse(consented_services_json);
1138	} catch (e) {
1139		consented_services = {};
1140	}
1141	return consented_services;
1142}
1143/**
1144 * Get cookie path
1145 * @returns {*}
1146 */
1147function cmplz_get_cookie_path(){
1148	return typeof complianz.cookie_path !== 'undefined' && complianz.cookie_path !== '' ? complianz.cookie_path : '/';
1149}
1150
1151/**
1152 * retrieve domain to set the cookies on
1153 * @returns {string}
1154 */
1155function cmplz_get_cookie_domain(){
1156	var domain = '';
1157	if ( complianz.set_cookies_on_root == 1 && complianz.cookie_domain.length>3){
1158		domain = complianz.cookie_domain;
1159	}
1160	if (domain.indexOf('localhost') !== -1 ) {
1161		domain = '';
1162	}
1163	return domain;
1164}
1165
1166/**
1167 * Set consent for a category
1168 * @param category
1169 * @param value
1170 */
1171window.cmplz_set_consent = function (category, value){
1172	cmplz_set_accepted_cookie_policy_id();
1173	var previous_value = cmplz_get_cookie(category);
1174	//do not trigger a change event if nothing has changed.
1175	if ( previous_value === value ) {
1176		return;
1177	}
1178
1179	//keep checkboxes in banner and on cookie policy in sync
1180	var checked = value === 'allow';
1181	document.querySelectorAll('input.cmplz-'+category).forEach(obj => {
1182		obj.checked = checked;
1183	});
1184
1185	cmplz_set_cookie(category, value);
1186	if ( value === 'allow' ) {
1187		cmplz_enable_category(category);
1188	}
1189
1190	cmplz_wp_set_consent(category, value);
1191	if ( category === 'statistics' ) {
1192		cmplz_wp_set_consent('statistics-anonymous', 'allow');
1193	}
1194
1195	var details = new Object();
1196	details.category = category;
1197	details.value = value;
1198	details.region = complianz.region;
1199	details.categories = cmplz_accepted_categories();
1200	var event = new CustomEvent('cmplz_status_change', { detail: details });
1201	document.dispatchEvent(event);
1202
1203	if ( category === 'marketing' && value === 'deny' ) {
1204		cmplz_integrations_revoke();
1205		//give the code some time to finish, so our track status code can send a signal to the backend.
1206		setTimeout(function(){
1207			location.reload()
1208		}, 500);
1209	}
1210}
1211
1212/**
1213 * We use ajax to check the consenttype based on region, otherwise caching could prevent the user specific warning
1214 *
1215 * */
1216
1217var cmplz_user_data = [];
1218//check if it's already stored
1219if (typeof (Storage) !== "undefined" && sessionStorage.cmplz_user_data) {
1220	cmplz_user_data = JSON.parse(sessionStorage.cmplz_user_data);
1221}
1222
1223//if not stored yet, load. As features in the user object can be changed on updates, we also check for the version
1224if ( complianz.geoip == 1 && (cmplz_user_data.length == 0 || (cmplz_user_data.version !== complianz.version) || (cmplz_user_data.banner_version !== complianz.banner_version)) ) {
1225	var request = new XMLHttpRequest();
1226	request.open('GET', complianz.url+'banner?'+complianz.locale, true);
1227	request.setRequestHeader('Content-type', 'application/json');
1228	request.send();
1229	request.onload = function() {
1230		cmplz_user_data = JSON.parse(request.response);
1231		sessionStorage.cmplz_user_data = JSON.stringify(cmplz_user_data);
1232		conditionally_show_banner();
1233	};
1234} else {
1235	conditionally_show_banner();
1236}
1237
1238/**
1239 *  when ab testing, or using records of consent, we want to keep track of the unique user id
1240 */
1241
1242if ( complianz.store_consent == 1 ) {
1243	var cmplz_id_cookie = cmplz_get_cookie('id');
1244	var cmplz_id_session = '';
1245	var cmplz_id = '';
1246	if (typeof (Storage) !== "undefined" && sessionStorage.cmplz_id) {
1247		cmplz_id_session = JSON.parse(sessionStorage.cmplz_id);
1248	}
1249
1250	if ( cmplz_id_cookie.length == 0 && cmplz_id_session.length > 0 ) {
1251		cmplz_id = cmplz_id_session;
1252		cmplz_set_cookie('id', cmplz_id );
1253	}
1254
1255	if ( cmplz_id_cookie.length > 0 && cmplz_id_session.length == 0 ) {
1256		cmplz_id = cmplz_id_cookie;
1257	}
1258
1259	if ( typeof (Storage) !== "undefined" ) {
1260		sessionStorage.cmplz_id = JSON.stringify(cmplz_id);
1261	}
1262}
1263
1264// visibilitychange and pagehide work in more browsers hence we check if they are supported and try to use them
1265document.addEventListener('visibilitychange', function () {
1266	if ( document.visibilityState === 'hidden' ) {
1267		cmplz_track_status_end();
1268	}
1269});
1270window.addEventListener("pagehide", cmplz_track_status_end, false );
1271window.addEventListener("beforeunload", cmplz_track_status_end, false );
1272
1273function cmplz_track_status_end(){
1274	if ( !cmplz_consent_stored_once ) {
1275		cmplz_track_status();
1276	}
1277}
1278
1279/**
1280 * This creates an API which devs can use to trigger actions in complianz.
1281 */
1282document.addEventListener('cmplz_consent_action', function (e) {
1283	cmplz_set_consent( e.detail.category , 'allow' );
1284	cmplz_fire_categories_event();
1285	cmplz_track_status();
1286});
1287
1288/**
1289 * Deny all categories, and reload if needed.
1290 */
1291window.cmplz_deny_all = function(){
1292	for (var key in cmplz_categories) {
1293		if ( cmplz_categories.hasOwnProperty(key) ) {
1294			cmplz_set_consent(cmplz_categories[key], 'deny');
1295		}
1296	}
1297	var consentLevel = cmplz_highest_accepted_category();
1298	var reload = false;
1299
1300	if (consentLevel !== 'functional' || cmplz_exists_service_consent() ) {
1301		reload = true;
1302	}
1303	if ( cmplz_clear_all_complianz_cookies('cmplz_service') ) {
1304		reload = true;
1305	}
1306
1307	//has to be after the check if should be reloaded, otherwise that check won't work.
1308	cmplz_clear_all_service_consents();
1309	cmplz_integrations_revoke();
1310	cmplz_fire_categories_event();
1311	cmplz_track_status();
1312
1313	var event = new CustomEvent('cmplz_revoke', { detail: reload });
1314	document.dispatchEvent(event);
1315
1316	//we need to let the iab extension handle the reload, otherwise the consent revoke might not be ready yet.
1317	if ( !complianz.tcf_active && reload ) {
1318		location.reload();
1319	}
1320}
1321
1322/**
1323 * For both opt-in and opt-out, clicking cmplz-accept should result in accepting all categories
1324 */
1325cmplz_add_event('click', '.cmplz-accept', function(e){
1326	e.preventDefault();
1327	cmplz_accept_all();
1328	cmplz_set_banner_status('dismissed');
1329	cmplz_fire_categories_event();
1330	cmplz_track_status();
1331});
1332
1333/**
1334 *  Accept marketing cookies by clicking any other link cookie acceptance from a custom link
1335 */
1336
1337cmplz_add_event('click', '.cmplz-accept-marketing', function(e){
1338	e.preventDefault();
1339	let obj = e.target;
1340	var service = obj.getAttribute('data-service');
1341	if ( complianz.clean_cookies == 1 && typeof service !== 'undefined' && service ){
1342		cmplz_set_service_consent(service, true);
1343		cmplz_enable_category('', 'general');
1344		cmplz_enable_category('', service);
1345	} else {
1346		cmplz_enable_category('', 'general');
1347		cmplz_set_consent('marketing', 'allow' );
1348	}
1349	cmplz_set_banner_status('dismissed');
1350	cmplz_fire_categories_event();
1351	cmplz_track_status();
1352});
1353
1354
1355
1356/**
1357 * Accept a specific service
1358 */
1359cmplz_add_event('click', '.cmplz-accept-service', function(e){
1360	e.preventDefault();
1361	let obj = e.target;
1362	//that is for the change event, for input checkboxes
1363	let tagName = obj.tagName;
1364	if ( tagName === 'INPUT' ) return;
1365	let service = obj.getAttribute('data-service');
1366	if ( typeof service !== 'undefined' ){
1367		cmplz_set_service_consent(service, true);
1368		cmplz_enable_category('', 'general');
1369		cmplz_enable_category('', service);
1370	}
1371	cmplz_fire_categories_event();
1372	cmplz_track_status();
1373});
1374
1375/**
1376 * Accept a specific service
1377 */
1378cmplz_add_event('change', '.cmplz-accept-service', function(e){
1379	let obj = e.target;
1380	let service = obj.getAttribute('data-service');
1381	if ( typeof service !== 'undefined' ){
1382		if ( obj.checked ){
1383			cmplz_set_service_consent(service, true);
1384			cmplz_enable_category('', service);
1385		} else {
1386			cmplz_set_service_consent(service, false);
1387			//give our track status time to finish
1388			setTimeout(function(){
1389				location.reload()
1390			}, 500);
1391		}
1392	}
1393	cmplz_fire_categories_event();
1394	cmplz_track_status();
1395});
1396
1397
1398
1399/**
1400 * On the banner, clicking a category should fire the category only after the save button is clicked.
1401 *
1402 */
1403cmplz_add_event('click', '.cmplz-save-preferences', function(e){
1404	let obj = e.target;
1405	cmplz_banner = obj.closest('.cmplz-cookiebanner');
1406	for (var key in cmplz_categories) {
1407		if ( cmplz_categories.hasOwnProperty(key) ) {
1408			var category = cmplz_categories[key];
1409			var categoryElement = cmplz_banner.querySelector('input.cmplz-' + category);
1410			if (categoryElement) {
1411				if (categoryElement.checked) {
1412					cmplz_set_consent(category, 'allow');
1413				} else {
1414					cmplz_set_consent(category, 'deny');
1415				}
1416			}
1417		}
1418	}
1419	cmplz_set_banner_status('dismissed');
1420	cmplz_fire_categories_event();
1421	cmplz_track_status();
1422});
1423
1424cmplz_add_event('click', '.cmplz-close', function(e){
1425	cmplz_set_banner_status('dismissed');
1426});
1427
1428cmplz_add_event('click', '.cmplz-view-preferences', function(e){
1429	let obj = e.target;
1430	cmplz_banner = obj.closest('.cmplz-cookiebanner');
1431	if ( cmplz_banner.querySelector('.cmplz-categories').classList.contains('cmplz-fade-in')) {
1432		cmplz_banner.classList.remove('cmplz-categories-visible');
1433		cmplz_banner.querySelector('.cmplz-categories' ).classList.remove('cmplz-fade-in');
1434		cmplz_banner.querySelector('.cmplz-view-preferences' ).style.display = 'block';
1435		cmplz_banner.querySelector('.cmplz-save-preferences' ).style.display = 'none';
1436	} else {
1437		cmplz_banner.classList.add('cmplz-categories-visible');
1438		cmplz_banner.querySelector('.cmplz-categories' ).classList.add('cmplz-fade-in');
1439		cmplz_banner.querySelector('.cmplz-view-preferences' ).style.display = 'none';
1440		cmplz_banner.querySelector('.cmplz-save-preferences' ).style.display = 'block';
1441	}
1442});
1443/**
1444 * On the cookie policy, clicking a category should fire the category immediately
1445 *
1446 */
1447cmplz_add_event('change', '.cmplz-manage-consent-container .cmplz-category', function(e){
1448	for (var key in cmplz_categories) {
1449		if ( cmplz_categories.hasOwnProperty(key) ) {
1450			var category = cmplz_categories[key];
1451			var categoryElement = document.querySelector('.cmplz-manage-consent-container input.cmplz-' + category);
1452			if (categoryElement) {
1453				if (categoryElement.checked) {
1454					cmplz_set_consent(category, 'allow');
1455				} else {
1456					cmplz_set_consent(category, 'deny');
1457				}
1458				cmplz_set_banner_status('dismissed');
1459				cmplz_fire_categories_event();
1460				cmplz_track_status();
1461			}
1462		}
1463	}
1464
1465});
1466
1467cmplz_add_event('click', '.cmplz-deny', function(e){
1468	e.preventDefault();
1469	cmplz_set_banner_status('dismissed');
1470	cmplz_deny_all();
1471
1472});
1473
1474cmplz_add_event('click', 'button.cmplz-manage-settings', function(e){
1475	e.preventDefault();
1476	var catsContainer = document.querySelector('.cmplz-cookiebanner .cmplz-categories');
1477	var saveSettings = document.querySelector('.cmplz-save-settings');
1478	var manageSettings = document.querySelector('button.cmplz-manage-settings');
1479	if ( !cmplz_is_hidden(catsContainer) ){
1480		saveSettings.style.display='none';
1481		manageSettings.style.display = 'block';
1482		catsContainer.style.display='none';
1483	} else {
1484		saveSettings.style.display = 'block';
1485		manageSettings.style.display='none';
1486		catsContainer.style.display = 'block';
1487	}
1488});
1489
1490cmplz_add_event('click', 'button.cmplz-manage-consent', function(e){
1491	e.preventDefault();
1492	cmplz_set_banner_status('show');
1493});
1494
1495/**
1496 * Handle dismiss on scroll and dismiss on timeout
1497 */
1498function cmplz_set_up_auto_dismiss() {
1499	if ( complianz.consenttype === 'optout' ) {
1500		if ( complianz.dismiss_on_scroll==1 ) {
1501			var onWindowScroll = function(evt) {
1502				if (window.pageYOffset > Math.floor(400)) {
1503					cmplz_set_banner_status('dismissed');
1504					cmplz_fire_categories_event();
1505					cmplz_track_status();
1506					window.removeEventListener('scroll', onWindowScroll);
1507					this.onWindowScroll = null;
1508				}
1509			};
1510			window.addEventListener('scroll', onWindowScroll);
1511		}
1512
1513		var delay = parseInt(complianz.dismiss_timeout);
1514		if ( delay > 0 ) {
1515			var cmplzDismissTimeout = window.setTimeout(function () {
1516				cmplz_set_banner_status('dismissed');
1517				cmplz_fire_categories_event();
1518				cmplz_track_status();
1519			}, Math.floor(delay));
1520		}
1521	}
1522}
1523
1524function cmplz_fire_categories_event(){
1525	let details = new Object();
1526	details.category = cmplz_highest_accepted_category();
1527	details.categories = cmplz_accepted_categories();
1528	details.region = complianz.region;
1529	event = new CustomEvent('cmplz_fire_categories', { detail: details });
1530	document.dispatchEvent(event);
1531}
1532/**
1533 * Track the status of current consent
1534 * @param status
1535 */
1536
1537function cmplz_track_status( status ) {
1538	var cats = [];
1539	status = typeof status !== 'undefined' ? status : false;
1540
1541	var event = new CustomEvent('cmplz_track_status', { detail: status });
1542	document.dispatchEvent(event);
1543
1544	if ( !status ) {
1545		cats = cmplz_accepted_categories();
1546	} else {
1547		cats = [status];
1548	}
1549	cmplz_set_category_as_body_class();
1550	var saved_cats, saved_services;
1551	try {saved_cats = JSON.parse(cmplz_get_cookie('saved_categories'));} catch (e) {saved_cats = {};}
1552	try {saved_services = JSON.parse(cmplz_get_cookie('saved_services'));} catch (e) {saved_services = {};}
1553	var consented_services = cmplz_get_all_service_consents();
1554
1555	//compare current cats with saved cats. When there are no changes, do nothing.
1556	if (cmplz_equals(saved_cats, cats) && cmplz_equals(saved_services, consented_services)) {
1557		return;
1558	}
1559
1560	if ( complianz.store_consent != 1 ) {
1561		return;
1562	}
1563
1564	//keep track of the fact that the status was saved at least once
1565	cmplz_set_cookie('saved_categories', JSON.stringify(cats));
1566	cmplz_set_cookie('saved_services', JSON.stringify(consented_services));
1567	cmplz_consent_stored_once = true;
1568	var request = new XMLHttpRequest();
1569	request.open('POST', complianz.url+'track', true);
1570	var data = {
1571		'consented_categories': cats,
1572		'consented_services':consented_services,
1573		'consenttype': window.wp_consent_type,//store the source consenttype, as our complianz.consenttype will not include optinstats.
1574	};
1575
1576	request.setRequestHeader('Content-type', 'application/json');
1577	request.send(JSON.stringify(data));
1578
1579}
1580
1581/**
1582 * Get accepted categories
1583 *
1584 * @returns {string}
1585 */
1586function cmplz_accepted_categories() {
1587	var consentedCategories = cmplz_categories;
1588	var consentedTemp = [];
1589
1590	//because array filter changes keys, we make a temp arr
1591	for (var key in consentedCategories) {
1592		if ( consentedCategories.hasOwnProperty(key) ) {
1593			var category = consentedCategories[key];
1594			if (cmplz_has_consent(category)) {
1595				consentedTemp.push(category);
1596			}
1597		}
1598	}
1599
1600	consentedCategories = consentedCategories.filter(function(value, index, consentedCategories){
1601		return cmplz_in_array(value, consentedTemp);
1602	});
1603	return consentedCategories;
1604}
1605
1606/**
1607 * Enable the checkbox for each category which was enabled
1608 *
1609 * */
1610
1611function cmplz_sync_category_checkboxes() {
1612	for ( var key in cmplz_categories ) {
1613		if ( cmplz_categories.hasOwnProperty(key) ) {
1614			var category = cmplz_categories[key];
1615			if (cmplz_has_consent(category) || category === 'functional') {
1616				document.querySelectorAll('input.cmplz-' + category).forEach(obj => {
1617					obj.checked = true;
1618				});
1619			} else {
1620				document.querySelectorAll('input.cmplz-' + category).forEach(obj => {
1621					obj.checked = false;
1622				});
1623			}
1624		}
1625	}
1626}
1627
1628/**
1629 * Merge two objects
1630 *
1631 * */
1632
1633function cmplz_merge_object(userdata, ajax_data) {
1634	var output = [];
1635	//first, we fill the important data.
1636	for (key in ajax_data) {
1637		if (ajax_data.hasOwnProperty(key)) output[key] = ajax_data[key];
1638	}
1639
1640	//conditionally add static data
1641	for (var key in userdata) {
1642		//only add if not in ajax_data
1643		if (!ajax_data.hasOwnProperty(key) || typeof ajax_data[key] === 'undefined') {
1644			if (userdata.hasOwnProperty(key)) output[key] = userdata[key];
1645		}
1646	}
1647
1648	return output;
1649}
1650
1651/**
1652 * If current cookie policy has changed, reset cookie consent
1653 *
1654 * */
1655
1656function cmplz_check_cookie_policy_id() {
1657	var user_policy_id = cmplz_get_cookie('policy_id');
1658	if (user_policy_id && (complianz.current_policy_id !== user_policy_id) ) {
1659		cmplz_clear_all_complianz_cookies('cmplz');
1660	}
1661}
1662
1663/**
1664 * Clear all our own cookies, to make sure path issues are resolved.
1665 *
1666 *
1667 */
1668function cmplz_clear_all_complianz_cookies(cookie_part){
1669	var foundCookie = false;
1670
1671	if (typeof document === 'undefined') {
1672		return foundCookie;
1673	}
1674	var secure = ";secure";
1675	var date = new Date();
1676	date.setTime(date.getTime() - (24 * 60 * 60 * 1000));
1677	var expires = ";expires=" + date.toGMTString();
1678	if (window.location.protocol !== "https:") secure = '';
1679	(function () {
1680		var cookies = document.cookie.split("; ");
1681		for (var c = 0; c < cookies.length; c++) {
1682			var d = window.location.hostname.split(".");
1683			//if we have more than one result in the array, we can skip the last one, as it will be the .com/.org extension
1684			var skip_last = d.length > 1;
1685			while (d.length > 0) {
1686				var cookieName = cookies[c].split(";")[0].split("=")[0];
1687				var p = location.pathname;
1688				p = p.replace(/^\/|\/$/g, '').split('/');
1689				if ( cookieName.indexOf(cookie_part) !==-1 ) {
1690					foundCookie = true;
1691					var cookieBase = encodeURIComponent(cookieName) + '=;SameSite=Lax' + secure + expires +';domain=.' + d.join('.') + ';path=';
1692					var cookieBaseDomain = encodeURIComponent(cookieName) + '=;SameSite=Lax' + secure + expires +';domain=;path=';
1693					document.cookie = cookieBaseDomain + '/';
1694					document.cookie = cookieBase+ '/';
1695					while (p.length > 0) {
1696						var path = p.join('/');
1697						if ( path.length>0 ) {
1698							document.cookie = cookieBase + '/' + path;
1699							document.cookie = cookieBaseDomain + '/' + path;
1700							document.cookie = cookieBase + '/' + path + '/';
1701							document.cookie = cookieBaseDomain + '/' + path + '/';
1702						}
1703						p.pop();
1704					};
1705				}
1706				d.shift();
1707				//prevents setting cookies on .com/.org
1708				if (skip_last && d.length==1) d.shift();
1709			}
1710		}
1711	})();
1712
1713	//to prevent a double reload, we preserve the cookie policy id.
1714	cmplz_set_accepted_cookie_policy_id();
1715	return foundCookie;
1716}
1717
1718/**
1719 *
1720 * If a policy is accepted, save this in the user policy id
1721 *
1722 * */
1723
1724function cmplz_set_accepted_cookie_policy_id() {
1725	cmplz_set_cookie('policy_id', complianz.current_policy_id);
1726}
1727
1728/**
1729 * For supported integrations, initialize the not consented state
1730 *
1731 * */
1732
1733function cmplz_integrations_init() {
1734	var cookiesToSet = complianz.set_cookies;
1735	//check if we have scripts that need to be set to true on init.
1736	for (var key in cookiesToSet) {
1737		if (cookiesToSet.hasOwnProperty(key) && cookiesToSet[key][1] === '1') {
1738			cmplz_set_cookie(key, cookiesToSet[key][1], false);
1739		}
1740	}
1741}
1742
1743/**
1744 * For supported integrations, revoke consent
1745 *
1746 * */
1747function cmplz_integrations_revoke() {
1748	var cookiesToSet = complianz.set_cookies;
1749	for (var key in cookiesToSet) {
1750		if (cookiesToSet.hasOwnProperty(key)) {
1751			cmplz_set_cookie(key, cookiesToSet[key][1], false);
1752			if ( cookiesToSet[key][1] == false ){
1753				cmplz_clear_all_complianz_cookies(key);
1754			}
1755		}
1756	}
1757}
1758
1759/**
1760 * For supported integrations, set consent
1761 *
1762 * */
1763
1764function cmplz_set_integrations_cookies() {
1765	var cookiesToSet = complianz.set_cookies;
1766	for (var key in cookiesToSet) {
1767		if (cookiesToSet.hasOwnProperty(key)) {
1768			cmplz_set_cookie(key, cookiesToSet[key][0], false);
1769		}
1770	}
1771}
1772
1773
1774function cmplz_get_url_parameter(sPageURL, sParam) {
1775	if (typeof sPageURL === 'undefined') return false;
1776
1777	var queryString = sPageURL.split('?');
1778	if (queryString.length == 1) return false;
1779
1780	var sURLVariables = queryString[1].split('&'),
1781		sParameterName,
1782		i;
1783	for (i = 0; i < sURLVariables.length; i++) {
1784		if ( sURLVariables.hasOwnProperty(i) ) {
1785			sParameterName = sURLVariables[i].split('=');
1786			if (sParameterName[0] === sParam) {
1787				return sParameterName[1] === undefined ? true : decodeURIComponent(sParameterName[1]);
1788			}
1789		}
1790	}
1791	return false;
1792}
1793
1794/**
1795 * If the parameter cmplz_region_redirect =true is passed, find the user's region, and redirect.
1796 */
1797function cmplz_maybe_auto_redirect() {
1798	var redirect = cmplz_get_url_parameter(window.location.href, 'cmplz_region_redirect');
1799	var region = cmplz_get_url_parameter(window.location.href, 'cmplz-region');
1800	if (redirect && !region) {
1801		window.location.href = window.location.href + '&cmplz-region=' + complianz.region;
1802	}
1803}
1804
1805/**
1806 * wrapper to set consent for wp consent API. If consent API is not active, do nothing
1807 * @param type
1808 * @param value
1809 */
1810function cmplz_wp_set_consent(type, value) {
1811	//wp consent api integration
1812	if (typeof wp_set_consent == 'function') {
1813		wp_set_consent(type, value);
1814	}
1815}
1816
1817/**
1818 * Load revoke options
1819 */
1820
1821function cmplz_load_manage_consent_container() {
1822	let manage_consent_container = document.querySelector('.cmplz-manage-consent-container');
1823	if ( manage_consent_container ) {
1824		var request = new XMLHttpRequest();
1825		request.open('GET', complianz.url+'manage_consent_html?'+complianz.locale, true);
1826		request.setRequestHeader('Content-type', 'application/json');
1827		request.send();
1828		request.onload = function() {
1829			let html = JSON.parse(request.response);
1830			manage_consent_container.insertAdjacentHTML( 'beforeend', html );
1831			cmplz_sync_category_checkboxes();
1832			let nojavascript = document.querySelector('#cmplz-manage-consent-container-nojavascript')
1833			nojavascript.style.display = 'none';
1834			manage_consent_container.style.display = 'block';
1835			event = new CustomEvent('cmplz_manage_consent_container_loaded');
1836			document.dispatchEvent(event);
1837		};
1838	}
1839}
1840
1841/**
1842 * Make slider radio's tabable
1843 */
1844
1845cmplz_add_event('keypress', '.cmplz-banner-slider label', function(e){
1846	var keycode = (e.keyCode ? e.keyCode : e.which);
1847	if (keycode == '32') {
1848		document.activeElement.click();
1849	}
1850});
1851
1852/**
1853 * Compare two arrays
1854 * @param array
1855 * @returns {boolean}
1856 */
1857function cmplz_equals (array_1, array_2) {
1858	if ( !Array.isArray(array_1) ) {
1859		array_1 = Object.keys(array_1);
1860		array_2 = Object.keys(array_2);
1861	}
1862	// if the other array is a falsy value, return
1863	if (!array_1 || !array_2)
1864		return false;
1865
1866	// compare lengths - can save a lot of time
1867	if (array_1.length != array_2.length)
1868		return false;
1869
1870	for (var i = 0, l=array_1.length; i < l; i++) {
1871		// Check if we have nested arrays
1872		if (array_1[i] instanceof Array && array_2[i] instanceof Array) {
1873			// recurse into the nested arrays
1874			if (!cmplz_equals(array_1[i], array_2[i]))
1875				return false;
1876		}
1877		else if (array_1[i] != array_2[i]) {
1878			// Warning - two different object instances will never be equal: {x:20} != {x:20}
1879			return false;
1880		}
1881	}
1882	return true;
1883}
1884
1885
1886
1887/**
1888 * Hooked into jquery
1889 */
1890if ('undefined' != typeof window.jQuery) {
1891	// jQuery present
1892	jQuery(document).ready(function ($) {
1893		/**
1894		 * Activate fitvids on the parent element if active
1895		 *  a.o. Beaverbuilder
1896		 */
1897		$(document).on("cmplz_category_enabled", cmplz_enable_fitvids);
1898		function cmplz_enable_fitvids(data) {
1899			document.querySelectorAll('.cmplz-video').forEach(obj => {
1900				//turn obj into jquery object
1901				let $obj = $(obj);
1902				if (typeof $obj.parent().fitVids == 'function') {
1903					$obj.parent().fitVids();
1904				}
1905			});
1906		}
1907	});
1908}
1909

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.