1/* 2 * ISC License 3 * 4 * Copyright (c) 2024 idnovate.com 5 * idnovate is a Registered Trademark & Property of idnovate.com, innovación y desarrollo SCP 6 * 7 * Permission to use, copy, modify, and/or distribute this software for any 8 * purpose with or without fee is hereby granted, provided that the above 9 * copyright notice and this permission notice appear in all copies. 10 * 11 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH 12 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 13 * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, 14 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 15 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 16 * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 17 * PERFORMANCE OF THIS SOFTWARE. 18 * 19 * @author idnovate 20 * @copyright 2024 idnovate 21 * @license https://www.isc.org/licenses/ https://opensource.org/licenses/ISC ISC License 22 */ 23var cookiesPlusBlockedScripts = cookiesPlusBlockedScripts || []; 24 25var cookieGdpr = { 26 init: function () { 27 if (document.cookie.indexOf('cookiesplus=') === -1) { 28 // cookiesplus cookie doesn't exist, initialize it 29 // cookiesplusVars = []; 30 // cookiesplusVars['C_P_DISPLAY_MODAL'] = false; 31 32 if (typeof C_P_EXPIRY === 'undefined') { 33 console.log('%cC_P_EXPIRY is not defined', 'background: red; color: white'); 34 return; 35 } 36 37 var expireTime = new Date(); 38 expireTime.setDate(expireTime.getDate() + C_P_EXPIRY); 39 var expires = "expires=" + expireTime.toUTCString(); 40 41 var cookieString = "cookiesplus={}; " + expires + "; path=/; SameSite=" + PS_COOKIE_SAMESITE + ";"; 42 43 if (PS_COOKIE_SECURE === 1) { 44 cookieString += " Secure;"; 45 } 46 47 document.cookie = cookieString; 48 } 49 50 // mode DIVs before </body> 51 $('.cookiesplus-move').appendTo(document.body); 52 53 let cookiesplusVars = cookieGdpr.tryParseJSONObject(decodeURIComponent(cookieGdpr.getCookiesPlusCookieValue('cookiesplus'))); 54 55 // Initialize values 56 cookiesplusFinalities = Object.keys(cookiesplusVars).filter(v => v.startsWith('cookiesplus-finality')); 57 cookiesplusFinalities.forEach(function (key) { 58 if (cookiesplusVars[key] === 'on') { 59 $("label[for='"+key+'-'+cookiesplusVars[key]+"']").click() 60 } 61 }) 62 63 cookieGdpr.removeCookies(); 64 65 cookieGdpr.executeScripts(); 66 67 // Don't display modal in Cookies CMS 68 if ($('body#cms').length) { 69 id = $('body#cms').attr('class').match(/cms-[\w-]*\b/); 70 if (id) { 71 id = id[0].replace(/[^0-9]/gi, ''); 72 if (typeof cookiesplusVars.C_P_CMS_PAGE !== 'undefined' 73 && (typeof cookiesplusVars.C_P_CMS_PAGE === id)) { 74 return; 75 } 76 } 77 } 78 79 if (typeof cookiesplusVars.C_P_DISPLAY_MODAL === 'undefined' 80 || (typeof cookiesplusVars.C_P_DISPLAY_MODAL !== 'undefined' 81 && cookiesplusVars.C_P_DISPLAY_MODAL == true)) { 82 cookieGdpr.displayModal(); 83 } 84 85 }, 86 displayModal: function () { 87 if (typeof $.uniform !== "undefined" && typeof $.uniform.update !== "undefined") { 88 $.uniform.update(".cookiesplus-finality-checkbox"); 89 $.uniform.restore(".cookiesplus-finality-checkbox"); 90 } 91 92 if (typeof C_P_FINALITIES_COUNT === 'undefined' 93 || C_P_FINALITIES_COUNT <= 1) { 94 return; 95 } 96 97 if (typeof C_P_NOT_AVAILABLE_OUTSIDE_EU !== 'undefined' 98 && C_P_NOT_AVAILABLE_OUTSIDE_EU === 0) { 99 return; 100 } else { 101 this.displayOverlay(); 102 103 $('.cookiesplus-actions .first-layer').show(); 104 105 $('.cookiesplus-finalities').hide(); 106 $('.cookiesplus-actions .second-layer').hide(); 107 108 $('#cookiesplus-modal .cookiesplus-close-and-save').show(); 109 $('#cookiesplus-modal .cookiesplus-close').hide(); 110 111 $('#cookiesplus-modal').fadeIn('fast'); 112 } 113 114 // this.checkEvenDimensions('#cookiesplus-modal'); 115 /*$(window).resize(function () { 116 cookieGdpr.checkEvenDimensions('#cookiesplus-modal'); 117 });*/ 118 }, 119 displayModalAdvanced: function (fromFirstLayer) { 120 if (typeof $.uniform !== "undefined" && typeof $.uniform.update !== "undefined") { 121 $.uniform.update(".cookiesplus-finality-checkbox"); 122 $.uniform.restore(".cookiesplus-finality-checkbox"); 123 } 124 125 /*if (C_P_FINALITIES_COUNT === 0) { 126 return; 127 }*/ 128 this.displayOverlay(); 129 130 if (typeof C_P_NOT_AVAILABLE_OUTSIDE_EU !== 'undefined' 131 && C_P_NOT_AVAILABLE_OUTSIDE_EU === 0) { 132 $('#cookiesplus-modal-not-available').fadeIn('fast'); 133 $('#cookiesplus-overlay').click(function() { 134 cookieGdpr.close(); 135 }) 136 } else { 137 $('#cookiesplus-modal').fadeIn('fast'); 138 139 $('.cookiesplus-actions .first-layer').hide(); 140 141 $('.cookiesplus-finalities').show(); 142 $('.cookiesplus-actions .second-layer').show(); 143 144 if (!fromFirstLayer) { 145 $('#cookiesplus-modal .cookiesplus-close-and-save').hide(); 146 $('#cookiesplus-modal .cookiesplus-close').show(); 147 } 148 } 149 150 // this.checkEvenDimensions('#cookiesplus-modal'); 151 }, 152 save: function () { 153 return cookieGdpr.sendForm(); 154 }, 155 acceptAllCookies: function () { 156 $('input:radio:not(:disabled)[name^=cookiesplus-finality-][value=on]').prop('checked', true); 157 158 return cookieGdpr.sendForm(); 159 }, 160 rejectAllCookies: function () { 161 $('input:radio:not(:disabled)[name^=cookiesplus-finality-][value=off]').prop('checked', true); 162 163 return cookieGdpr.sendForm(); 164 }, 165 displayOverlay: function () { 166 if (typeof C_P_OVERLAY !== 'undefined' 167 && C_P_OVERLAY === '1') { 168 $('#cookiesplus-overlay').fadeIn('fast'); 169 $('#cookiesplus-overlay').css('background-color', 'rgba(0, 0, 0, ' + C_P_OVERLAY_OPACITY + ')'); 170 } 171 $('#cookiesplus-overlay').click(function(){ 172 cookieGdpr.shake($('#cookiesplus-modal'), 4, 2, 20); 173 }); 174 }, 175 close: function () { 176 $('#cookiesplus-modal, #cookiesplus-modal-not-available, #cookiesplus-overlay').hide(); 177 // $('.cookiesplus-save').prop('disabled', true); 178 }, 179 checkEvenDimensions: function (div) { 180 // $(div).css('height', ''); 181 var styleObject = $(div).prop('style'); 182 styleObject.removeProperty('height'); 183 if ($(div).height() % 2 === 1) { 184 $(div).height(2 * Math.round(($(div).height() - 1) / 2)); 185 } 186 187 styleObject.removeProperty('width'); 188 $(div).css('width', ''); 189 if ($(div).width() % 2 === 1) { 190 $(div).width(2 * Math.round(($(div).width() - 1) / 2)); 191 } 192 }, 193 shake: function (div, shakes, distance, duration) { 194 if (shakes > 0) { 195 div.each(function () { 196 var $el = $(this); 197 var left = $el.css('left'); 198 $el.animate({left: "-=" + distance}, duration, function () { 199 $el.animate({left: "+=" + distance * 2}, duration, function () { 200 $el.animate({left: left}, duration, function () { 201 cookieGdpr.shake($el, shakes - 1, distance, duration); 202 }); 203 }); 204 }); 205 }); 206 } 207 }, 208 sendForm: function() { 209 // Read cookie value
210 let cookiesplusVars = cookieGdpr.tryParseJSONObject(decodeURIComponent(cookieGdpr.getCookiesPlusCookieValue('cookiesplus'))); 211 212 if (cookiesplusVars instanceof Array) { 213 cookiesplusVars = Object.assign({}, cookiesplusVars); 214 } 215 216 // Save new info 217 cookiesplusVars['C_P_DISPLAY_MODAL'] = false; 218 219 $('#cookiesplus-form input:checked').each(function() { 220 cookiesplusVars[$(this).attr('name')] = $(this).val(); 221 }); 222 223 cookiesplusVars['consent_date'] = C_P_DATE; 224 225 var expireTime = new Date(); 226 expireTime.setDate(expireTime.getDate() + C_P_EXPIRY); 227 var expires = "expires=" + expireTime.toUTCString(); 228 229 var cookieString = "cookiesplus=" + encodeURIComponent(JSON.stringify(cookiesplusVars)) + "; " + expires + "; path=/; SameSite=" + PS_COOKIE_SAMESITE + ";"; 230 231 if (PS_COOKIE_SECURE === 1) { 232 cookieString += " Secure;"; 233 } 234 235 document.cookie = cookieString; 236 237 cookieGdpr.removeCookies(); 238 239 if (typeof C_P_REFRESH !== 'undefined' 240 && !C_P_REFRESH) { 241 $.ajax({ 242 type: "POST", 243 cache : false, 244 async : true, 245 url : $('#cookiesplus-form').attr('action'), 246 data: 'saveCookiesPlusPreferences=&ajax=1&'+$('#cookiesplus-form').serialize(), 247 dataType: 'json', 248 headers: { 249 "cache-control": "no-cache" 250 }, 251 success: function(data) { 252 if (data.consent_link && data.consent_hash) { 253 $('.cookiesplus-consent-hash a').attr('href', data.consent_link); 254 $('.cookiesplus-consent-hash a').text(data.consent_hash); 255 $('.cookiesplus-consent-hash').show(); 256 257 cookiesplusVars['consent_hash'] = data.consent_hash; 258 259 var cookieString = "cookiesplus=" + encodeURIComponent(JSON.stringify(cookiesplusVars)) + "; " + expires + "; path=/; SameSite=" + PS_COOKIE_SAMESITE + ";"; 260 261 if (PS_COOKIE_SECURE === 1) { 262 cookieString += " Secure;"; 263 } 264 265 document.cookie = cookieString; 266 } 267 268 /*var d = new Date(); 269 d.setTime(d.getTime() + (365 * 1000)); 270 var expires = "expires=" + d.toUTCString();*/ 271 // document.cookie = "cookiesplus=" + data.cookie + "; " + expires + ";path=/"; 272 273 cookieGdpr.executeScripts(); 274 cookieGdpr.fireGTMEvents(); 275 cookieGdpr.fireFBPixel(); 276 }, 277 error: function(XMLHttpRequest, textStatus, errorThrown) { 278 console.log(errorThrown); 279 } 280 }); 281 282 cookieGdpr.close(); 283 284 return false; 285 } else { 286 cookieGdpr.close(); 287 288 return true; 289 } 290 }, 291 removeCookies : function() { 292 $('#cookiesplus-form input:checked').each(function() { 293 if ($(this).val() !== 'on') { 294 // Save preferences 295 let finalityId = $(this).data('finality-id'); 296 if (typeof C_P_COOKIES[finalityId] !== 'undefined') { 297 Object.keys(C_P_COOKIES[finalityId]).forEach(function (key) { 298 if (C_P_COOKIES[finalityId][key].name.includes('#')) { 299 let cookieValue = C_P_COOKIES[finalityId][key].name; 300 let hashIndex = cookieValue.indexOf("#"); 301 let prefix = cookieValue.substr(0, hashIndex); 302 let suffix = cookieValue.substr(hashIndex + 1); 303 console.log('Removing cookies starting with ' + prefix + ' and ending with ' + suffix); 304 document.cookie.split(";").forEach(function(cookie) { 305 let cookieName = cookie.trim().split("=")[0]; 306 if (cookieName.indexOf(prefix) === 0 && cookieName.endsWith(suffix)) { 307 var urlParts = location.hostname.split('.'); 308 for (var i = 2; i < urlParts.length + 1; i++) { 309 console.log('Removing cookie ' + co
309okieName); 310 document.cookie = cookieName + '=;expires=Thu, 01 Jan 1970 00:00:01 GMT;Max-Age=0; path=/;'; 311 document.cookie = cookieName + '=;expires=Thu, 01 Jan 1970 00:00:01 GMT;Max-Age=0; path=/; domain='+urlParts.slice(-i).join('.'); 312 document.cookie = cookieName + '=;expires=Thu, 01 Jan 1970 00:00:01 GMT;Max-Age=0; path=/; domain=.'+urlParts.slice(-i).join('.'); 313 } 314 } 315 }); 316 } else { 317 console.log('Removing cookie ' + C_P_COOKIES[finalityId][key].name); 318 var urlParts = location.hostname.split('.'); 319 for (var i = 2; i < urlParts.length + 1; i++) { 320 document.cookie = C_P_COOKIES[finalityId][key].name + '=;expires=Thu, 01 Jan 1970 00:00:01 GMT;Max-Age=0; path=/;'; 321 document.cookie = C_P_COOKIES[finalityId][key].name + '=;expires=Thu, 01 Jan 1970 00:00:01 GMT;Max-Age=0; path=/; domain='+urlParts.slice(-i).join('.'); 322 document.cookie = C_P_COOKIES[finalityId][key].name + '=;expires=Thu, 01 Jan 1970 00:00:01 GMT;Max-Age=0; path=/; domain=.'+urlParts.slice(-i).join('.'); 323 } 324 } 325 }) 326 } 327 } 328 }); 329 }, 330 executeScripts : function() { 331 // For each checked finality, execute associated script 332 $('#cookiesplus-form input:checked').each(function() { 333 if ($(this).val() === 'on') { 334 // Execute finality script 335 if (typeof C_P_SCRIPT !== 'undefined' && C_P_SCRIPT[$(this).data('finality-id')]) { 336 // var F = new Function(C_P_SCRIPT[$(this).data('finality-id')]); 337 // F(); 338 339 $('body').append('<div style="display: none;" id="cookiesplus-scripts-' + $(this).data('finality-id') + '"></div>'); 340 cookieGdpr.setInnerHTML(document.querySelector('#cookiesplus-scripts-' + $(this).data('finality-id')), C_P_SCRIPT[$(this).data('finality-id')]); 341 342 // Remove script to avoid execute it more than once 343 C_P_SCRIPT[$(this).data('finality-id')] = []; 344 } 345 } else if ($(this).val() === 'off') { 346 // Execute finality script 347 if (typeof C_P_SCRIPT_NOT !== 'undefined' && C_P_SCRIPT_NOT[$(this).data('finality-id')]) { 348 // var F = new Function(C_P_SCRIPT_NOT[$(this).data('finality-id')]); 349 // F(); 350 351 $('body').append('<div style="display: none;" id="cookiesplus-scripts-' + $(this).data('finality-id') + '"></div>'); 352 cookieGdpr.setInnerHTML(document.querySelector('#cookiesplus-scripts-' + $(this).data('finality-id')), C_P_SCRIPT_NOT[$(this).data('finality-id')]); 353 354 // Remove script to avoid execute it more than once 355 C_P_SCRIPT_NOT[$(this).data('finality-id')] = []; 356 } 357 } 358 }); 359 360 // Append blocked script, js and css 361 for (var i = 0; i < cookiesPlusBlockedScripts.length; i++) { 362 let cookiesPlusBlockedScript = cookiesPlusBlockedScripts[i]; 363 let finalities = cookiesPlusBlockedScript['finalities'].split(','); 364 let allFinalitiesAccepted = true; 365 for (var j = 0; j < finalities.length; j++) { 366 if (!$('#cookiesplus-form input#cookiesplus-finality-' + finalities[j] + '-on:checked').val()) { 367 allFinalitiesAccepted = false; 368 break; 369 } 370 } 371 372 if (allFinalitiesAccepted) { 373 // Append JS and scripts 374 if (!$.isEmptyObject(cookiesPlusBlockedScript['js'])) { 375 Object.keys(cookiesPlusBlockedScript['js']).forEach(function(key) { 376 var s = document.createElement( 'script'); 377 s.setAttribute( 'src', cookiesPlusBlockedScript['js'][key] ); 378 s.setAttribute('async', ''); 379 document.body.appendChild(s); 380 (function(cookiesPlusBlockedScriptKey) { 381 s.onload = function() {
382 if (cookiesPlusBlockedScript['script']) { 383 $(cookiesPlusBlockedScript['location']).replaceWith(cookiesPlusBlockedScript['script']); 384 cookiesPlusBlockedScripts[cookiesPlusBlockedScriptKey]['script'] = []; 385 } 386 }; 387 })(i); 388 }) 389 cookiesPlusBlockedScripts[i]['js'] = []; 390 } else { 391 if (cookiesPlusBlockedScript['script']) { 392 $(cookiesPlusBlockedScript['location']).replaceWith(cookiesPlusBlockedScript['script']); 393 cookiesPlusBlockedScripts[i]['script'] = []; 394 } 395 } 396 397 // Append CSS 398 Object.keys(cookiesPlusBlockedScript['css']).forEach(function(key) { 399 var s = document.createElement('link'); 400 s.setAttribute('rel', 'stylesheet'); 401 s.setAttribute('href', cookiesPlusBlockedScript['css'][key] ); 402 document.head.appendChild(s); 403 }) 404 cookiesPlusBlockedScripts[i]['css'] = []; 405 } 406 } 407 408 return true; 409 }, 410 fireGTMEvents : function() { 411 // For each checked finality, execute associated script 412 let consentUpdateObject = {}; // Create an empty object to accumulate keys and values 413 $('#cookiesplus-form input:checked').each(function () { 414 if (typeof C_P_GTM !== 'undefined' && !$.isEmptyObject(C_P_GTM) && C_P_GTM[$(this).data('finality-id')]) { 415 if (C_P_GTM[$(this).data('finality-id')]['gtmFinality']) { 416 417 Object.keys(C_P_GTM[$(this).data('finality-id')]['gtmFinality']).forEac
417h(key => { 418 if ($(this).val() === 'on') { 419 // Grant consent 420 console.log('Granting consent ' + key); 421 consentUpdateObject[key] = 'granted'; 422 } else { 423 // Deny consent 424 console.log('Denying consent ' + key); 425 consentUpdateObject[key] = 'denied'; 426 } 427 }); 428 } 429 } 430 }); 431 432 // Send all the accumulated keys and values to gtag 433 console.log('Consent update object:', consentUpdateObject); 434 gtag('consent', 'update', consentUpdateObject); 435 436 window.dataLayer = window.dataLayer || []; 437 $('#cookiesplus-form input:checked').each(function() { 438 if ($(this).val() === 'on') { 439 // Fire GTM events 440 if (typeof C_P_GTM !== 'undefined' && !$.isEmptyObject(C_P_GTM) && C_P_GTM[$(this).data('finality-id')]) { 441 if (C_P_GTM[$(this).data('finality-id')]['firingEvent']) { 442 console.log('Firing event '+[C_P_GTM[$(this).data('finality-id')]['firingEvent']]); 443 dataLayer.push({'event': [C_P_GTM[$(this).data('finality-id')]['firingEvent']]}); 444 } 445 } 446 } 447 }); 448 dataLayer.push({'event': 'gtm.init_consent'}); 449 450 return true; 451 }, 452 fireFBPixel : function() { 453 if (typeof C_P_FB === 'undefined' || $.isEmptyObject(C_P_FB) ) { 454 return false; 455 } 456 457 let fbAllConsents = false; 458 459 // For each finality, execute associated script 460 $('#cookiesplus-form input:checked').each(function() { 461 // Fire FB Pixel 462 fbAllConsents = true; 463 if ($(this).val() !== 'on' && C_P_FB[$(this).data('finality-id')]) { 464 fbAllConsents = false; 465 return false; 466 } 467 }); 468 469 if (fbAllConsents) { 470 console.log('Firing FB Pixel'); 471 fbq('consent', 'grant'); 472 } 473 474 return true; 475 }, 476 setInnerHTML : function(elm, html) { 477 elm.innerHTML = html;
478 Array.from(elm.querySelectorAll("script")).forEach( function(oldScript) { 479 const newScript = document.createElement("script"); 480 Array.from(oldScript.attributes) 481 .forEach( function(attr) { 482 newScript.setAttribute(attr.name, attr.value) 483 }); 484 newScript.appendChild(document.createTextNode(oldScript.innerHTML)); 485 oldScript.parentNode.replaceChild(newScript, oldScript); 486 }); 487 }, 488 tryParseJSONObject: function(jsonString) { 489 try { 490 var o = JSON.parse(jsonString); 491 492 // Handle non-exception-throwing cases: 493 // Neither JSON.parse(false) or JSON.parse(1234) throw errors, hence the type-checking, 494 // but... JSON.parse(null) returns null, and typeof null === "object", 495 // so we must check for that, too. Thankfully, null is falsey, so this suffices: 496 if (o && typeof o === "object") { 497 return o; 498 } 499 } 500 catch (e) { } 501 502 return {}; 503 }, 504 getCookiesPlusCookieValue: function(name) { 505 // return document.cookie.match('(^|;)\\s*' + name + '\\s*=\\s*([^;]+)')?.pop() || ''; 506 var match = document.cookie.match(RegExp('(?:^|;\\s*)' + name + '=([^;]*)')); 507 return match ? match[1] : null; 508 } 509} 510 511$(document).ready(function () { 512 if ($('.ets_speed_dynamic_hook').length) { 513 $(document).on("hooksLoaded", function() { 514 cookieGdpr.init(); 515 }); 516 } else { 517 cookieGdpr.init(); 518 } 519 520 $('.cookiesplus-displaymodal').on('click', function() { 521 cookieGdpr.displayModal(); 522 }) 523 524 $('.cookiesplus-displaymodaladvanced').on('click', function() { 525 cookieGdpr.displayModalAdvanced(); 526 }) 527 528 $('a[href*="#cookiesplus-displaymodaladvanced"]').click(function(e) { 529 e.preventDefault(); 530 cookieGdpr.displayModalAdvanced(); 531 }); 532});
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.