1var AEC = (function() 2{ 3 return { 4 add: function(context, dataLayer) 5 { 6 let element = context, qty = 1, variant = [], variant_attribute_option = [], products = []; 7 8 document.querySelectorAll('input[name=qty]:checked, [name=qty]').forEach(element => 9 { 10 qty = element.value; 11 }); 12 13 qty = Math.abs(qty); 14 15 if (isNaN(qty)) 16 { 17 qty = 1; 18 } 19 20 if ('undefined' !== typeof jQuery) 21 { 22 var form = jQuery(context).closest('form'); 23 24 if (form.length) 25 { 26 if (!form.valid()) 27 { 28 return true; 29 } 30 } 31 } 32 33 if (!AEC.gtm()) 34 { 35 if (element.dataset.click) 36 { 37 AEC.Time.track(dataLayer, AEC.Const.TIMING_CATEGORY_ADD_TO_CART, element.dataset.name, element.dataset.category); 38 39 eval(element.dataset.click); 40 } 41 42 return true; 43 } 44 45 if(element.dataset.configurable) 46 { 47 var variants = []; 48 49 document.querySelectorAll('[name^="super_attribute"]').forEach(attribute => 50 { 51 if (attribute.matches('select')) 52 { 53 var name = attribute.getAttribute('name'), id = name.substring(name.indexOf('[') + 1, name.lastIndexOf(']')); 54 55 if (attribute.selectedIndex) 56 { 57 var option = attribute.options[attribute.selectedIndex]; 58 59 if (option) 60 { 61 variants.push( 62 { 63 id: id, 64 option: option.label, 65 text: option.text 66 }); 67 } 68 } 69 } 70 71 if (attribute.matches('input') && -1 != attribute.type.indexOf('radio')) 72 { 73 if (attribute.parentNode.classList.contains('swatch-option-selected') || attribute.checked) 74 { 75 Object.entries(AEC.SUPER).forEach(([key, super_attribute]) => 76 { 77 if (-1 != attribute.name.indexOf("super_attribute[" + super_attribute.id + "]")) 78 { 79 let variant = { 80 id: super_attribute.id, 81 text: super_attribute.label, 82 option: attribute.value 83 }; 84 85 variants.push(variant); 86 87 } 88 }); 89 } 90 } 91 }); 92 93 /** 94 * Colour Swatch support 95 */ 96 if (!variants.length) 97 { 98 Object.entries(AEC.SUPER).forEach(([key, attribute]) => 99 { 100 var swatch = document.querySelectorAll('div[attribute-code="' + attribute.code + '"], div[data-attribute-code="' + attribute.code + '"]'); 101 102 swatch.forEach(element => 103 { 104 let variant = 105 { 106 id: attribute.id, 107 text: '', 108 option: null 109 }; 110 111 var select = element.querySelector('select'); 112 113 if (select) 114 { 115 if (select.selectedIndex) 116 { 117 var option = select.options[select.selectedIndex]; 118 119 if (option) 120 { 121 variant.text = option.text; 122 variant.option = option.value; 123 } 124 } 125 } 126 else 127 { 128 var span = element.querySelector('span.swatch-attribute-selected-option'); 129 130 if (span) 131 { 132 variant.text = span.innerHTML; 133 variant.option = span.parentNode.dataset.optionSelected 134 } 135 } 136 137 variants.push(variant); 138 }); 139 }); 140 } 141 142 if (!variants.length) 143 { 144 AEC.EventDispatcher.trigger('ec.variants', variants); 145 } 146 147 var SUPER_SELECTED = []; 148 149 for (i = 0, l = variants.length; i < l; i++) 150 { 151 for (a = 0, b = AEC.SUPER.length; a < b; a++) 152 { 153 if (AEC.SUPER[a].id == variants[i].id) 154 { 155 var text = variants[i].text; 156 157 if (AEC.useDefaultValues) 158 { 159 AEC.SUPER[a].options.forEach(option => 160 { 161 if (parseInt(option.value_index) == parseInt(variants[i].option)) 162 { 163 if (option.hasOwnProperty('admin_label')) 164 { 165 text = option.admin_label; 166 } 167 else if (option.hasOwnProperty('store_label')) 168 { 169 text = option.store_label; 170 } 171 172 } 173 }); 174 } 175 176 variant.push([AEC.SUPER[a].label,text].join(AEC.Const.VARIANT_DELIMITER_ATT)); 177 178 variant_attribute_option.push( 179 { 180 attribute: variants[i].id, 181 option: variants[i].option 182 }) 183 } 184 } 185 } 186 187 if (!variant.length) 188 { 189 if (element.dataset.click) 190 { 191 AEC.Time.track(dataLayer, AEC.Const.TIMING_CATEGORY_ADD_TO_CART, element.dataset.name, element.dataset.category); 192 193 eval(element.dataset.click); 194 } 195 196 return true; 197 } 198 } 199 200 if (element.dataset.grouped) 201 { 202 for (u = 0, y = window.G.length; u < y; u++) 203 { 204 let field = document.querySelector('[name="super_group[' + window.G[u].id + ']"]'); 205 206 if (field) 207 { 208 (qty => 209 { 210 if (qty) 211 { 212 products.push( 213 { 214 'name': window.G[u].name, 215 'id': window.G[u].sku, 216 'price': window.G[u].price, 217 'category': window.G[u].category, 218 'brand': window.G[u].brand, 219 'quantity': qty 220 }); 221 } 222 })(Math.abs(field.value)); 223 } 224 } 225 } 226 else 227 {
228 products.push( 229 { 230 'name': element.dataset.name, 231 'id': 1 === parseInt(element.dataset.useSimple) ? element.dataset.simpleId : element.dataset.id, 232 'price': element.dataset.price, 233 'category': element.dataset.category, 234 'brand': element.dataset.brand, 235 'variant': variant.join(AEC.Const.VARIANT_DELIMITER), 236 'quantity': qty 237 }); 238 } 239 240 for (i = 0, l = products.length; i < l; i++) 241 { 242 (function(product) 243 { 244 Object.entries(AEC.parseJSON(element.dataset.attributes)).forEach(([key, value]) => 245 { 246 product[key] = value; 247 }); 248 249 })(products[i]); 250 } 251 252 var data = 253 { 254 'event': 'addToCart', 255 'eventLabel': element.dataset.name, 256 'ecommerce': 257 { 258 'currencyCode': AEC.currencyCode, 259 'add': 260 { 261 'actionField': 262 { 263 'list': element.dataset.list 264 }, 265 'products': products 266 }, 267 'options': variant_attribute_option 268 }, 269 'currentStore': element.dataset.store 270 }; 271 272 if (AEC.useDefaultValues) 273 { 274 data['currentStore'] = AEC.storeName; 275 } 276 277 /** 278 * Notify listeners 279 */ 280 this.EventDispatcher.trigger('ec.add.data', data); 281 282 /** 283 * Track event 284 */ 285 AEC.Cookie.add(data).push(dataLayer); 286 287 /** 288 * Save backreference 289 */ 290 if (AEC.localStorage) 291 { 292 (function(products) 293 { 294 for (var i = 0, l = products.length; i < l; i++) 295 { 296 AEC.Storage.reference().set( 297 { 298 id: products[i].id, 299 category: products[i].category 300 }); 301 } 302 })(products); 303 } 304 305 /** 306 * Track time 307 */ 308 AEC.Time.track(dataLayer, AEC.Const.TIMING_CATEGORY_ADD_TO_CART, element.dataset.name, element.dataset.category); 309 310 if (AEC.facebook) 311 { 312 if ("undefined" !== typeof fbq) 313 { 314 (function(product, products, fbq) 315 { 316 var content_ids = [], price = 0; 317 318 for (i = 0, l = products.length; i < l; i++) 319 { 320 content_ids.push(products[i].id); 321 322 price += parseFloat(products[i].price); 323 } 324 325 (function(callback) 326 { 327 if (AEC.Const.COOKIE_DIRECTIVE) 328 { 329 AEC.CookieConsent.queue(callback).process(); 330 } 331 else 332 { 333 callback.apply(window,[]); 334 } 335 }) 336 ( 337 (function(product, content_ids, price) 338 { 339 return function() 340 { 341 if ('undefined' === typeof variants) 342 { 343 variants = []; 344 } 345 346 fbq('track', 'AddToCart', 347 { 348 content_name: product, 349 content_ids: content_ids, 350 content_type: !variants.length ? 'product' : 'product_group', 351 value: price, 352 currency: AEC.currencyCode 353 }, 354 { eventID: AEC.UUID.generate({ event: 'AddToCart'}) }); 355 } 356 })(product, content_ids, price) 357 ); 358 359 })(element.dataset.name, products, fbq); 360 } 361 } 362 363 if (element.dataset.click) 364 { 365 eval(element.dataset.click); 366 } 367 368 return true; 369 }, 370 addSwatch: function(context,dataLayer) 371 { 372 var element = context; 373 374 if (window.jQuery) 375 { 376 jQuery(document).on('ajax:addToCart', function() 377 { 378 var attributes = []; 379 380 Object.entries(AEC.parseJSON(element.dataset.swatch)).forEach(([key, value]) => 381 { 382 attributes.push(value); 383 }); 384 385 var option = document.querySelector('.swatch-option.selected'); 386 387 if (!option) 388 { 389 return true; 390 } 391 392 var variant = [[attributes[0].attribute_label, option.getAttribute('aria-label')].join(AEC.Const.VARIANT_DELIMITER_ATT)].join(AEC.Const.VARIANT_DELIMITER); 393 394 var products = 395 [ 396 { 397 'name': element.dataset.name, 398 'id': element.dataset.id, 399 'price': element.dataset.price, 400 'category': element.dataset.category, 401 'brand': element.dataset.brand, 402 'variant': variant, 403 'quantity': 1 404 } 405 ]; 406 407 var data = 408 { 409 'event': 'addToCart', 410 'eventLabel': element.dataset.name, 411 'ecommerce': 412 { 413 'currencyCode': AEC.currencyCode, 414 'add': 415 { 416 'actionField': 417 { 418 'list': element.dataset.list 419 }, 420 'products': products 421 } 422 }, 423 'currentStore': element.dataset.store 424 }; 425 426 AEC.EventDispatcher.trigger('ec.add.swatch.data', data); 427 428 /** 429 * Track event 430 */ 431 AEC.Cookie.add(data).push(dataLayer); 432 433 /** 434 * Track time 435 */ 436 AEC.Time.track(dataLayer, AEC.Const.TIMING_CATEGORY_ADD_TO_CART, element.dataset.name, element.dataset.category); 437 }); 438 } 439 440 return true; 441 }, 442 click: function(context,dataLayer) 443 { 444 var element = context; 445
446 if (!AEC.gtm()) 447 { 448 AEC.Time.track(dataLayer, AEC.Const.TIMING_CATEGORY_PRODUCT_CLICK, element.dataset.name, element.dataset.category); 449 450 return true; 451 } 452 453 var item = 454 { 455 'name': element.dataset.name, 456 'id': element.dataset.id, 457 'price': element.dataset.price, 458 'category': element.dataset.category, 459 'brand': element.dataset.brand, 460 'quantity': element.dataset.quantity, 461 'position': element.dataset.position 462 }; 463 464 Object.entries(AEC.parseJSON(element.dataset.attributes)).forEach(([key, value]) => 465 { 466 item[key] = value; 467 }); 468 469 var data = 470 { 471 'event': 'productClick', 472 'eventLabel': element.dataset.name, 473 'ecommerce': 474 { 475 'click': 476 { 477 'actionField': 478 { 479 'list': element.dataset.list 480 }, 481 'products': 482 [ 483 item 484 ] 485 } 486 }, 487 'currentStore': element.dataset.store 488 }; 489 490 AEC.EventDispatcher.trigger('ec.click.data', data); 491 492 /** 493 * Push data 494 */ 495 AEC.Cookie.click(data).push(dataLayer); 496 497 /** 498 * Track time 499 */ 500 AEC.Time.track(dataLayer, AEC.Const.TIMING_CATEGORY_PRODUCT_CLICK, element.dataset.name, element.dataset.category); 501 502 if (element.dataset.click) 503 { 504 eval(element.dataset.click); 505 } 506 507 return true; 508 }, 509 remove: function(context, dataLayer) 510 { 511 var element = context; 512
513 if (!AEC.gtm()) 514 { 515 AEC.Time.track(dataLayer, AEC.Const.TIMING_CATEGORY_REMOVE_FROM_CART, element.dataset.name, element.dataset.category); 516 } 517 518 var item = 519 { 520 'name': element.dataset.name, 521 'id': element.dataset.id, 522 'price': element.dataset.price, 523 'category': element.dataset.category, 524 'brand': element.dataset.brand, 525 'quantity': element.dataset.quantity 526 }; 527 528 Object.entries(AEC.parseJSON(element.dataset.attributes)).forEach(([key, value]) => 529 { 530 item[key] = value; 531 }); 532 533 var data = 534 { 535 'event': 'removeFromCart', 536 'eventLabel': element.dataset.name, 537 'ecommerce': 538 { 539 'remove': 540 { 541 'actionField': 542 { 543 'list': element.dataset.list 544 }, 545 'products': 546 [ 547 item 548 ] 549 } 550 } 551 }; 552 553 AEC.EventDispatcher.trigger('ec.remove.data', data); 554 555 if (AEC.Message.confirm) 556 { 557 require(['Magento_Ui/js/modal/confirm'], function(confirmation) 558 { 559 confirmation( 560 { 561 title: AEC.Message.confirmRemoveTitle, 562 content: AEC.Message.confirmRemove, 563 actions: 564 { 565 confirm: function() 566 { 567 /** 568 * Track event 569 */ 570 AEC.Cookie.remove(data).push(dataLayer); 571 572 /** 573 * Track time 574 */ 575 AEC.Time.track(dataLayer, AEC.Const.TIMING_CATEGORY_REMOVE_FROM_CART, element.dataset.name); 576 577 /** 578 * Execute standard data-post 579 */ 580 jQuery(document).dataPost('postData', AEC.parseJSON(element.dataset.postAction)); 581 }, 582 cancel: function() 583 { 584 return false; 585 }, 586 always: function() 587 { 588 return false; 589 } 590 } 591 }); 592 }); 593 } 594 else 595 { 596 /** 597 * Track event 598 */ 599 AEC.Cookie.remove(data).push(dataLayer); 600 601 /** 602 * Track time 603 */ 604 AEC.Time.track(dataLayer, AEC.Const.TIMING_CATEGORY_REMOVE_FROM_CART, element.dataset.name); 605 } 606 607 return false; 608 }, 609 wishlist: function(context, dataLayer) 610 { 611 var element = context; 612 613 if (!AEC.gtm()) 614 { 615 /** 616 * Track time 617 */ 618 AEC.Time.track(dataLayer, AEC.Const.TIMING_CATEGORY_PRODUCT_WISHLIST, element.dataset.name,'Wishlist'); 619 620 return true; 621 } 622 623 let data = 624 { 625 event: element.dataset.event, 626 eventLabel: element.dataset.eventLabel 627 }; 628 629 AEC.EventDispatcher.trigger('ec.add.wishlist', data, { attributes: element.dataset.eventAttributes }); 630 631 /** 632 * Push data 633 */ 634 dataLayer.push(data); 635 636 return true; 637 }, 638 compare: function(context, dataLayer) 639 { 640 var element = context; 641 642 if (!AEC.gtm()) 643 { 644 /** 645 * Track time 646 */ 647 AEC.Time.track(dataLayer, AEC.Const.TIMING_CATEGORY_PRODUCT_COMPARE, element.dataset.name,'Compare'); 648 649 return true; 650 } 651 652 let data = 653 { 654 event: element.dataset.event, 655 eventLabel: element.dataset.eventLabel 656 }; 657 658 AEC.EventDispatcher.trigger('ec.add.compare', data, { attributes: element.dataset.eventAttributes } ); 659 660 /** 661 * Push data 662 */ 663 dataLayer.push(data); 664 665 return true; 666 }, 667 Bind: (function() 668 { 669 return { 670 apply: function(parameters) 671 { 672 /** 673 * Merge persistent storage 674 */ 675 AEC.Persist.merge(); 676 677 /** 678 * Push private data 679 */ 680 AEC.Cookie.pushPrivate(); 681 682 document.addEventListener('DOMContentLoaded',() => 683 { 684 document.body.addEventListener('catalogCategoryAddToCartRedirect', () => 685 { 686 dataLayer.push( 687 { 688 event: AEC.Const.CATALOG_CATEGORY_ADD_TO_CART_REDIRECT_EVENT 689 }); 690 }); 691 }); 692 693 if (parameters) 694 { 695 if (parameters.performance) 696 { 697 if (window.performance) 698 { 699 window.onload = function() 700 { 701 setTimeout(function() 702 { 703 var time = performance.timing.loadEventEnd - performance.timing.responseEnd; 704 705 var timePayload = 706 { 707 'event':'performance', 708 'performance': 709 { 710 'timingCategory': 'Load times', 711 'timingVar': 'load', 712 'timingValue': (time % 60000) 713 } 714 }; 715 716 switch(window.google_tag_params.ecomm_pagetype) 717 { 718 case 'home': 719 720 timePayload.performance.timingLabel = 'Home'; 721 722 AEC.CookieConsent.queue(() => 723 { 724 dataLayer.push(timePayload); 725 }).process(); 726 727 break; 728 case 'product': 729 730 timePayload.performance.timingLabel = 'Product'; 731 732 AEC.CookieConsent.queue(() => 733 { 734 dataLayer.push(timePayload); 735 }).process(); 736 737 break; 738 739 case 'category': 740 741 timePayload.performance.timingLabel = 'Category'; 742 743 AEC.CookieConsent.queue(() => 744 { 745 dataLayer.push(timePayload); 746 }).process(); 747 748 break; 749 } 750 751 }, 0); 752 } 753 } 754 } 755 } 756 757 return this; 758 } 759 } 760 })(), 761 Time: (function() 762 { 763 var T = 764 {
765 event: 'trackTime', 766 timingCategory: '', 767 timingVar: '', 768 timingValue: -1, 769 timingLabel: '' 770 }; 771 772 var time = new Date().getTime(); 773 774 return { 775 track: function(dataLayer, category, variable, label) 776 { 777 T.timingValue = (new Date().getTime()) - time; 778 779 if (category) 780 { 781 T.timingCategory = category; 782 } 783 784 if (variable) 785 { 786 T.timingVar = variable; 787 } 788 789 if (label) 790 { 791 T.timingLabel = label; 792 } 793 794 (function(callback) 795 { 796 if (AEC.Const.COOKIE_DIRECTIVE) 797 { 798 AEC.CookieConsent.queue(callback).process(); 799 } 800 else 801 { 802 callback.apply(window,[]); 803 } 804 }) 805 ( 806 (function(dataLayer, T) 807 { 808 return function() 809 { 810 dataLayer.push(T); 811 } 812 })(dataLayer, T) 813 ); 814 }, 815 trackContinue: function(dataLayer, category, variable, label) 816 { 817 this.track(dataLayer, category, variable, label); 818 819 time = new Date().getTime(); 820 } 821 } 822 })(), 823 Persist:(function() 824 { 825 var DATA_KEY = 'persist'; 826 827 var proto = 'undefined' != typeof Storage ? 828 { 829 push: function(key, entity) 830 { 831 /** 832 * Get data 833 */ 834 var data = this.data(); 835 836 /** 837 * Push data 838 */ 839 data[key] = entity; 840 841 /** 842 * Save to local storage 843 */ 844 localStorage.setItem(DATA_KEY, JSON.stringify(data)); 845 846 return this; 847 }, 848 data: function() 849 { 850 var data = localStorage.getItem(DATA_KEY); 851 852 if (null !== data) 853 { 854 return JSON.parse(data); 855 } 856 857 return {}; 858 }, 859 merge: function() 860 { 861 var data = this.data(); 862 var push = 863 { 864 persist: {} 865 }; 866 867 for (var i in data) 868 { 869 push.persist[i] = data[i]; 870 } 871 872 dataLayer.push(push); 873 874 return this; 875 }, 876 clear: function() 877 { 878 /** 879 * Reset private local storage 880 */ 881 localStorage.setItem(DATA_KEY,JSON.stringify({})); 882 883 return this; 884 } 885 } : { 886 push: function(){}, 887 merge: function(){}, 888 clear: function(){} 889 }; 890 891 /** 892 * Constants 893 */ 894 proto.CONST_KEY_PROMOTION = 'persist_promotion'; 895 896 return proto; 897 898 })(), 899 Checkout: (function() 900 { 901 return { 902 data: {}, 903 tracked: {}, 904 step: function(previous, current, currentCode) 905 { 906 if (this.data && this.data.hasOwnProperty('ecommerce')) 907 { 908 this.data.ecommerce.checkout.actionField.step = ++current; 909 910 /** 911 * Notify listeners 912 */ 913 AEC.EventDispatcher.trigger('ec.checkout.step.data', this.data); 914 915 /** 916 * Track checkout step 917 */ 918 AEC.Cookie.checkout(this.data).push(dataLayer); 919 } 920 921 return this; 922 }, 923 stepOption: function(step, option) 924 { 925 if (!option) 926 { 927 return this; 928 } 929 930 if (!option.toString().length) 931 { 932 return this; 933 } 934 935 var data = 936 { 937 'event': 'checkoutOption', 938 'ecommerce': 939 { 940 'checkout_option': 941 { 942 'actionField': 943 { 944 'step': step, 945 'option': option 946 } 947 } 948 } 949 }; 950 951 /** 952 * Notify listeners 953 */ 954 AEC.EventDispatcher.trigger('ec.checkout.step.option.data', data); 955 956 /** 957 * Track checkout option 958 */ 959 AEC.Cookie.checkoutOption(data).push(dataLayer); 960 961 return this; 962 } 963 } 964 })(), 965 Cookie: (function() 966 { 967 return { 968 data: null, 969 privateData: null, 970 reset: function() 971 { 972 if (AEC.reset) 973 { 974 dataLayer.push({ ecommerce: null }); 975 } 976 977 return dataLayer; 978 }, 979 push: function(dataLayer, consent) 980 { 981 consent = typeof consent !== 'undefined' ? consent : true; 982 983 if (this.data) 984 { 985 if (consent) 986 { 987 if (AEC.Const.COOKIE_DIRECTIVE) 988 { 989 if (AEC.Const.COOKIE_DIRECTIVE_CONSENT_GRANTED) 990 { 991 this.reset().push(this.data); 992 } 993 } 994 else 995 { 996 this.reset().push(this.data); 997 } 998 } 999 else 1000 { 1001 this.reset().push(this.data); 1002 } 1003 1004 /** 1005 * Reset data to prevent further push 1006 */ 1007 this.data = null; 1008 } 1009 1010 return this; 1011 }, 1012 pushPrivate: function() 1013 { 1014 var data = this.getPrivateData(); 1015 1016 if (data) 1017 { 1018 dataLayer.push( 1019 { 1020 privateData: data 1021 }); 1022 } 1023 1024 return this; 1025 }, 1026 augment: function(products) 1027 { 1028 /** 1029 * Parse data & apply local reference 1030 */ 1031 var reference = AEC.Storage.reference().get(); 1032 1033 if (reference) 1034 { 1035 for (var i = 0, l = products.length; i < l; i++) 1036 { 1037 for (var a = 0, b = reference.length; a < b; a++) 1038 { 1039 if (products[i].id.toString().toLowerCase() === reference[a].id.toString().toLowerCase()) 1040 { 1041 products[i].category = reference[a].category; 1042 } 1043 } 1044 } 1045 } 1046 1047 return products; 1048 }, 1049 click: function(data) 1050 { 1051 AEC.EventDispatcher.trigger('ec.cookie.click.data', data); 1052 1053 this.data = data; 1054 1055 return this; 1056 }, 1057 add: function(data) 1058 { 1059 AEC.EventDispatcher.trigger('ec.cookie.add.data', data); 1060 1061 this.data = data; 1062 1063 return this; 1064 }, 1065 remove: function(data) 1066 { 1067 AEC.EventDispatcher.trigger('ec.cookie.remove.item.data', data); 1068 1069 this.data = data; 1070 1071 if (AEC.localStorage) 1072 { 1073 this.data.ecommerce.remove.products = this.augment(this.data.ecommerce.remove.products); 1074 } 1075 1076 return this; 1077 }, 1078 update: function(data) 1079 { 1080 AEC.EventDispatcher.trigger('ec.cookie.update.item.data', data); 1081 1082 this.data = data; 1083 1084 return this; 1085 }, 1086 visitor: function(data) 1087 { 1088 AEC.EventDispatcher.trigger('ec.cookie.visitor.data', data); 1089 1090 this.data = (function(data, privateData) 1091 { 1092 if (privateData) 1093 { 1094 if (privateData.hasOwnProperty('visitor')) 1095 { 1096 data.visitorId = privateData.visitor.visitorId; 1097 data.visitorLoginState = privateData.visitor.visitorLoginState; 1098 } 1099 } 1100 1101 return data; 1102 1103 })(data, AEC.Cookie.getPrivateData()); 1104 1105 return this; 1106 }, 1107 detail: function(data) 1108 { 1109 AEC.EventDispatcher.trigger('ec.cookie.detail.data', data); 1110 1111 this.data = data; 1112 1113 return this; 1114 }, 1115 purchase: function(data) 1116 { 1117 AEC.EventDispatcher.trigger('ec.cookie.purchase.data', data); 1118 1119 this.data = data; 1120 1121 if (AEC.localStorage) 1122 { 1123 this.data.ecommerce.purchase.products = this.augment(this.data.ecommerce.purchase.products); 1124 } 1125 1126 return this; 1127 }, 1128 impressions: function(data) 1129 { 1130 AEC.EventDispatcher.trigger('ec.cookie.impression.data', data); 1131 1132 this.data = data; 1133 1134 return this; 1135 }, 1136 checkout: function(data) 1137 { 1138 AEC.EventDispatcher.trigger('ec.cookie.checkout.step.data', data); 1139 1140 this.data = data; 1141 1142 if (AEC.localStorage) 1143 { 1144 this.data.ecommerce.checkout.products = this.augment(this.data.ecommerce.checkout.products); 1145 } 1146 1147 return this; 1148 }, 1149 checkoutOption: function(data) 1150 { 1151 AEC.EventDispatcher.trigger('ec.cookie.checkout.step.option.data', data); 1152 1153 this.data = data; 1154 1155 return this; 1156 }, 1157 promotion: function(data) 1158 { 1159 AEC.EventDispatcher.trigger('ec.cookie.promotion.data', data); 1160 1161 this.data = data; 1162 1163 return this; 1164 }, 1165 promotionClick: function(data, element) 1166 { 1167 AEC.EventDispatcher.trigger('ec.cookie.promotion.click', data, 1168 { 1169 element: element 1170 }); 1171 1172 this.data = data; 1173 1174 return this; 1175 }, 1176 remarketing: function(data) 1177 { 1178 AEC.EventDispatcher.trigger('ec.cookie.remarketing.data', data); 1179 1180 this.data = data; 1181 1182 return this; 1183 }, 1184 getPrivateData: function() 1185 { 1186 if (!this.privateData) 1187 { 1188 var cookie = this.get('privateData'); 1189 1190 if (cookie) 1191 { 1192 this.privateData = this.parse(cookie); 1193 } 1194 } 1195 1196 return this.privateData; 1197 }, 1198 set: function(name, value, days) 1199 { 1200 if (!days) 1201 { 1202 days = 30; 1203 } 1204 1205 let date = new Date(); 1206 1207 date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000)); 1208 1209 document.cookie = name + "=" + value + "; expires=" + date.toGMTString() + "; path=/"; 1210 1211 return this; 1212 }, 1213 get: function(name) 1214 { 1215 var start = document.cookie.indexOf(name + "="), len = start + name.length + 1; 1216 1217 if ((!start) && (name != document.cookie.substring(0, name.length))) 1218 { 1219 return null; 1220 } 1221 1222 if (start == -1) 1223 { 1224 return null; 1225 } 1226 1227 var end = document.cookie.indexOf(String.fromCharCode(59), len); 1228 1229 if (end == -1) 1230 { 1231 end = document.cookie.length; 1232 } 1233 1234 return decodeURIComponent(document.cookie.substring(len, end)); 1235 }, 1236 unset: function(name) 1237 { 1238 document.cookie = name + "=" + "; path=/; expires=" + (new Date(0)).toUTCString(); 1239 1240 return this; 1241 }, 1242 parse: function(json) 1243 { 1244 var json = decodeURIComponent(json.replace(/\+/g, ' ')); 1245 1246 return JSON.parse(json); 1247 } 1248 } 1249 })(), 1250 CookieConsent: (function() 1251 { 1252 return { 1253 chain: {}, 1254 queue: function(callback, event) 1255 { 1256 event = typeof event !== 'undefined' ? event : AEC.Const.COOKIE_DIRECTIVE_CONSENT_GRANTED_EVENT; 1257 1258 if (!this.chain.hasOwnProperty(event)) 1259 { 1260 this.chain[event] = []; 1261 } 1262 1263 this.chain[event].push(callback); 1264 1265 return this; 1266 }, 1267 dispatch: function(consent) 1268 { 1269 /** 1270 * Essential cookies 1271 */ 1272 AEC.Const.COOKIE_DIRECTIVE_CONSENT_GRANTED = true; 1273 1274 /** 1275 * Push consent to dataLayer 1276 */ 1277 dataLayer.push(consent); 1278 1279 return this.process(consent.event); 1280 }, 1281 process: function(event) 1282 { 1283 event = typeof event !== 'undefined' ? event : AEC.Const.COOKIE_DIRECTIVE_CONSENT_GRANTED_EVENT; 1284 1285 if (this.chain.hasOwnProperty(event) && this.getConsent(event)) 1286 { 1287 for (a = 0, b = this.chain[event].length; a < b; a++) 1288 { 1289 this.chain[event][a].apply(this,[]); 1290 } 1291 1292 this.chain[event] = []; 1293 } 1294 1295 return this; 1296 }, 1297 getConsent: function(event) 1298 { 1299 return 1 == AEC.Cookie.get(event); 1300 }, 1301 acceptConsent: function(event) 1302 { 1303 return this.dispatch({ event:event }); 1304 }, 1305 declineConsent: function(event) 1306 { 1307 return this.dispatch({ event:event }); 1308 }, 1309 getConsentDialog: function(dataLayer, endpoints) 1310 { 1311 if (1 == AEC.Cookie.get(AEC.Const.COOKIE_DIRECTIVE_CONSENT_DECLINE_EVENT)) 1312 { 1313 return true; 1314 } 1315 1316 if (1 != AEC.Cookie.get(AEC.Const.COOKIE_DIRECTIVE_CONSENT_GRANTED_EVENT)) 1317 { 1318 AEC.Request.get(endpoints.cookieContent, {}, (response) => 1319 { 1320 var directive = (body => 1321 { 1322 body.insertAdjacentHTML('beforeend', response.cookieContent); 1323 1324 return body.lastElementChild; 1325 1326 })(document.body); 1327 1328 directive.querySelectorAll('a.ec-gtm-cookie-directive-note-toggle').forEach(element => 1329 { 1330 element.addEventListener('click', event => 1331 { 1332 event.target.nextElementSibling.style.display = 'block' === event.target.nextElementSibling.style.display ? 'none' : 'block'; 1333 }); 1334 }); 1335 1336 directive.querySelectorAll('a.accept').forEach(element => 1337 { 1338 element.addEventListener('click', event => 1339 { 1340 event.target.text = event.target.dataset.confirm; 1341 1342 var grant = [...directive.querySelectorAll('[name="cookie[]"]:checked')].map(element => { return element.value }); 1343 1344 AEC.Request.post(endpoints.cookie, { cookie: grant }, response => 1345 { 1346 Object.keys(response).forEach(event => 1347 { 1348 AEC.CookieConsent.acceptConsent(event); 1349 }); 1350 1351 directive.remove(); 1352 }); 1353 }); 1354 }); 1355 1356 directive.querySelectorAll('a.accept-all').forEach(element => 1357 { 1358 element.addEventListener('click', event => 1359 { 1360 event.target.text = event.target.dataset.confirm; 1361 1362 [...directive.querySelectorAll('[name="cookie[]"]')].forEac
1362h(element => 1363 { 1364 element.checked = true; 1365 }); 1366 1367 element.parentNode.removeChild(element.previousElementSibling); 1368 1369 var grant = [...directive.querySelectorAll('[name="cookie[]"]:checked')].map(element => { return element.value }); 1370 1371 AEC.Request.post(endpoints.cookie, { cookie: grant }, response => 1372 { 1373 Object.keys(response).forEach(event => 1374 { 1375 AEC.CookieConsent.acceptConsent(event); 1376 }); 1377 1378 directive.remove(); 1379 }); 1380 }); 1381 }); 1382 1383 directive.querySelectorAll('a.decline').forEach(element => 1384 { 1385 element.addEventListener('click', event => 1386 { 1387 AEC.Request.post(endpoints.cookie, { decline: true }, response => 1388 { 1389 Object.keys(response).forEach(event => 1390 { 1391 AEC.CookieConsent.declineConsent(event); 1392 }); 1393 1394 directive.remove(); 1395 }); 1396 }); 1397 }); 1398 }); 1399 } 1400 else 1401 { 1402 if (AEC.Const.COOKIE_DIRECTIVE_SEGMENT_MODE) 1403 { 1404 (segments => 1405 { 1406 for (i = 0, l = segments.length; i < l;i++) 1407 { 1408 if (1 == AEC.Cookie.get(segments[i])) 1409 { 1410 AEC.CookieConsent.acceptConsent(segments[i]); 1411 } 1412 } 1413 1414 })(AEC.Const.COOKIE_DIRECTIVE_SEGMENT_MODE_EVENTS); 1415 } 1416 else 1417 { 1418 AEC.CookieConsent.acceptConsent(AEC.Const.COOKIE_DIRECTIVE_CONSENT_GRANTED_EVENT); 1419 } 1420 } 1421 } 1422 } 1423 })(), 1424 Storage: (function(api) 1425 { 1426 return { 1427 set: function(property, value) 1428 { 1429 if ('undefined' !== typeof(Storage)) 1430 { 1431 localStorage.setItem(property, JSON.stringify(value)); 1432 } 1433 1434 return this; 1435 1436 }, 1437 get: function(property) 1438 { 1439 if ('undefined' !== typeof(Storage)) 1440 { 1441 return JSON.parse(localStorage.getItem(property)); 1442 } 1443 1444 return null; 1445 }, 1446 reference: function() 1447 { 1448 return (function(storage) 1449 { 1450 return { 1451 set: function(reference) 1452 { 1453 var current = storage.get('category.add') || []; 1454 1455 var exists = (function(current, reference) 1456 { 1457 for (i = 0, l = current.length; i < l; i++) 1458 { 1459 if (current[i].id.toString().toLowerCase() === reference.id.toString().toLowerCase()) 1460 { 1461 /** 1462 * Update category 1463 */ 1464 current[i].category = reference.category; 1465 1466 return true; 1467 } 1468 } 1469 1470 return false; 1471 1472 })(current, reference); 1473 1474 if (!exists) 1475 { 1476 current.push(reference); 1477 } 1478 1479 storage.set('category.add', current); 1480 1481 return this; 1482 }, 1483 get: function() 1484 { 1485 return storage.get('category.add'); 1486 } 1487 } 1488 })(this); 1489 } 1490 } 1491 })(), 1492 gtm: function() 1493 { 1494 if ("undefined" === typeof google_tag_manager) 1495 { 1496 /** 1497 * Log error to console 1498 */ 1499 console.log('Unable to detect Google Tag Manager. Please verify if GTM install snippet is available.'); 1500 1501 return false; 1502 } 1503 1504 return true; 1505 }, 1506 parseJSON: function(content) 1507 { 1508 if ('object' === typeof content) 1509 { 1510 return content; 1511 } 1512 1513 if ('string' === typeof content) 1514 { 1515 try 1516 { 1517 return JSON.parse(content); 1518 } 1519 catch (e){} 1520 } 1521 1522 return {}; 1523 }, 1524 getPayloadSize: function(object) 1525 { 1526 var objects = [object]; 1527 var size = 0; 1528 1529 for (var index = 0; index < objects.length; index++) 1530 { 1531 switch (typeof objects[index]) 1532 { 1533 case 'boolean': 1534 size += 4; 1535 break; 1536 case 'number': 1537 size += 8; 1538 break; 1539 case 'string': 1540 size += 2 * objects[index].length; 1541 break; 1542 case 'object': 1543 if (Object.prototype.toString.call(objects[index]) != '[object Array]') 1544 { 1545 for (var key in objects[index]) size += 2 * key.length; 1546 } 1547 for (var key in objects[index]) 1548 { 1549 var processed = false;
1550 1551 for (var search = 0; search < objects.length; search++) 1552 { 1553 if (objects[search] === objects[index][key]) { 1554 processed = true; 1555 break; 1556 } 1557 } 1558 if (!processed) objects.push(objects[index][key]); 1559 } 1560 } 1561 } 1562 return size; 1563 }, 1564 getPayloadChunks: function(arr, len) 1565 { 1566 var chunks = [],i = 0, n = arr.length; 1567 1568 while (i < n) 1569 { 1570 chunks.push(arr.slice(i, i += len)); 1571 } 1572 1573 return chunks; 1574 }, 1575 url: function(url) 1576 { 1577 return [this.Const.URL, url].join(''); 1578 }, 1579 EventDispatcher: (function() 1580 { 1581 return { 1582 events: {}, 1583 on: function(event, callback) 1584 { 1585 var handlers = this.events[event] || []; 1586 1587 handlers.push(callback); 1588 1589 this.events[event] = handlers; 1590 }, 1591 trigger: function() 1592 { 1593 /** 1594 * Cast arguments to array 1595 */ 1596 let args = [...arguments]; 1597 1598 /** 1599 * Get event 1600 */ 1601 let event = args ? args.shift() : null; 1602 1603 /** 1604 * Get handlers 1605 */ 1606 let handlers = this.events[event] || []; 1607 1608 /** 1609 * Get data 1610 */ 1611 let data = args ? args.shift() : {}; 1612 1613 /** 1614 * Get options 1615 */ 1616 let options = args ? args.shift() : {}; 1617 1618 /** 1619 * Quit if no handler 1620 */ 1621 if (!handlers || handlers.length < 1) 1622 { 1623 return; 1624 } 1625 1626 console.log(event + '(' + handlers.length + ' listeners)'); 1627 1628 handlers.forEach(function(handler) 1629 { 1630 handler(data, options); 1631 }); 1632 } 1633 } 1634 })(), 1635 Request: (function() 1636 { 1637 return { 1638 get: function(url, params, callback) 1639 { 1640 this.execute('GET', [url,this.serialize(params)].join('?'), callback).send(null); 1641 }, 1642 post: function(url, params, callback) 1643 { 1644 this.execute('POST', url, callback).send(this.serialize(params)); 1645 }, 1646 execute: function(method, url, callback) 1647 { 1648 try 1649 { 1650 var request = new XMLHttpRequest(); 1651 1652 request.open(method, url, true); 1653 1654 request.setRequestHeader('Content-Type','application/x-www-form-urlencoded'); 1655 request.setRequestHeader('X-Requested-With','XMLHttpRequest'); 1656 1657 request.addEventListener('load', () => 1658 { 1659 let response; 1660 1661 if ('application/json' === request.getResponseHeader("Content-Type")) 1662 { 1663 response = JSON.parse(request.responseText); 1664 } 1665 else 1666 { 1667 response = request.responseText; 1668 } 1669 1670 if ('function' === typeof callback) 1671 { 1672 callback(response); 1673 } 1674 }); 1675 } 1676 catch (e) 1677 { 1678 console.log(e.message); 1679 1680 return null; 1681 } 1682 1683 1684 return request; 1685 }, 1686 serialize: function(entity, prefix) 1687 { 1688 var query = []; 1689 1690 Object.keys(entity).map(key => 1691 { 1692 var k = prefix ? prefix + "[" + key + "]" : key, value = entity[key]; 1693 1694 query.push((value !== null && typeof value === "object") ? this.serialize(value, k) : encodeURIComponent(k) + "=" + encodeURIComponent(value)); 1695 }); 1696 1697 return query.join("&"); 1698 } 1699 } 1700 })(), 1701 UUID: (() => 1702 { 1703 return { 1704 generate: event => 1705 { 1706 event = event || {}; 1707 1708 if (-1 == ['AddToCart'].indexOf(event)) 1709 { 1710 try 1711 { 1712 let current = AEC.Cookie.get('facebook_latest_uuid'); 1713 1714 if (current) 1715 { 1716 current = JSON.parse(current); 1717 1718 if (current.hasOwnProperty('uuid') && current.hasOwnProperty('event')) 1719 { 1720 if (event.event === current.event) 1721 { 1722 return current.uuid; 1723 } 1724 } 1725 } 1726 } 1727 catch (e){} 1728 } 1729 1730 let uuid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) 1731 { 1732 var r = Math.random() * 16 | 0, v = c == 'x' ? r : (r & 0x3 | 0x8); 1733 return v.toString(16); 1734 }); 1735 1736 event['uuid'] = uuid; 1737 1738 /**
1739 * Set facebook uuid cookie 1740 */ 1741 if (AEC.Const.COOKIE_DIRECTIVE) 1742 { 1743 if (AEC.Const.COOKIE_DIRECTIVE_CONSENT_GRANTED) 1744 { 1745 AEC.Cookie.set('facebook_latest_uuid', JSON.stringify(event)); 1746 } 1747 } 1748 else 1749 { 1750 AEC.Cookie.set('facebook_latest_uuid', JSON.stringify(event)); 1751 } 1752 1753 return uuid; 1754 } 1755 } 1756 })() 1757 } 1758})();
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.