PageSourceSearch

https://www.stiga.com/static/version1790224918/frontend/Magento/base/default/Anowave_Ec/js/ec.js

js stiga.com collected 2026-09-24 09:36:38 UTC 44,999 bytes, 1,982 lines download raw bytes

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

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.