PageSourceSearch

https://www.teppich.com/media/com_hikashop/js/hikashop.js?v=610

js teppich.com collected 2026-10-06 16:37:14 UTC 73,347 bytes, 2,268 lines download raw bytes

1/**
2 * @package    HikaShop for Joomla!
3 * @version    6.1.0
4 * @author     hikashop.com
5 * @copyright  (C) 2010-2025 HIKARI SOFTWARE. All rights reserved.
6 * @license    GNU/GPLv3 http://www.gnu.org/licenses/gpl-3.0.html
7 */
8(function() {
9
10function preventDefault() { this.returnValue = false; }
11function stopPropagation() { this.cancelBubble = true; }
12
13var Oby = {
14	version: 20171104,
15	ajaxEvents : {},
16
17	hasClass: function(o,n) {
18		if(o.classList && o.classList.contains)
19			return o.classList.contains(n);
20		if(o.className == '' ) return false;
21		var reg = new RegExp("(^|\\s+)"+n+"(\\s+|$)");
22		return reg.test(o.className);
23	},
24	addClass: function(o,n) {
25		if(o.classList && o.classList.add)
26			return o.classList.add(n);
27		if( !this.hasClass(o,n) ) {
28			if( o.className == '' ) {
29				o.className = n;
30			} else {
31				o.className += ' '+n;
32			}
33		}
34	},
35	trim: function(s) {
36		if(s.trim) return s.trim();
37		return (s ? '' + s : '').replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, '');
38	},
39	removeClass: function(e, c) {
40		if(e.classList && e.classList.remove)
41			return e.classList.remove(c);
42		var t = this;
43		if( t.hasClass(e,c) ) {
44			var cn = ' ' + e.className + ' ';
45			e.className = t.trim(cn.replace(' '+c+' ',' '));
46		}
47	},
48	toggleClass: function(e,c) {
49		if(e.classList && e.classList.toggle)
50			return e.classList.toggle(c);
51		var t = this;
52		if( t.hasClass(e,c) ) {
53			return t.removeClass(e,c);
54		}
55		return t.addClass(e,c);
56	},
57	addEvent: function(d,e,f) {
58		if( d.attachEvent )
59			d.attachEvent('on' + e, f);
60		else if (d.addEventListener)
61			d.addEventListener(e, f, false);
62		else
63			d['on' + e] = f;
64		return f;
65	},
66	removeEvent: function(d,e,f) {
67		try {
68			if( d.detachEvent )
69				d.detachEvent('on' + e, f);
70			else if( d.removeEventListener)
71				d.removeEventListener(e, f, false);
72			else
73				d['on' + e] = null;
74		} catch(e) {}
75	},
76	cancelEvent: function(e) {
77		if( !e ) {
78			e = window.event;
79			if( !e )
80				return false;
81		}
82		if(e.stopPropagation)
83			e.stopPropagation();
84		else
85			 e.cancelBubble = true;
86		if( e.preventDefault )
87			e.preventDefault();
88		else
89			e.returnValue = false;
90		return false;
91	},
92	fireEvent: function(obj,e,data) {
93		var d = document, evt = null;
94		if(document.createEvent) {
95			evt = d.createEvent('HTMLEvents');
96			evt.initEvent(e, false, true);
97			if(data) evt.data = data;
98			obj.dispatchEvent(evt);
99			return;
100		}
101		if(data && d.createEventObject) {
102			evt = d.createEventObject();
103			evt.data = data;
104			obj.fireEvent('on'+e, evt);
105			return;
106		}
107		obj.fireEvent('on'+e);
108	},
109	fireAjax: function(name,params) {
110		var t = this, ev, r = null, ret = [];
111		if( t.ajaxEvents[name] === undefined )
112			return false;
113		for(var e in t.ajaxEvents[name]) {
114			if( e == '_id' )
115				continue;
116			ev = t.ajaxEvents[name][e];
117			if(!ev || typeof(ev) != 'function')
118				continue;
119			try {
120				r = ev(params);
121				if(r !== undefined)
122					ret.push(r);
123			}catch(e){}
124		}
125		return ret;
126	},
127	registerAjax: function(name, fct) {
128		var t = this;
129		if(typeof(name) == 'object') {
130			var r = [];
131			for(var k = name.length - 1; k >= 0; k--) {
132				r[r.length] = t.registerAjax(name[k], fct);
133			}
134			return r;
135		}
136		if( t.ajaxEvents[name] === undefined )
137			t.ajaxEvents[name] = {'_id':0};
138		var id = t.ajaxEvents[name]['_id'];
139		t.ajaxEvents[name]['_id'] += 1;
140		t.ajaxEvents[name][id] = fct;
141		return id;
142	},
143	unregisterAjax: function(name, id) {
144		if( t.ajaxEvents[name] === undefined || t.ajaxEvents[name][id] === undefined)
145			return false;
146		t.ajaxEvents[name][id] = null;
147		return true;
148	},
149	ready: function(fct) {
150		var w = window, d = document, t = this;
151		if(d.readyState === "complete") {
152			fct();
153			return;
154		}
155		var done = false, top = true, root = d.documentElement,
156			init = function(e) {
157				if(e.type == 'readystatechange' && d.readyState != 'complete') return;
158				t.removeEvent((e.type == 'load' ? w : d), e.type, init);
159				if(!done && (done = true))
160					fct();
161			},
162			poll = function() {
163				try{ root.doScroll('left'); } catch(e){ setTimeout(poll, 50); return; }
164				init('poll');
165			};
166		if(d.createEventObject && root.doScroll) {
167			try{ top = !w.frameElement; } catch(e){}
168			if(top) poll();
169		}
170		t.addEvent(d,'DOMContentLoaded',init);
171		t.addEvent(d,'readystatechange',init);
172		t.addEvent(w,'load',init);
173	},
174	evalJSON: function(text, secure) {
175		if( typeof(text) != "string" || !text.length) return null;
176		if(JSON !== undefined && typeof(JSON.parse) == 'function') {
177			try { var ret = JSON.parse(text); return ret; } catch(e) {
178				return this.extractJSON(text);
179			}
180		}
181		if(secure && !(/^[,:{}\[\]0-9.\-+Eaeflnr-u \n\r\t]*$/).test(text.replace(/\\./g, '@').replace(/"[^"\\\n\r]*"/g, ''))) return null;
182		try { var ret = eval('(' + text + ')'); return ret; } catch(e) { }
183		return null;
184	},
185	extractJSON: function(str) {
186		var firstOpen, firstClose, candidate;
187		firstOpen = str.indexOf('{', firstOpen + 1);
188		do {
189			firstClose = str.lastIndexOf('}');
190			if(firstClose <= firstOpen) {
191				return null;
192			}
193			do {
194				candidate = str.substring(firstOpen, firstClose + 1);
195				try {
196					var res = JSON.parse(candidate);
197					return res;
198				}
199				catch(e) {
200					console.log('failed parsing JSON in string below:');
201					console.log(candidate);
202				}
203				firstClose = str.substr(0, firstClose).lastIndexOf('}');
204			} while(firstClose > firstOpen);
205			firstOpen = str.indexOf('{', firstOpen + 1);
206		} while(firstOpen != -1);
207		return null;
208	},
209	getXHR: function() {
210		var xhr = null, w = window;
211		if(w.XMLHttpRequest || w.ActiveXObject) {
212			if(w.ActiveXObject) {
213				try {
214					xhr = new ActiveXObject("Microsoft.XMLHTTP");
215				} catch(e) {}
216			} else
217				xhr = new w.XMLHttpRequest();
218		}
219		return xhr;
220	},
221	xRequest: function(url, options, cb, cbError) {
222		var t = this, xhr = t.getXHR();
223		if(!options) options = {};
224		if(!cb) cb = function(){};
225		options.mode = options.mode || 'GET';
226		options.update = options.update || false;
227		xhr.onreadystatechange = function() {
228			if(xhr.readyState != 4)
229				return;
230			if( xhr.status == 200 || (xhr.status == 0 && xhr.responseText > 0) || !cbError ) {
231				if(cb)
232					cb(xhr,options.params);
233				if(options.update)
234					t.updateElem(options.update, xhr.responseText);
235			} else {
236				cbError(xhr,options.params);
237			}
238		};
239		xhr.open(options.mode, url, true);
240		if(options.mode.toUpperCase() == 'POST' && typeof(options.data) == 'string') {
241			xhr.setRequestHeader("Content-type","application/x-www-form-urlencoded");
242		}
243		if(typeof Joomla !== 'undefined' && Joomla && Joomla.getOptions) {
244			var csrf = Joomla.getOptions("csrf.token", "");
245			if(csrf) {
246				xhr.setRequestHeader("X-CSRF-Token", csrf);
247			}
248		}
249		xhr.send( options.data );
250	},
251	getFormData: function(target, encoded) {
252		var d = document, ret = {};
253		if(encoded === undefined) encoded = true;
254		if( typeof(target) == 'string' )
255			target = d.getElementById(target);
256		if( target === undefined )
257			target = d;
258		var typelist = ['input','select','textarea'];
259		for(var t in typelist) {
260			if(!typelist.hasOwnProperty(t))
261				continue;
262			t = typelist[t];
263			var inputs = target.getElementsByTagName(t);
264			for(var i = 0; i < inputs.length; i++) {
265				if( !inputs[i].name || inputs[i].disabled )
266					continue;
267				var evalue = inputs[i].value, n = inputs[i].name, etype = '';
268				if( t == 'input' )
269					etype = inputs[i].type.toLowerCase();
270				if( (etype == 'radio' || etype == 'checkbox') && !inputs[i].checked )
271					evalue = null;
272				if(t == 'select' && inputs[i].multiple) {
273					for(var k = inputs[i].options.length - 1; k >= 0; k--) {
274						if(!inputs[i].options[k].selected)
275							continue;
276						//if( ret != '' ) ret += '&';
277						//ret += encodeURI(inputs[i].name) + '=' + encodeURIComponent(inputs[i].options[k].value);
278						if(ret.hasOwnProperty(n)) {
279							if(typeof(ret[n]) != 'object')
280								ret[n] = [ ret[n] ];
281							ret[n][ ret[n].length ] = inputs[i].options[k].value;
282						} else
283							ret[ n ] = inputs[i].options[k].value;
284						evalue = null;
285					}
286				}
287				if( (etype != 'file' && etype != 'submit') && evalue != null ) {
288					//if( ret != '' ) ret += '&';
289					//ret += encodeURI(inputs[i].name) + '=' + encodeURIComponent(evalue);
290
291					if(ret.hasOwnProperty(n)) {
292						if(typeof(ret[n]) != 'object')
293							ret[n] = [ ret[n] ];
294						ret[n][ ret[n].length ] = evalue;
295					} else
296						ret[ n ] = evalue;
297				}
298			}
299		}
300		if(encoded)
301			return this.encodeFormData(ret);
302		return ret;
303	},
304	encodeFormData: function(data) {
305		var ret = '', v = null;
306		if(typeof(data) == "string")
307			return data;
308		for(var k in data) {
309			if(!data.hasOwnProperty(k))
310				continue;
311			v = data[k];
312			if(typeof(v) == 'object') {
313				for(var i in v) {
314					if(!v.hasOwnProperty(i))
315						continue;
316					if( ret != '' ) ret += '&';
317					ret += encodeURI(k) + '=' + encodeURIComponent(v[i]);
318				}
319			} else {
320				if( ret != '' ) ret += '&';
321				ret += encodeURI(k) + '=' + encodeURIComponent(v);
322			}
323		}
324		return ret;
325	},
326	updateElem: function(elem, data) {
327		var d = document, scripts = '';
328		if( typeof(elem) == 'string' )
329			elem = d.getElementById(elem);
330		var text = data.replace(/<script[^>]*>([\s\S]*?)<\/script>/gi, function(all, code){
331			if(all.indexOf('type="application/json"')>=0 || all.indexOf('type="application/ld+json"')>=0)
332				return all;
333			scripts += code + '\n';
334			return '';
335		});
336		elem.innerHTML = text;
337		if( scripts != '' ) {
338			var script = d.createElement('script');
339			script.setAttribute('type', 'text/javascript');
340			script.text = scripts;
341			try {
342				d.head.appendChild(script);
343				d.head.removeChild(script);
344			} catch(e) {}
345		}
346	},
347	ease: function(v) {
348		return 1+Math.pow(v-1,3);
349	},
350	easeInOut: function(t,s,dt,du) {
351		return dt/2 * (1 - Math.cos(Math.PI*t/du)) + s;
352	},
353	scrollTo: function(name, anim, visible, margin) {
354		var t = this, d = document, w = window,
355			elem = d.getElementById(name);
356		if(!elem)
357			return;
358		if(margin === undefined) margin = 0;
359		if(!anim) {
360			window.scrollTo(0, elem.offsetTop - margin);
361			return;
362		}
363		if( t.anim && t.anim.timer )
364			clearInterval( t.anim.timer );
365		t.anim = { timer:null, s:null, dt:0, du:150, t:0, inc:10 };
366		if( w.scrollY )
367			t.anim.s = w.scrollY;
368		else if( d.documentElement.scrollTop )
369			t.anim.s = d.documentElement.scrollTop;
370		else
371			t.anim.s = d.body.scrollTop;
372		if(visible) {
373			if( d.documentElement.scrollTop )
374				h = d.documentElement.clientHeight;
375			else
376				h = d.body.clientHeight;
377			if(t.anim.s <= elem.offsetTop && (t.anim.s + h - 150) > elem.offsetTop)
378				return;
379		}
380		t.anim.dt = elem.offsetTop - t.anim.s - margin;
381		var o = this;
382		t.anim.timer = setInterval( function() {
383			var a = o.anim;
384			if( !a || !a.timer )
385				return;
386			a.t += a.inc;
387			if( a.t < a.du ) {
388				window.scrollTo(0, o.easeInOut(a.t, a.s, a.dt, a.du), false, margin);
389			} else {
390				window.scrollTo(0, a.s + a.dt, false, margin);
391				clearInterval(a.timer);
392				a.timer = null;
393			}
394		}, t.anim.inc );
395	}
396};
397if((typeof(window.Oby) == 'undefined') || window.Oby.version < Oby.version) {
398	window.Oby = Oby;
399	window.obscurelighty = Oby;
400}
401
402var oldHikaShop = window.hikashop || hikashop;
403
404var hikashop = {
405	translations: {},
406	translations_url: null,
407	submitFct: null,
408	filterRefreshTimer: false,
409
410	setCookie: function (name,value,delay) {
411		document.cookie = name + "=" + (value || "")  +  "; expires=" + delay + "; path=/";
412   	},
413	submitBox: function(data) {
414		var t = this, d = document, w = window;
415		if( t.submitFct ) {
416			try {
417				t.submitFct(data);
418			} catch(err) {}
419		}
420		t.closeBox();
421	},
422	deleteId: function(id) {
423		var t = this, d = document, el = id;
424		if( typeof(id) == "string") {
425			el = d.getElementById(id);
426		}
427		if(!el)
428			return;
429		el.parentNode.removeChild(el);
430	},
431	dup: function(tplName, htmlblocks, id, extraData, appendTo) {
432		var d = document, tplElem = d.getElementById(tplName);
433		if(!tplElem) return;
434		var container = tplElem.parentNode;
435		elem = tplElem.cloneNode(true);
436		if(!appendTo) {
437			container.insertBefore(elem, tplElem);
438		} else {
439			if(typeof(appendTo) == "string")
440				appendTo = d.getElementById(appendTo);
441			appendTo.appendChild(elem);
442		}
443		elem.style.display = "";
444		elem.id = '';
445		if(id)
446			elem.id = id;
447		for(var k in htmlblocks) {
448			elem.innerHTML = elem.innerHTML.replace(new RegExp("{"+k+"}","g"), htmlblocks[k]);
449			elem.innerHTML = elem.innerHTML.replace(new RegExp("%7B"+k+"%7D","g"), htmlblocks[k]);
450		}
451		if(extraData) {
452			for(var k in extraData) {
453				elem.innerHTML = elem.innerHTML.replace(new RegExp('{'+k+'}','g'), extraData[k]);
454				elem.innerHTML = elem.innerHTML.replace(new RegExp('%7B'+k+'%7D','g'), extraData[k]);
455			}
456		}
457		return elem;
458	},
459	deleteRow: function(id) {
460		var t = this, d = document, el = id;
461		if( typeof(id) == "string") {
462			el = d.getElementById(id);
463		} else {
464			while(el != null && el.tagName.toLowerCase() != 'tr') {
465				el = el.parentNode;
466			}
467		}
468		if(!el)
469			return;
470		var table = el.parentNode;
471		table.removeChild(el);
472		if( table.tagName.toLowerCase() == 'tbody' )
473			table = table.parentNode;
474		t.cleanTableRows(table);
475		return;
476	},
477	dupRow: function(tplName, htmlblocks, id, extraData) {
478		var d = document, tplLine = d.getElementById(tplName),
479				tableUser = tplLine.parentNode;
480		if(!tplLine) return;
481		trLine = tplLine.cloneNode(true);
482		tableUser.insertBefore(trLine, tplLine);
483		trLine.style.display = "";
484		trLine.id = "";
485		if(id)
486			trLine.id = id;
487		for(var i = tplLine.cells.length - 1; i >= 0; i--) {
488			if(trLine.cells[i]) {
489				for(var k in htmlblocks) {
490					if(!htmlblocks.hasOwnProperty(k))
491						continue;
492					trLine.cells[i].innerHTML = trLine.cells[i].innerHTML.replace(new RegExp("{"+k+"}","g"), htmlblocks[k]);
493					trLine.cells[i].innerHTML = trLine.cells[i].innerHTML.replace(new RegExp("%7B"+k+"%7D","g"), htmlblocks[k]);
494				}
495				if(extraData) {
496					for(var k in extraData) {
497						if(!extraData.hasOwnProperty(k))
498							continue;
499						trLine.cells[i].innerHTML = trLine.cells[i].innerHTML.replace(new RegExp('{'+k+'}','g'), extraData[k]);
500						trLine.cells[i].innerHTML = trLine.cells[i].innerHTML.replace(new RegExp('%7B'+k+'%7D','g'), extraData[k]);
501					}
502				}
503			}
504		}
505		if(tplLine.className == "row0") tplLine.className = "row1";
506		else if(tplLine.className == "row1") tplLine.className = "row0";
507		return trLine;
508	},
509	cleanTableRows: function(id) {
510		var d = document, el = id;
511		if(typeof(id) == "string")
512			el = d.getElementById(id);
513		if(el == null || el.tagName.toLowerCase() != 'table')
514			return;
515
516		var k = 0, c = '', line = null, lines = el.getElementsByTagName('tr');
517		for(var i = 0; i < lines.length; i++) {
518			line = lines[i];
519			if( line.style.display != "none") {
520				c = ' '+line.className+' ';
521				if( c.indexOf(' row0 ') >= 0 || c.indexOf(' row1 ') >= 0 ) {
522					line.className = c.replace(' row'+(1-k)+' ', ' row'+k+' ').replace(/^\s*|\s*$/g, '');
523					k = 1 - k;
524				}
525			}
526		}
527	},
528	checkRow: function(id) {
529		var t = this, d = document, el = id;
530		if(typeof(id) == "string")
531			el = d.getElementById(id);
532		if(el == null || el.tagName.toLowerCase() != 'input')
533			return;
534		if(this.clicked) {
535			this.clicked = null;
536			t.isChecked(el);
537			return;
538		}
539		el.checked = !el.checked;
540		t.isChecked(el);
541	},
542	isChecked: function(id,cancel) {
543		var d = document, el = id;
544		if(typeof(id) == "string")
545			el = d.getElementById(id);
546		if(el == null || el.tagName.toLowerCase() != 'input')
547			return;
548		if(el.form.boxchecked) {
549			if(el.checked)
550				el.form.boxchecked.value++;
551			else
552				el.form.boxchecked.value--;
553		}
554	},
555	checkAll: function(checkbox, stub) {
556		stub = stub || 'cb';
557		if(!checkbox.form)
558			return false;
559		var o = window.Oby, cb = checkbox.form, c = 0;
560		for(var i = 0, n = cb.elements.length; i < n; i++) {
561			var e = cb.elements[i];
562			if (e != checkbox && e.type == checkbox.type && ((stub && e.id.indexOf(stub) == 0) || !stub)) {
563				e.checked = checkbox.checked;
564				o.fireEvent(e, 'change');
565				o.fireEvent(e, 'click');
566				c += (e.checked == true ? 1 : 0);
567			}
568		}
569		if (cb.boxchecked) {
570			cb.boxchecked.value = c;
571		}
572		return true;
573	},
574	submitform: function(task, form, extra) {
575		var d = document;
576		if(typeof form == 'string') {
577			var f = d.getElementById(form);
578			if(!f)
579				f = d.forms[form];
580			if(!f)
581				return true;
582			form = f;
583		}
584		if(task) {
585			form.task.value = task;
586		}
587		if(typeof form.onsubmit == 'function')
588			form.onsubmit();
589		form.submit();
590		return false;
591	},
592	get: function(elem, target) {
593		window.hikashop.xRequest(elem.getAttribute('href'), {update: target});
594		return false;
595	},
596	form: function(elem, target) {
597		var data = window.Oby.getFormData(target);
598		window.hikashop.xRequest(elem.getAttribute('href'), {update: target, mode: 'POST', data: data});
599		return false;
600	},
601	openBox: function(elem, url, jqmodal) {
602		var w = window;
603		if(typeof(elem) == "string")
604			elem = document.getElementById(elem);
605		if(!elem)
606			return false;
607		try {
608			var hkpopup = elem.getAttribute('data-hk-popup');
609			if(jqmodal === undefined) {
610				jqmodal = false;
611				var test_rel = elem.getAttribute('rel');
612				if(test_rel == null && hkpopup == null && typeof(jQuery) != "undefined")
613					jqmodal = true;
614			}
615			if(hkpopup) {
616				var fct = this['openBox_' + hkpopup.toLowerCase()];
617				if(fct) {
618					var ret = fct(elem, url);
619					if(ret == true)
620						return false;
621				}
622			}
623			if(!jqmodal && this.openBox_squeezebox(elem, url))
624				return false;
625			if(this.openBox_bootstrap(elem, url))
626				return false;
627			console.log('no popup system found');
628		} catch(e) { console.log(e); }
629		return false;
630	},
631	openBox_squeezebox: function(elem, url) {
632		if(window.SqueezeBox === undefined)
633			return false;
634		if(url !== undefined && url !== null)
635			elem.href = url;
636		if(!elem.rel && elem.getAttribute('data-hk-popup') == 'squeezebox')
637			elem.rel = elem.getAttribute('data-squeezebox');
638		if(window.SqueezeBox.open !== undefined)
639			SqueezeBox.open(elem, {parse: 'rel'});
640		else if(window.SqueezeBox.fromElement !== undefined)
641			SqueezeBox.fromElement(elem);
642		setTimeout(function(){
643			jQuery('#sbox-content').find('iframe').attr('name', 'hikashop_popup_iframe');
644		},500);
645		return true;
646	},
647	openBox_bootstrap: function(elem, url) {
648		if(typeof(jQuery) == "undefined")
649			return false;
650		var id = elem.getAttribute('id');
651		jQuery('#modal-' + id).modal('show');
652		if(!url)
653			return true;
654		if(document.getElementById('modal-' + id + '-container'))
655			jQuery('#modal-' + id + '-container').find('iframe').attr('src', url);
656		else
657			jQuery('#modal-' + id).find('iframe').attr('src', url);
658		jQuery('#modal-' + id).find('iframe').attr('name', 'hikashop_popup_iframe');
659		return true;
660	},
661	openBox_vex: function(elem, url) {
662		if(typeof(vex) == "undefined")
663			return false;
664		var href = elem.href || null;
665		if(url !== undefined && url !== null)
666			href = url;
667		if(!href) href = elem.getAttribute('href');
668		settings = window.Oby.evalJSON(elem.getAttribute('data-vex'));
669		if(settings.x && settings.y && href) {
670			settings.content = '<iframe style="border:0;margin:0;padding:0;" name="hikashop_popup_iframe" width="'+settings.x+'px" height="'+settings.y+'px" src="'+href+'"></iframe>';
671			settings.afterOpen = function(context) { context.width(settings.x + 'px'); };
672		}
673		vex.defaultOptions.className = 'vex-theme-default';
674		vex.open( settings );
675		return true;
676	},
677	closeBox: function(parent) {
678		var d = document, w = window;
679		if(parent) {
680			d = window.parent.document;
681			w = window.parent;
682		}
683		try {
684			var e = d.getElementById('sbox-window');
685			if(e && typeof(e.close) != "undefined") {
686				e.close();
687			} else if(typeof(w.jQuery) != "undefined" && w.jQuery('div.modal.in') && w.jQuery('div.modal.in').hasClass('in')) {
688				w.jQuery('div.modal.in').modal('hide');
689			} else if(typeof(vex) != 'undefined' && vex.close && vex.close() === true) {
690				return;
691			} else if(w.SqueezeBox !== undefined) {
692				w.SqueezeBox.close();
693			}
694		} catch(err) {}
695	},
696	submitPopup: function(id, task, form) {
697		var d = document, t = this, el = d.getElementById('modal-'+id+'-iframe');
698		if(!el) {
699			if(document.getElementById('modal-' + id + '-container'))
700				el = jQuery('#modal-' + id + '-container').find('iframe').get(0);
701			else
702				el = jQuery('#modal-' + id).find('iframe').get(0);
703		}
704		if(el && el.contentWindow.hikashop) {
705			if(task === undefined) task = null;
706			if(form === undefined) form = 'adminForm';
707			el.contentWindow.hikashop.submitform(task, form);
708		}
709		return false;
710	},
711	tabSelect: function(m,c,id) {
712		var d = document, sub = null;
713		if(typeof m == 'string')
714			m = d.getElementById(m);
715		if(!m) return;
716		if(typeof id == 'string')
717			id = d.getElementById(id);
718		sub = m.getElementsByTagName('div');
719		if(sub) {
720			for(var i = sub.length - 1; i >= 0; i--) {
721				if(sub[i].getAttribute('class') == c) {
722					sub[i].style.display = 'none';
723				}
724			}
725		}
726		if(id) id.style.display = '';
727	},
728	changeState: function(el, id, url) {
729		var d = document;
730		if(!d.getElementById(id + '_container'))
731			return false;
732		var mainDiv = el.closest('.hikashop_checkout_address');
733		if(mainDiv)
734			window.checkout.setLoading(mainDiv, true, true);
735		window.Oby.xRequest(url, null, function(xhr){
736			var w = window;
737			w.hikashop.updateElem(id + '_container', xhr.responseText);
738			var defaultVal = '', defaultValInput = d.getElementById(id + '_default_value'), stateSelect = d.getElementById(id);
739			if(defaultValInput) { defaultVal = defaultValInput.value; }
740			if(stateSelect && w.hikashop.optionValueIndexOf(stateSelect.options, defaultVal) >= 0)
741				stateSelect.value = defaultVal;
742			if(typeof(jQuery) != "undefined" && jQuery().chosen) { jQuery('#'+id).chosen(); }
743			if(mainDiv)
744				window.checkout.setLoading(mainDiv, false);
745			w.Oby.fireAjax('hikashop.stateupdated', {id: id, elem: stateSelect});
746		});
747	},
748	optionValueIndexOf: function(options, value) {
749		for(var i = options.length - 1; i >= 0; i--) {
750			if(options[i].value == value)
751				return i;
752		}
753		return -1;
754	},
755	getOffset: function(el) {
756		var x = 0, y = 0;
757		while(el && !isNaN( el.offsetLeft ) && !isNaN( el.offsetTop )) {
758			x += el.offsetLeft - el.scrollLeft;
759			y += el.offsetTop - el.scrollTop;
760			el = el.offsetParent;
761		}
762		return { top: y, left: x };
763	},
764	dataStore: function(name, value) {
765		if(localStorage) {
766			localStorage.setItem(name, value);
767		} else {
768			var expire = new Date(); expire.setDate(expire.getDate() + 5);
769			document.cookie = name+"="+value+"; expires="+expire;
770		}
771	},
772	dataGet: function(name) {
773		if(localStorage) {
774			return localStorage.getItem(name);
775		}
776		if(document.cookie.length > 0 && document.cookie.indexOf(name+"=") != -1) {
777			var s = name+"=", o = document.cookie.indexOf(s) + s.length, e = document.cookie.indexOf(";",o);
778			if(e == -1) e = document.cookie.length;
779			return unescape(document.cookie.substring(o, e));
780		}
781		return null;
782	},
783	setArrayDisplay: function(fields, displayValue) {
784		var d = document, e = null;
785		if(displayValue === true) displayValue = '';
786		if(displayValue === false) displayValue = 'none';
787		for(var i = 0; i < fields.length; i++) {
788			e = d.getElementById(fields[i]);
789			if(e) e.style.display = displayValue;
790		}
791	},
792	ready: function(fct) {
793		var w = window, d = w.document;
794		if(d.readyState === "complete") {
795			fct();
796			return;
797		}
798		if(w.jQuery !== undefined) {
799			jQuery(d).ready(fct);
800		} else if(window.addEvent) {
801			w.addEvent("domready", fct);
802		} else
803			w.Oby.ready(fct);
804	},
805	noChzn: function() {
806		if(!window.jQuery)
807			return false;
808		jQuery('.no-chzn').each(function(i,el) {
809			var id = el.getAttribute('id'), chzn = null;
810			if(id) {
811				id = id.replace('{','_').replace('}','_');
812				chzn = jQuery('#'+id+'_chzn');
813			} else {
814				chzn = el.nextSibling;
815			}
816			if(chzn) chzn.remove();
817			jQuery(el).removeClass('chzn-done').show();
818		});
819		return true;
820	},
821	switchTab: function(el) {
822		if(!el || !el.parentNode || !el.parentNode.parentNode) return false;
823		var d = document, w = window, o = w.Oby,
824			c = el.parentNode.parentNode,
825			r = c.getAttribute('rel'),
826			current = el.getAttribute('rel'),
827			dest = null;
828		if(!r || r.substring(0,5) != 'tabs:') return false;
829		if(current.substring(0,4) != 'tab:') return false;
830		var id = r.substring(5),
831			tabs = c.childNodes;
832		current = current.substring(4);
833		dest = d.getElementById(id + current);
834		if(!dest) return false;
835		for(var k = 0; k < tabs.length; k++) {
836			if(!tabs[k] || tabs[k].nodeName.toLowerCase() != 'li') continue;
837			var i = 0, l = tabs[k].childNodes[i], lr = null;
838			while(l.nodeName.toLowerCase() != 'a' && i < tabs[k].childNodes.length)
839				l = tabs[k].childNodes[++i];
840			if(l.nodeName.toLowerCase() == 'a')
841				lr = l.getAttribute('rel');
842			if(!lr || lr.substring(0,4) != 'tab:')
843				continue;
844			var lid = lr.substring(4);
845			if(lid == current) continue;
846			o.removeClass(tabs[k], 'active');
847			var ld = d.getElementById(id + lid);
848			if(ld) ld.style.display = 'none';
849		}
850		dest.style.display = '';
851		o.addClass(el.parentNode, 'active');
852		el.blur();
853		return false;
854	},
855	dlTitle: function(parent) {
856		var t = this, d = document, w = window;
857		if(parent && typeof(parent) == 'string')
858			parent = d.getElementById(parent);
859		if(!parent)
860			parent = d;
861		var dt = parent.getElementsByTagName('dt'), val = null,
862			hkTip = (typeof(hkjQuery) != "undefined" && hkjQuery().hktooltip);
863		for(var i = 0; i < dt.length; i++) {
864			if(dt[i].offsetWidth === 0) {
865				dt[i].dlTitleFct = function(evt){
866					t.dlTitle(this.parentNode);
867					if(hkTip)
868						hkjQuery(this).hktooltip('show');
869					this.removeEventListener('mouseover', this.dlTitleFct);
870					this.dlTitleFct = null;
871				};
872				dt[i].addEventListener('mouseover', dt[i].dlTitleFct);
873			}
874			if(dt[i].offsetWidth < dt[i].scrollWidth && !dt[i].getAttribute('title')) {
875				val = (dt[i].innerText !== undefined) ? dt[i].innerText : dt[i].textContent;
876
877				if(hkTip) {
878					dt[i].setAttribute('data-title', val);
879					hkjQuery(dt[i]).hktooltip({"html": true,"container": "body"});
880				} else
881					dt[i].setAttribute('title', val);
882			}
883		}
884	},
885	checkConsistency: function() {
886		if(!document.querySelectorAll)
887			return;
888		var s = null, elems = null,
889			parents = document.querySelectorAll('[data-consistencyheight]');
890		if(!parents || !parents.length)
891			return;
892		for(var i = parents.length - 1; i >= 0; i--) {
893			s = parents[i].getAttribute('data-consistencyheight');
894			if(s == '' || s == 'true')
895				continue;
896			var reg = new RegExp('^\.[-_a-z0-9]+$', 'i');
897			if(reg.test(s) && document.getElementsByClassName)
898				elems = parents[i].getElementsByClassName(s.substring(1));
899			else
900				elems = parents[i].querySelectorAll(s);
901			if(!elems || !elems.length)
902				continue;
903			if(this.setConsistencyHeight(elems, 'min') === false)
904				continue;
905			parents[i].setAttribute('data-consistencyheight-done', s);
906			parents[i].removeAttribute('data-consistencyheight');
907		}
908	},
909	setConsistencyHeight: function(elems, mode) {
910		if(!elems || !elems.length || elems.length == 0)
911			return;
912		var maxHeight = 0, cpt = 0, h = 0, w = window;
913		for(var i = elems.length - 1; i >= 0; i--) {
914			try {
915				h = parseFloat( w.getComputedStyle(elems[i], '').getPropertyValue('height') );
916				h = Math.ceil(h);
917			} catch(e) {
918				h = NaN;
919			}
920			if(isNaN(h))
921				h = (elems[i].currentStyle ? elems[i].currentStyle.height : elems[i].clientHeight);
922
923			if(maxHeight > 0 && h < maxHeight) {
924				cpt++;
925			} else if(h > maxHeight) {
926				maxHeight = h;
927				cpt++;
928			}
929		}
930		if(maxHeight <= 0)
931			return false;
932
933		if(cpt <= 1)
934			return;
935		for(var i = elems.length - 1; i >= 0; i--) {
936			if(mode !== undefined && mode == 'min')
937				elems[i].style.minHeight = maxHeight + 'px';
938			else
939				elems[i].style.height = maxHeight + 'px';
940		}
941	},
942	refreshFilters: function (el, skipSelf) {
943		"use strict";
944		var d = document, t = this, o = window.Oby,
945		container = null, data = null, containerName = el.getAttribute('data-container-div');
946
947		if(containerName)
948			container = d.forms[containerName];
949
950		if(!container)
951			return false;
952
953		var url = container.getAttribute('action');
954		var scrollToTop = container.getAttribute('data-scroll');
955
956		// delay timer to avoid too many ajax calls
957		if(t.filterRefreshTimer !== false) clearTimeout(t.filterRefreshTimer);
958		t.filterRefreshTimer = setTimeout(function() {
959
960			data = o.getFormData(container);
961			data += '&tmpl=raw';
962			o.xRequest(url, {mode:'POST', data: data}, function(xhr) {
963				var resp = o.evalJSON(xhr.responseText);
964
965				if(resp.newURL) {
966					var urlInHistory = resp.newURL.replace('tmpl=raw&', '', 'g').replace('tmpl=component&', '', 'g').replace('filter=1&', '', 'g').replace('&tmpl=raw', '', 'g').replace('&tmpl=component', '', 'g').replace('&filter=1', '', 'g');
967					window.history.pushState(data, d.title, urlInHistory);
968
969					window.addEventListener('popstate', function(e) {
970						if(window.location.href.includes('hikashop_url_reload=1')) {
971							window.location.href.replace('&hikashop_url_reload=1','').reload();
972						}
973					});
974				}
975
976				var refreshAreas = document.querySelectorAll('.filter_refresh_div');
977
978				var triggers = o.fireAjax('filters.update', {el: el, refreshAreas : refreshAreas, resp: resp});
979				if(triggers !== false && triggers.length > 0)
980					return true;
981
982				var refreshUrl = null;
983				t.refreshCounter = 0;
984				for(let i = 0; i < refreshAreas.length; i++) {
985					var currentArea = refreshAreas[i];
986					if(skipSelf && currentArea.querySelector('#'+el.id))
987						continue;
988
989					if(resp.newURL && currentArea.getAttribute('data-use-url')) {
990						refreshUrl = resp.newURL;
991					} else {
992						refreshUrl = currentArea.getAttribute('data-refresh-url');
993						if(resp.params) {
994							refreshUrl += '&' + resp.params + '&return_url=' + encodeURIComponent(window.location.href);
995						}
996					}
997					if(!refreshUrl)
998						continue;
999					t.refreshCounter++;
1000					var className = currentArea.getAttribute('data-refresh-class');
1001					if(className) o.addClass(currentArea, className);
1002					t.refreshOneArea(refreshUrl, currentArea, el, refreshAreas, resp);
1003				}
1004
1005				if(scrollToTop) {
1006					window.hikashop.smoothScroll();
1007				}
1008			});
1009			t.filterRefreshTimer = false;
1010		}, 300);
1011		return false;
1012	},
1013	smoothScroll: function(target) {
1014		var target = document.querySelector('div[id^="hikashop_category_information_menu_"]');
1015		if(!target)
1016			return;
1017		var currentScroll = document.documentElement.scrollTop || document.body.scrollTop;
1018		if (currentScroll > target.offsetTop) {
1019			window.requestAnimationFrame(window.hikashop.smoothScroll);
1020			window.scrollTo (target.offsetTop, currentScroll - (currentScroll/5));
1021		}
1022	},
1023	refreshOneArea: function(refreshUrl, currentArea, el, refreshAreas, resp) {
1024		var d = document, t = this, o = window.Oby;
1025		o.xRequest(refreshUrl, {mode:'GET'}, function (xhr2) {
1026			var div = d.createElement('div');
1027			var scripts = '';
1028			var text = xhr2.responseText.replace(/<script[^>]*>([\s\S]*?)<\/script>/gi, function(all, code){
1029				if(all.indexOf('type="application/json"') != -1)
1030					return '';
1031				if(all.indexOf('type="application/ld+json"') != -1)
1032					return '';
1033				scripts += code + '\n';
1034				return '';
1035			});
1036
1037			var body = /<body.*?>([\s\S]*)<\/body>/.exec(text);
1038			if(!body)
1039				body = text;
1040			else
1041				body = body[1];
1042			window.hikashop.updateElem(div, body);
1043			var newElem = div.querySelector('.filter_refresh_div');
1044
1045			// to avoid scroll in chrome
1046			setTimeout(function(){
1047				if(!currentArea) {
1048					t.refreshCounter--;
1049					return;
1050				}
1051				var className = currentArea.getAttribute('data-refresh-class');
1052				if(className) o.removeClass(currentArea, className);
1053				if(!newElem) {
1054					t.refreshCounter--;
1055					return;
1056				}
1057				var parentNode = currentArea.parentNode;
1058				if(!parentNode) {
1059					t.refreshCounter--;
1060					return;
1061				}
1062				parentNode.replaceChild(newElem, currentArea);
1063				if( scripts != '' ) {
1064					new Promise((resolve, reject)=>{
1065						var script = d.createElement('script');
1066						script.setAttribute('type', 'text/javascript');
1067
1068						var windowErrorHandler = (event) =>{
1069							event.preventDefault();
1070							var error = event.error;
1071							error.stack = error.stack + '\n\n' + scripts;
1072							window.removeEventListener('error', windowErrorHandler);
1073							reject(error);
1074						};
1075						window.addEventListener('error', windowErrorHandler);
1076
1077						var rejectHandler = (error) =>{
1078							window.removeEventListener('error', windowErrorHandler);
1079							reject(error);
1080						};
1081						script.addEventListener('error', rejectHandler);
1082						script.addEventListener('abort', rejectHandler);
1083						var loadedHandler = ()=>{
1084							window.removeEventListener('error', windowErrorHandler);
1085							resolve();
1086						};
1087
1088						script.addEventListener('load', loadedHandler);
1089						script.text = scripts.replaceAll('let jch_', 'jch_').replaceAll('const jch', 'window.hikashop.jch');
1090						try {
1091							d.head.appendChild(script);
1092							d.head.removeChild(script);
1093						} catch (e) {
1094							if (e instanceof SyntaxError) {
1095							}
1096						}
1097					})
1098					.catch(error => {
1099						console.warn('Could not process JavaScript code:\n', error);
1100					})
1101					.then(()=>{
1102					});
1103				}
1104
1105				if(!window.localPage) window.localPage = {};
1106				window.localPage.infiniteScrollPage = 1;
1107
1108				setTimeout(function(){
1109					var needHeightConsistency = currentArea.querySelector('[data-consistencyheight]');
1110					if(needHeightConsistency) {
1111						var elems = parentNode.querySelectorAll('.hikashop_subcontainer');
1112						if(elems && elems.length)
1113							window.hikashop.setConsistencyHeight(elems, 'min');
1114					}
1115
1116					if(window.hikaVotes)
1117						initVote(currentArea);
1118					if(hkjQuery && hkjQuery.hktooltip)
1119						hkjQuery('[data-toggle="hk-tooltip"]').hktooltip({"html": true,"container": "body"});
1120
1121					t.refreshCounter--;
1122					if(t.refreshCounter == 0) {
1123						o.fireAjax('filters.updated', {el: el, refreshAreas : refreshAreas, resp: resp});
1124					}
1125				}, 200);
1126			}, 0);
1127		});
1128	},
1129	addToCart: function(el, type, container, data) {
1130
1131		var d = document, t = this, o = window.Oby,
1132			product_id = 0,
1133			url = el.getAttribute('href'),
1134			cart_type = ((type !== 'wishlist') ? 'cart' : 'wishlist'),
1135			containerName = el.getAttribute('data-addTo-div'),
1136			extraContainer = el.getAttribute('data-addTo-extra'),
1137			dest_id = el.getAttribute('data-addTo-cartid');
1138
1139		product_id = (cart_type == 'cart') ? el.getAttribute('data-addToCart') : el.getAttribute('data-addToWishlist');
1140		dest_id = (dest_id ? parseInt(dest_id) : 0);
1141		if(!url)
1142			url = el.getAttribute('data-href');
1143
1144		// Avoid bots and crawlers to add products in the cart
1145		var r = /bot|googlebot|crawler|spider|robot|crawling/i;
1146		if(navigator && navigator.userAgent && r.test(navigator.userAgent))
1147			return false;
1148
1149		var process = true;
1150		window.Oby.fireAjax(cart_type+'-button.clicked', {el: el, product_id: product_id, type: cart_type, cart_id: dest_id, process: process});
1151		if(!process)
1152			return true;
1153
1154		// No product ID - fallback mode
1155		if(!product_id || !url) {
1156			if(containerName && d.forms[containerName]) {
1157				d.forms[containerName].submit();
1158				return false;
1159			}
1160			return true;
1161		}
1162
1163		if(typeof container !== 'undefined') {
1164			// container is provided, just use it
1165		}else if(containerName && product_id) {
1166			// search for the container on the page
1167			container = d.forms['hikashop_product_form_' + product_id + '_' + containerName] || d.forms[containerName];
1168		}
1169
1170		url += (url.indexOf('?') >= 0 ? '&' : '?') + 'tmpl=raw';
1171		if(typeof data !== 'undefined') {
1172		} else if(container) {
1173			if(window.FormData)
1174				data = new FormData(container);
1175			else
1176				data = o.getFormData(container);
1177			if(extraContainer) {
1178				extraContainer = d.forms[extraContainer] || d.getElementById(extraContainer);
1179				if(window.FormData) {
1180					extra = o.getFormData(extraContainer, false);
1181					for(var k in extra) {
1182						if(!extra.hasOwnProperty(k))
1183							continue;
1184						if(k == 'product_id')
1185							extra[k] = product_id;
1186						if(typeof(extra[k]) == 'object') {
1187							for(var i in extra[k]) {
1188								data.append(k, extra[k][i]);
1189							}
1190						} else
1191							data.append(k, extra[k]);
1192					}
1193				} else {
1194					var extra = o.getFormData(extraContainer);
1195					if(extra)
1196						data += '&' + extra;
1197					data += '&product_id='+product_id;
1198				}
1199			}
1200			if(window.FormData) {
1201				data.append('cart_type', cart_type);
1202				if(dest_id)
1203					data.append('cart_id', dest_id);
1204			} else {
1205				data += '&cart_type=' + cart_type;
1206				if(dest_id)
1207					data += '&cart_id+' + dest_id;
1208			}
1209		} else {
1210			data = 'cart_type=' + cart_type;
1211			if(dest_id)
1212				data += '&cart_id+' + dest_id;
1213		}
1214
1215		var className = el.getAttribute('data-addTo-class');
1216		if(className) o.addClass(el, className);
1217
1218		// if we are in a popup we want the add to cart to happen in the parent frame.
1219		// however, this can cause issues if the website is inside an iframe from another domain so we add a try/catch so that the add to cart can work
1220		if(window.self !== window.top) {
1221			try {
1222				if(window.top.hikashop)
1223					return window.top.hikashop.addToCart(el, type, container, data);
1224			} catch(e) {}
1225		}
1226
1227		o.xRequest(url, {mode:'POST', data: data}, function(xhr) {
1228			var className = el.getAttribute('data-addTo-class');
1229			if(className) o.removeClass(el, className);
1230
1231			var resp = Oby.evalJSON(xhr.responseText);
1232			var cart_id = (resp && (resp.ret || resp.ret === 0)) ? resp.ret : parseInt(xhr.responseText);
1233			if(isNaN(cart_id)) {
1234				console.log('cart_id was not returned in addToCart AJAX call');
1235				console.log(resp);
1236				return false;
1237			}
1238
1239			var triggers = window.Oby.fireAjax(cart_type+'.updated', {id: cart_id, el: el, product_id: product_id, type: cart_type, resp: resp});
1240			if(triggers !== false && triggers.length > 0)
1241				return true;
1242			if(window.localPage && cart_type == 'cart' && window.localPage.cartRedirect && typeof(window.localPage.cartRedirect) == 'function')
1243				return window.localPage.cartRedirect(cart_id, product_id, resp);
1244			if(window.localPage && cart_type == 'wishlist' && window.localPage.
1244wishlistRedirect && typeof(window.localPage.wishlistRedirect) == 'function')
1245				return window.localPage.wishlistRedirect(cart_id, product_id, resp);
1246		});
1247		return false;
1248	},
1249	addToWishlist: function(el) {
1250		return this.addToCart(el, 'wishlist');
1251	},
1252	checkQuantity: function(el) {
1253		var value = parseInt(el.value), old = el.getAttribute('data-hk-qty-old'),
1254			min = parseInt(el.getAttribute('data-hk-qty-min')),
1255			max = parseInt(el.getAttribute('data-hk-qty-max')),
1256			allowZero = el.getAttribute('data-hk-allow-zero') == 'true';
1257		if(old)
1258			old = parseInt(old);
1259		// No values - return
1260		if(isNaN(value)) {
1261			el.value = old || (isNaN(min) ? 1 : min);
1262			return false;
1263		}
1264		if(''+value != el.value)
1265			el.value = value;
1266		if(isNaN(min) || isNaN(max))
1267			return false;
1268		var triggers = window.Oby.fireAjax("quantity.checked", {el:el, value:value, max:max, min:min});
1269		if(
1270			(triggers !== false && triggers.length > 0) ||
1271			(value == 0 && allowZero) ||
1272			((value <= max || max == 0) && value >= min)
1273		) {
1274			// quantity change is ok
1275
1276			// trigger add to cart if the quantity input is synchronized with the cart
1277			var isSynch = document.getElementById(el.id + '_synch');
1278			if(isSynch) {
1279				isSynch.value = value;
1280				var addToCartButton = document.getElementById(el.id + '_add_to_cart_button');
1281				if(addToCartButton) {
1282					addToCartButton.onclick();
1283				}
1284			}
1285			return true;
1286		}
1287		if(max > 0 && value > max) {
1288			el.value = max;
1289			if(hkjQuery.notify) {
1290				this.translate(['QUANTITY_CHANGE_IMPOSSIBLE', 'MAXIMUM_FOR_PRODUCT_IS_X'], function(trans){
1291					hkjQuery(el).notify({title:trans[0],text:trans[1].replace('%s', max), image:'<i class="fa fa-3x fa-exclamation-circle"></i>'},{style:"metro",className:"warning",arrowShow:true,position:"top left"});
1292				});
1293			}
1294		} else if(value < min) {
1295			el.value = min;
1296			if(hkjQuery.notify) {
1297				this.translate(['QUANTITY_CHANGE_IMPOSSIBLE', 'MINIMUM_FOR_PRODUCT_IS_X'], function(trans){
1298					hkjQuery(el).notify({title:trans[0],text:trans[1].replace('%s', min), image:'<i class="fa fa-3x fa-exclamation-circle"></i>'},{style:"metro",className:"warning",arrowShow:true,position:"top left"});
1299				});
1300			}
1301		}
1302		// should not happen ?
1303		return true;
1304	},
1305	translate: function(keys, callback) {
1306		var t = this, trans = {}, missingKeys = [], o = window.Oby;
1307
1308		for(var c = 0; c < keys.length; c++) {
1309			var key = keys[c];
1310			if(!t.translations[key]) {
1311				missingKeys.push(key);
1312			} else {
1313				trans[c] = t.translations[key];
1314			}
1315		}
1316
1317		if(!missingKeys.length) {
1318			callback(trans);
1319			return;
1320		}
1321
1322		if(!t.translations_url) {
1323			console.log('missing translations URL');
1324			return;
1325		}
1326		o.xRequest(t.translations_url, {mode:'POST', data: 'translations=' + missingKeys.join(',')}, function(xhr) {
1327			var resp = o.evalJSON(xhr.responseText);
1328			foundKeys = Object.getOwnPropertyNames(resp);
1329			for(var c = 0; c < foundKeys.length; c++) {
1330				var key = foundKeys[c];
1331				trans[keys.indexOf(key)] = resp[key];
1332				t.translations[key] = resp[key];
1333			}
1334			callback(trans);
1335		});
1336	},
1337	addTrans: function(data) {
1338		for(var k in data) {
1339			if(!data.hasOwnProperty(k)) continue;
1340			this.translations[k] = data[k];
1341		}
1342	},
1343	updateQuantity: function(el, dataInput, mod) {
1344		var d = document, input = el;
1345		if(!el)
1346			return false;
1347		if(dataInput === undefined || !dataInput)
1348			dataInput = el.getAttribute('data-hk-qty-input');
1349		if(d.getElementById(dataInput))
1350			input = d.getElementById(dataInput);
1351		if(mod === undefined || !mod)
1352			mod =  parseInt(el.getAttribute('data-hk-qty-mod'));
1353		if(isNaN(mod) || mod == 0)
1354			mod = 1;
1355		var value = parseInt(input.value);
1356		if(isNaN(value))
1357			value = 0;
1358		input.value = (value + mod);
1359		this.checkQuantity(input);
1360		if(el.tagName.toLowerCase() == 'a')
1361			el.blur();
1362		return false;
1363	},
1364	deleteFromCart: function(el, cart_type, container) {
1365		if(el.processing)
1366			return false;
1367
1368		var d = document, t = this, o = window.Oby,
1369			url = el.getAttribute('href');
1370		if(!cart_type || cart_type === undefined)
1371			cart_type = el.getAttribute('data-cart-type');
1372		if(!cart_type || cart_type == '')
1373			return true;
1374
1375		url += (url.indexOf('?') >= 0 ? '&' : '?') + 'tmpl=raw';
1376		var cart_id = parseInt(el.getAttribute('data-cart-id')),
1377			cart_product_id = parseInt(el.getAttribute('data-cart-product-id'));
1378		if(cart_id === NaN || cart_product_id === NaN)
1379			return true;
1380
1381		if(container && typeof(container) == 'string')
1382			container = d.getElementById(container);
1383
1384		el.processing = true;
1385		if(container)
1386			o.addClass(container, "hikashop_checkout_loading");
1387		var data = 'cart_type=' + cart_type + '&cart_id=' + cart_id + '&cart_product_id=' + cart_product_id;
1388
1389		o.xRequest(url, {mode:'POST', data: data}, function(xhr) {
1390			el.processing = false;
1391			if(container)
1392				o.removeClass(container, "hikashop_checkout_loading");
1393
1394			var resp = Oby.evalJSON(xhr.responseText);
1395			cart_id = (resp && resp.ret) ? resp.ret : ((resp && resp.empty && resp.empty == 'true') ? cart_id : parseInt(xhr.responseText));
1396			if(cart_id === NaN)
1397				return;
1398			resp.cart_product_id = cart_product_id;
1399			resp.quantity = 0;
1400			var params = {id: cart_id, type: cart_type, resp: resp, notify: false};
1401			window.Oby.fireAjax(cart_type+'.updated', params);
1402		});
1403		return false;
1404	},
1405	submitCartModule: function(form, container, cart_type) {
1406		this.formAjaxSubmit(form, container, function(data, params) {
1407			var resp = window.Oby.evalJSON(data);
1408			var cart_id = (resp && resp.ret) ? resp.ret : parseInt(data);
1409			if(cart_id === NaN)
1410				return;
1411			var updatedElements = [];
1412			for (var key of params.keys()) {
1413				if(key.startsWith('item[') && key.endsWith('][cart_product_quantity]')) {
1414					updatedElements.push({ cart_product_id: key.replace('item[', '').replace('][cart_product_quantity]', ''), quantity_requested: params.get(key)});
1415				}
1416			}
1417			window.Oby.fireAjax(cart_type+'.updated', {id: cart_id, type: cart_type, resp: resp, updated_elements: updatedElements, notify: false});
1418		});
1419		return false;
1420	},
1421	formAjaxSubmit: function(form, container, cb) {
1422		var d = document, o = window.Oby,
1423			url = form.action;
1424		if(form.processing)
1425			return false;
1426		if(container && typeof(container) == 'string')
1427			container = d.getElementById(container);
1428		if(window.FormData) {
1429			data = new FormData(form);
1430			data.append('tmpl', 'raw');
1431		} else {
1432			data = o.getFormData(form);
1433			data += '&tmpl=raw';
1434		}
1435		form.processing = true;
1436		if(container)
1437			o.addClass(container, "hikashop_checkout_loading");
1438		o.xRequest(url, {mode:'POST', data: data}, function(xhr) {
1439			form.processing = false;
1440			if(container)
1441				o.removeClass(container, "hikashop_checkout_loading");
1442			if(!cb)
1443				o.updateElem(container, xhr.responseText);
1444			cb(xhr.responseText, data);
1445		});
1446		return false;
1447	},
1448	syncInit : function() {
1449		window.hikashop.noChzn();
1450		window.Oby.registerAjax(['cart.updated'], function(params){
1451			window.hikashop.refreshSync(params);
1452		});
1453		window.Oby.registerAjax(['hkContentChanged'], function(params){
1454			window.Oby.xRequest(window.hikashop.cartInfoUrl, {}, function(xhr) {
1455				var resp = Oby.evalJSON(xhr.responseText);
1456				var params = {resp: resp};
1457				window.hikashop.refreshSync(params);
1458			});
1459		});
1460
1461		window.Oby.registerAjax(['hkCustomFieldChanged'], function(params){
1462			if(params.field_type != 'item')
1463				return;
1464			window.Oby.xRequest(window.hikashop.cartInfoUrl, {}, function(xhr) {
1465				var resp = Oby.evalJSON(xhr.responseText);
1466				var params = {resp: resp};
1467				window.hikashop.refreshSync(params);
1468			});
1469		});
1470
1471		if(window.hikashop.cartInfo) {
1472			var params = {resp: window.hikashop.cartInfo};
1473			window.hikashop.refreshSync(params);
1474		}
1475	},
1476	xRequest: function(url, options, cb, cbError) {
1477		var t = this, xhr = window.Oby.getXHR();
1478		if(!options) options = {};
1479		if(!cb) cb = function(){};
1480		options.mode = options.mode || 'GET';
1481		options.update = options.update || false;
1482		options.replace = options.replace === undefined || options.replace;
1483		xhr.onreadystatechange = function() {
1484			if(xhr.readyState != 4)
1485				return;
1486			if( xhr.status == 200 || (xhr.status == 0 && xhr.responseText > 0) || !cbError ) {
1487				if(cb)
1488					cb(xhr,options.params);
1489				if(options.update)
1490					t.updateElem(options.update, xhr.responseText, options.replace);
1491			} else {
1492				cbError(xhr,options.params);
1493			}
1494		};
1495		xhr.open(options.mode, url, true);
1496		if(options.mode.toUpperCase() == 'POST' && typeof(options.data) == 'string') {
1497			xhr.setRequestHeader("Content-type","application/x-www-form-urlencoded");
1498		}
1499		if(typeof Joomla !== 'undefined' && Joomla && Joomla.getOptions) {
1500			var csrf = Joomla.getOptions("csrf.token", "");
1501			if(csrf) {
1502				xhr.setRequestHeader("X-CSRF-Token", csrf);
1503			}
1504		}
1505		xhr.send( options.data );
1506	},
1507	updateElem: function(elem, data, replace = true) {
1508		var d = document, scripts = [], json = '';
1509		if( typeof(elem) == 'string' )
1510			elem = d.getElementById(elem);
1511
1512		// extract the javascript files and scripts from the HTML
1513		var files = [];
1514		var scriptsAlreadyLoaded = document.getElementsByTagName("script");
1515		var text = data.replace(/<script([^>]*)>([\s\S]*?)<\/script>/gi, function(all, attributes, code){
1516			if(all.indexOf('type="application/json"') != -1) {
1517				json += code + '\n';
1518				return '';
1519			}
1520			if(all.indexOf('type="application/ld+json"') != -1)
1521				return '';
1522
1523			if(all.indexOf('type="importmap"') != -1)
1524				return '';
1525			regex = RegExp('src="([^"]+)"', 'gi');
1526			result = regex.exec(attributes);
1527			if(result) {
1528				result[1] = result[1].replace(/\.js\?[0-9a-f\.]{1,128}/gi, '.js').replace(/&amp;/g, '&');
1529				for(var i = 0; i < scriptsAlreadyLoaded.length; i++) {
1530					var src = scriptsAlreadyLoaded[i].getAttribute('src');
1531					if(src && src.includes(result[1]))
1532						return '';
1533				}
1534				files.push(result[1]);
1535				return '';
1536			}
1537			scripts.push(code.replace('document.addEventListener(\'DOMContentLoaded\',', 'window.hikashop.ready(').replace('document.addEventListener("DOMContentLoaded",', 'window.hikashop.ready(').replace('$(document).ready(', 'window.hikashop.ready(').replace( 'find("select").chosen(', 'find("select").filter(":visible").chosen('));
1538			return '';
1539		});
1540
1541		// add the HTML without the javascript elements to the element on the page
1542		if(text.indexOf('id="hikashop_main_content"')) {
1543			var wrapper = document.createElement('div');
1544			wrapper.innerHTML = text;
1545			var mainArea = wrapper.querySelector('#hikashop_main_content');
1546			if(mainArea) {
1547				if(replace)
1548					elem.innerHTML = '';
1549				elem.appendChild(mainArea);
1550				text = false;
1551			}
1552		}
1553		if(text !== false) {
1554			if(!replace)
1555				elem.insertAdjacentHTML('beforeend',text);
1556			else
1557				elem.innerHTML = text;
1558		}
1559
1560		// add the javascript elements and run them
1561		if( json != '' && Joomla) {
1562			var option = JSON.parse(json);
1563			if (option) {
1564				Joomla.loadOptions(option);
1565			}
1566		}
1567
1568		if(files.length) {
1569			this.loadScripts(files, function() {
1570				window.hikashop.addScript(scripts);
1571			});
1572		} else {
1573			window.hikashop.addScript(scripts);
1574		}
1575	},
1576	addScript: function (code, url) {
1577		if(!code.length)
1578			return;
1579		for(var k=0; k < code.length; k++) {
1580			try {
1581				var oNew = document.createElement("script");
1582				oNew.type = "text/javascript";
1583				oNew.textContent = code[k];
1584				document.getElementsByTagName("head")[0].appendChild(oNew);
1585			} catch (e) {
1586				if (e instanceof SyntaxError) {
1587					console.log(e.message + ' for ' + url);
1588					console.log(code);
1589				}
1590			}
1591		}
1592	},
1593	loadScripts: function(scripts, complete) {
1594		var xhr = window.Oby.getXHR();
1595		var loadScript = function( src ) {
1596			xhr.open("GET", src , true);
1597			xhr.send();
1598		};
1599		xhr.onreadystatechange = function() {
1600			if (xhr.readyState != 4)
1601				return;
1602			if (xhr.status == 200) {
1603				try {
1604					window.hikashop.addScript([xhr.responseText], xhr.responseURL);
1605				} catch (e) {
1606					if (e instanceof SyntaxError) {
1607						console.log(e.message + ' for ' + xhr.responseURL);
1608						console.log(xhr.responseText);
1609					}
1610				}
1611			}
1612			var next = scripts.shift();
1613			if ( next ) {
1614				loadScript(next);
1615			} else if ( typeof complete == 'function' ) {
1616				complete();
1617			}
1618		}
1619		loadScript( scripts.shift() );
1620	},
1621	refreshSync : function(params) {
1622		// the cart is empty so reset all the synched elements and refresh them
1623		if(params.resp.empty) {
1624			synchronizedEls = document.querySelectorAll('.synchronized_add_to_cart');
1625			for(var i=0; i < synchronizedEls.length; i++) {
1626				var el = synchronizedEls[i];
1627				el.value = 0;
1628				el.setAttribute('data-cart-product-id', 0);
1629				var id = el.getAttribute('data-id');
1630				window.hikashop.syncQuantity(id, el.value, el.value);
1631			}
1632		}
1633		// the cart is updated from the cart module
1634		else if(params.resp.products) {
1635			// loop on all the products on the page
1636			var els = document.querySelectorAll('.synchronized_add_to_cart');
1637
1638			if(!els.length)
1639				return;
1640			for(var k=0; k < els.length; k++) {
1641				var el = els[k];
1642				var id = el.getAttribute('data-id');
1643				var productId = el.getAttribute('data-product-id');
1644				var options = [];
1645				if(el.form) {
1646					var optionsTable = el.form.querySelector('.hikashop_product_options_table');
1647					if(optionsTable) {
1648						options = hikaProductOptions.getOptions();
1649					}
1650				}
1651				var found = false;
1652				// see if we have the product in the cart
1653				for(var i=0; i < params.resp.products.length; i++) {
1654					var result = params.resp.products[i];
1655					// get the current quantity from the response of the server and update the quantity for the quantity input of the current loop
1656					if(productId == result.product_id) {
1657						if(options.length || (result.options && result.options.length)) {
1658							// no options selected on the product page or no options selected in the product in the cart -> products are different
1659							if(!options.length || !result.options || !result.options.length)
1660								continue;
1661							var match = true;
1662							// check that both arrays contain the same elements
1663							for(var j=0; j < options.length; j++) {
1664								if(!result.options.includes(options[j])) {
1665									match = false;
1666									break;
1667								}
1668							}
1669							for(var j=0; j < result.options.length; j++) {
1670								if(!options.includes(result.options[j])) {
1671									match = false;
1672									break;
1673								}
1674							}
1675							if(!match)
1676								continue;
1677						}
1678						found = true;
1679						el.value = result.quantity;
1680					}
1681				}
1682				// TODO: add custom item fields
1683				if(!found) {
1684					el.value = 0;
1685					el.setAttribute('data-cart-product-id', 0);
1686				}
1687				window.hikashop.syncQuantity(id, el.value, el.value);
1688			}
1689		}
1690	},
1691	syncQuantity : function(id, qtyInCart, qtyInInput) {
1692		// refresh the quantity in the input field
1693		if(typeof qtyInInput !== 'undefined') {
1694
1695			var inputField = document.getElementById(id+'_select');
1696			if(!inputField)
1697				inputField = document.getElementById(id);
1698			if(inputField) {
1699				if(qtyInInput == 0) {
1700					var minQty = inputField.getAttribute('data-hk-qty-min');
1701					if(minQty == 0)
1702						qtyInInput = 1;
1703					else
1704						qtyInInput = minQty;
1705				}
1706				inputField.value = qtyInInput;
1707			}
1708		}
1709
1710		// update the display of the quantity input field and the buttons
1711		var quantityArea = document.getElementById(id + '_area');
1712		var cartButtonArea = document.getElementById(id + '_add_to_cart_button');
1713		var wishlistButtonArea = document.getElementById(id + '_add_to_wishlist_button');
1714		if(!quantityArea || !cartButtonArea)
1715			return;
1716		if(qtyInCart > 0) {
1717			quantityArea.style.display = '';
1718			cartButtonArea.style.display = 'none';
1719			if(wishlistButtonArea)
1720				wishlistButtonArea.style.display = 'none';
1721		} else {
1722			quantityArea.style.display = 'none';
1723			cartButtonArea.style.display = '';
1724			if(wishlistButtonArea)
1725				wishlistButtonArea.style.display = '';
1726		}
1727	},
1728	toggleOverlayBlock: function(el, type, state) {
1729		var t = this, d = document, w = window, o = w.Oby;
1730		if(typeof(el) == 'string')
1731			el = d.getElementById(el);
1732		if(!el)
1733			return false;
1734		var open = !!el.toggleOpen; // (el.style.display != 'none');
1735		if(type != 'hover' && type != 'toggle' && type != 'drawer')
1736			type = 'click';
1737		if(type == 'drawer') {
1738			if(open)
1739				hkDrawer.closeDrawer(el);
1740			else
1741				hkDrawer.openDrawer(el);
1742			return true;
1743		}
1744		if(type == 'hover' && (!state && open) || (state && !open))
1745			return;
1746		if(jQuery) {
1747			jQuery(el).slideToggle('fast');
1748		} else {
1749			el.style.display = (el.style.display == 'none')?'block':'none';
1750		}
1751		el.toggleOpen = !el.toggleOpen;
1752
1753		if(open) {
1754			if(type == 'hover') {
1755				o.removeEvent(el, "mouseout", el.toggleFunctionHover);
1756				el.toggleFunctionHover = null;
1757			}
1758			if(el.toggleFunction)
1759				o.removeEvent(document, "click", el.toggleFunction);
1760			el.toggleFunction = null;
1761			return true;
1762		}
1763		if(type == 'hover') {
1764			el.toggleFunctionHover = function(event) {
1765				if(event.target && this != event.target)
1766					return false;
1767				window.hikashop.toggleOverlayBlock(el, 'hover', true);
1768			};
1769			if(jQuery) {
1770				jQuery(el).mouseleave(el.toggleFunctionHover);
1771			} else {
1772				o.addEvent(el, "mouseout", el.toggleFunctionHover);
1773			}
1774		}
1775		var f = function(evt) {
1776			if (!evt) var evt = window.event;
1777			var trg = (window.event) ? evt.srcElement : evt.target;
1778			while(trg != null) {
1779				if(trg == el)
1780					return;
1781				trg = trg.parentNode;
1782			}
1783			t.toggleOverlayBlock(el);
1784			o.removeEvent(document, "click", f);
1785			el.toggleFunction = null;
1786		};
1787		el.toggleFunction = f;
1788		setTimeout(function(){ o.addEvent(document, "click", f); }, 100);
1789		return true;
1790	},
1791	addToCompare: function(el) {
1792		var t = this, d = document, w = window, o = w.Oby;
1793		if(!t.compare_list)
1794			t.compare_list = {};
1795
1796		if(el.disabled)
1797			return false;
1798
1799		var product_id = parseInt(el.getAttribute('data-addToCompare')),
1800			product_name = el.getAttribute('data-product-name'),
1801			css = el.getAttribute('data-addTo-class');
1802
1803		if(isNaN(product_id) || product_id <= 0)
1804			return false;
1805		if(!css || css == '')
1806			css = 'hika-compare';
1807
1808		var adding = !t.compare_list.hasOwnProperty(product_id);
1809		if(adding)
1810			t.compare_list[product_id] = product_name;
1811		else
1812			delete t.compare_list[product_id];
1813
1814		var elems = d.querySelectorAll('[data-addToCompare="'+product_id+'"]');
1815		if(elems && elems.forEach) {
1816			elems.forEach(function(e){
1817				if(e.nodeName.toLowerCase() == 'input' && e.type.toLowerCase() == 'checkbox')
1818					e.checked = adding;
1819				if(adding)
1820					o.addClass(e, css);
1821				else
1822					o.removeClass(e, css);
1823			});
1824		}
1825		var size = 0;
1826		if(Object.keys) {
1827			size = Object.keys(t.compare_list).length;
1828		} else {
1829			for(var k in t.compare_list) {
1830				if(compare_list.hasOwnProperty(k))
1831					size++;
1832			}
1833		}
1834		var triggers = window.Oby.fireAjax('compare.updated', {el: el, product_id: product_id, added: adding, list: t.compare_list, size: size});
1835		if(triggers !== false && triggers.length > 0)
1836			return false;
1837		return false;
1838	},
1839	toggleOptions: function() {
1840		var d = document, btnText = d.getElementById('openSearch_btn'),
1841		tagsDiv = d.getElementById('hikashop_listing_filters_id');
1842		if(tagsDiv.classList.contains("hidden-features") ) {
1843			tagsDiv.classList.remove("hidden-features");
1844			tagsDiv.classList.add("show-features");
1845			btnText.innerHTML = "<i class='fas fa-chevron-up'></i>";
1846		} else {
1847			tagsDiv.classList.remove("show-features");
1848			tagsDiv.classList.add("hidden-features");
1849			btnText.innerHTML = "<i class='fas fa-chevron-down'></i>";
1850		}
1851		return false;
1852	},
1853	clearOptions: function(options, defaults) {
1854		var d = document, btnText = d.getElementById('openSearch_btn'),
1855		tagsDiv = d.getElementById('hikashop_listing_filters_id');
1856		if(!options)
1857			return false;
1858		for(var i = options.length - 1; i >= 0; i--) {
1859			var name = 'filter_' + options[i];
1860			var el = d.getElementById(name);
1861			if(!el) {
1862				console.log('Filter option '+name+' not found');
1863				continue;
1864			}
1865			el.value = defaults[i];
1866		}
1867		var	clearEl = document.getElementById('hkclear');
1868		if(clearEl) {
1869			clearEl.value = 1;
1870		}
1871		return true;
1872	},
1873	clearSearch: function(el, id, all) {
1874		if(el.form.limitstart)
1875			el.form.limitstart.value = 0;
1876		var search = document.getElementById(id);
1877		if(search)
1878			search.value = '';
1879		if(all) {
1880			var v, els = el.form.querySelectorAll('[data-search-clear]');
1881			for(var i = els.length - 1; i >= 0; i--) {
1882				v = els[i].getAttribute('data-search-clear');
1883				els[i].value = v;
1884			}
1885		} else
1886			all = false;
1887		var triggers = window.Oby.fireAjax('search.cleared', {el: el, id: id, all: all});
1888		if(triggers !== false && triggers.length > 0)
1889			return false;
1890		el.form.submit();
1891		return true;
1892	},
1893	compareProducts: function(el, elems) {
1894		var t = this, params = '',
1895			url = el.getAttribute('data-compare-href');
1896		if(!url)
1897			return false;
1898		if(!elems)
1899			elems = t.compare_list;
1900		if(!elems)
1901			return false;
1902		for(var k in elems) {
1903			if(!elems.hasOwnProperty)
1904				continue;
1905			if(params != '') params += '&';
1906			params += 'cid[]=' + k;
1907		}
1908		el.href = url + ((url.indexOf('?') >= 0) ? '&' : '?') + params;
1909		return true;
1910	},
1911	toggleField: function(new_value, namekey, field_type, id, prefix, type) {
1912		var d = document, checked = 0, size = 0, obj = null, specialField = false,
1913			checkedGood = [], count = [], el = null,
1914			arr = d.getElementsByName('data['+field_type+']['+namekey+'][]');
1915
1916		// handle when this is passed in new_value
1917		// it allows for better handling of radios and checkboxes
1918		if(new_value instanceof Element) {
1919			if(new_value.type == 'radio' || new_value.type == 'checkbox') {
1920				elements = d.getElementsByName(new_value.name);
1921				for(cpt = 0; cpt < elements.length; cpt++) {
1922					if(elements[cpt].checked) {
1923						new_value = elements[cpt].value;
1924					}
1925				}
1926				if(new_value instanceof Element) {
1927					new_value = '';
1928				}
1929			} else {
1930				new_value = new_value.value;
1931			}
1932		} 
1933		if(!arr)
1934			return false;
1935
1936		if( new_value === null) {
1937			if(d.getElementById(type + namekey))
1938				new_value = d.getElementById(type + namekey).value;
1939			else {
1940				inputs = d.getElementsByName('data['+field_type+']['+namekey+']');
1941				for(var i = inputs.length - 1; i >= 0; i--) {
1942					if(inputs[i].checked)
1943						new_value = inputs[i].value;
1944				}
1945			}
1946		}
1947
1948		if(!this.fields_data && window.hikashopFieldsJs) {
1949			this.fields_data = window.hikashopFieldsJs;
1950		} else {
1951			for(var n in window.hikashopFieldsJs) {
1952				if(!window.hikashopFieldsJs.hasOwnProperty(n)) continue;
1953				if(this.fields_data[n]) continue;
1954				this.fields_data[n] = window.hikashopFieldsJs[n];
1955			}
1956		}
1957		if(this.fields_data === undefined || this.fields_data[field_type] === undefined) {
1958
1959		} else {
1960			size = (arr[0] && arr[0].length !== undefined) ? arr[0].length : arr.length;
1961
1962			if(prefix === undefined || !prefix || prefix.length == 0 || prefix.substr(-1) != '_')
1963				prefix = 'hikashop_';
1964
1965			var elementName = prefix + field_type + '_' + namekey;
1966			if(id)
1967				elementName = elementName + '_' + id;
1968			el = document.getElementById(elementName);
1969			var parentHidden = (el && el.style.display && el.style.display == 'none');
1970
1971			for(var c = 0; c < size; c++) {
1972				if(arr && arr[0] != undefined && arr[0].length != undefined)
1973					obj = d.getElementsByName('data['+field_type+']['+namekey+'][]').item(0).item(c);
1974				else
1975					obj = d.getElementsByName('data['+field_type+']['+namekey+'][]').item(c);
1976
1977				if(obj.checked || obj.selected)
1978					checked++;
1979
1980				if((obj.type && obj.type == 'checkbox') || obj.selected)
1981					specialField = true;
1982			}
1983			var data = this.fields_data[field_type][namekey];
1984
1985			for(var k in data) {
1986				if(typeof data[k] != 'object')
1987					continue;
1988
1989				for(var l in data[k]) {
1990					if(typeof data[k][l] != 'string')
1991						continue;
1992
1993					if (typeof count[k] == 'undefined') {
1994						count[k] = 0;
1995						checkedGood[k] = 0;
1996					}
1997					count[k]++;
1998					newEl = d.getElementById(namekey + '_' + k);
1999					if(newEl && (newEl.checked || newEl.selected)) {
2000						checkedGood[k]++;
2001						break;
2002					}
2003				}
2004			}
2005
2006			specialField = specialField || (arr[0] && arr[0].length && count.length > 1);
2007
2008			for(var j in data) {
2009				if(typeof data[j] != 'object')
2010					continue;
2011				for(var i in data[j]) {
2012					if(typeof data[j][i] != 'string')
2013						continue;
2014
2015					var elementName = prefix + field_type + '_' + data[j][i];
2016					if(id)
2017						elementName = elementName + '_' + id;
2018					el = document.getElementById(elementName);
2019					if(!el)
2020						continue;
2021					var condition = 'IS';
2022					if(data[j]['condition'] && data[j]['condition'][i])
2023						condition = data[j]['condition'][i];
2024					if( condition != 'IS NOT') {
2025						var display = 'none';
2026						var value = '';
2027					} else {
2028						var display = '';
2029						var value = el.value;
2030					}
2031					if(!parentHidden &&
2032						(
2033							(specialField && checkedGood[j] == count[j] && new_value != '')
2034							||
2035							(!specialField &&
2036								(
2037									j == new_value
2038									||
2039									(checkedGood[j] && count[j] && checkedGood[j] == count[j])
2040								)
2041							)
2042						)
2043					) {
2044						if(condition != 'IS NOT') {
2045							display = '';
2046							value = el.value;
2047						} else {
2048							display = 'none';
2049							value = '';
2050						}
2051					}
2052
2053					el.style.display = display;
2054					this.toggleField(value, data[j][i], field_type, id, prefix);
2055				}
2056			}
2057		}
2058		if(window.Oby && window.Oby.fireAjax)
2059			window.Oby.fireAjax("hkCustomFieldChanged", {field_type: field_type, namekey: namekey});
2060		return false;
2061	}
2062};
2063window.hikashop = hikashop;
2064
2065if(oldHikaShop && oldHikaShop instanceof Object) {
2066	for (var attr in oldHikaShop) {
2067		if (oldHikaShop.hasOwnProperty(attr) && !window.hikashop.hasOwnProperty(attr))
2068			window.hikashop[attr] = oldHikaShop[attr];
2069	}
2070}
2071})();
2072
2073function tableOrdering(order, dir, task) {
2074	var form = document.adminForm;
2075	form.filter_order.value = order;
2076	form.filter_order_Dir.value	= dir;
2077	submitform(task);
2078}
2079
2080function submitform(pressbutton) {
2081	var d = document;
2082	if(!d.adminForm)
2083		return false;
2084	if(pressbutton)
2085		d.adminForm.task.value = pressbutton;
2086
2087	// old codeMirror code
2088	if(typeof(CodeMirror) == 'function') {
2089		for(x in CodeMirror.instances) {
2090			d.getElementById(x).value = CodeMirror.instances[x].getCode();
2091		}
2092	}
2093	// Creating the event
2094	var event = new Event('submit', {
2095		'bubbles'    : true, // Whether the event will bubble up through the DOM or not
2096		'cancelable' : true  // Whether the event may be canceled or not
2097	});
2098	if(d.adminForm.dispatchEvent( event )) {
2099		d.adminForm.submit();
2100	}
2101	return false;
2102}
2103
2104if(!window.submitbutton) {
2105	window.submitbutton = function(name) { submitform(name); };
2106}
2107
2108function hikashopCheckChangeForm(type, form) {
2109	if(!form)
2110		return true;
2111	var varform = document[form];
2112
2113	if(typeof(hikashopFieldsJs) == 'undefined' || typeof(hikashopFieldsJs['reqFieldsComp']) == 'undefined' || typeof(hikashopFieldsJs['reqFieldsComp'][type]) == 'undefined' || hikashopFieldsJs['reqFieldsComp'][type].length <= 0)
2114		return true;
2115
2116	var d = document;
2117	for(var i = 0; i < hikashopFieldsJs['reqFieldsComp'][type].length; i++) {
2118		elementName = 'data['+type+']['+hikashopFieldsJs['reqFieldsComp'][type][i]+']';
2119		if(typeof(varform.elements[elementName]) == 'undefined')
2120			elementName = type+'_'+hikashopFieldsJs['reqFieldsComp'][type][i];
2121
2122		elementToCheck = varform.elements[elementName];
2123		elementId = 'hikashop_'+type+'_'+ hikashopFieldsJs['reqFieldsComp'][type][i];
2124		el = d.getElementById(elementId);
2125
2126		if(elementToCheck && (typeof el == 'undefined' || el == null || typeof el.style == 'undefined' || el.style.display!='none') && !hikashopCheckField(elementToCheck,type,i,elementName,varform.elements)) {
2127			if(typeof(hikashopFieldsJs['entry_id']) == 'undefined')
2128				return false;
2129
2130			for(var j = 1; j <= hikashop['entry_id']; j++) {
2131				elementName = 'data['+type+'][entry_'+j+']['+hikashopFieldsJs['reqFieldsComp'][type][i]+']';
2132				elementToCheck = varform.elements[elementName];
2133				elementId = 'hikashop_'+type+'_'+ hikashopFieldsJs['reqFieldsComp'][type][i] + '_' + j;
2134				el = d.getElementById(elementId);
2135				if(elementToCheck && (typeof el == 'undefined' || el == null || typeof el.style == 'undefined' || el.style.display != 'none') && !hikashopCheckField(elementToCheck,type,i,elementName,varform.elements)) {
2136					return false;
2137				}
2138			}
2139		}
2140	}
2141
2142	if(type == 'register') {
2143		// check the password confirmation field only if we are in selector registration and that the user selected "registration" or "simplified registration", or that the registration is on "all in one page" and that the password confirmation field is there
2144		var register = d.getElementById('data_register_registration_method0');
2145		if(!register)
2146			register = d.getElementById('data[register][registration_method]0');
2147
2148		var simplified_pwd = d.getElementById('data_register_registration_method3');
2149		if(!simplified_pwd)
2150			simplified_pwd = d.getElementById('data[register][registration_method]3');
2151
2152		if((simplified_pwd && simplified_pwd.checked) || (register && register.checked) || (!simplified_pwd && !register)) {
2153			// check password
2154			if(typeof(varform.elements['data[register][password]']) != 'undefined' && typeof(varform.elements['data[register][password2]']) != 'undefined') {
2155				passwd = varform.elements['data[register][password]'];
2156				passwd2 = varform.elements['data[register][password2]'];
2157				if(passwd.value != passwd2.value) {
2158					alert(hikashopFieldsJs['password_different']);
2159					return false;
2160				}
2161			}
2162		}
2163
2164		//check email
2165		var emailField = varform.elements['data[register][email]'];
2166		emailField.value = emailField.value.replace(/ /g,"");
2167		var filter = /^([a-z0-9_'&\.\-\+])+\@(([a-z0-9\-])+\.)+([a-z0-9]{2,14})+$/i;
2168		if(!emailField || !filter.test(emailField.value)) {
2169			alert(hikashopFieldsJs['valid_email']);
2170			return false;
2171		}
2172	} else if(type == 'address' && typeof(varform.elements['data[address][address_telephone]']) != 'undefined') {
2173		var phoneField = varform.elements['data[address][address_telephone]'], filter = /[0-9]+/i;
2174		if(phoneField) {
2175			phoneField.value = phoneField.value.replace(/ /g,"");
2176			if(phoneField.value.length > 0 && !filter.test(phoneField.value)) {
2177				alert(hikashopFieldsJs['valid_phone']);
2178				return false;
2179			}
2180		}
2181	}
2182
2183	return true;
2184}
2185
2186function hikashopCheckField(elementToCheck, type, i, elementName, form) {
2187	if(!elementToCheck)
2188		return true;
2189
2190	var d = document, isValid = false;
2191	if(typeof(elementToCheck.value) != 'undefined') {
2192		if(elementToCheck.value == ' ' && typeof(form[elementName+'[]']) != 'undefined') {
2193			if(form[elementName+'[]'].checked) {
2194				isValid = true;
2195			} else {
2196				for(var a = form[elementName+'[]'].length - 1; a >= 0; a--) {
2197					if(form[elementName+'[]'][a].checked && form[elementName+'[]'][a].value.length > 0)
2198						isValid = true;
2199				}
2200			}
2201		} else if(elementToCheck.value.length > 0){
2202			var found = false;
2203			for(var j in hikashopFieldsJs['regexFieldsComp'][type]) {
2204				if(hikashopFieldsJs['regexFieldsComp'][type][j] == hikashopFieldsJs['reqFieldsComp'][type][i]) found = j;
2205			}
2206			if(typeof(hikashopFieldsJs['regexFieldsComp']) != 'undefined' && typeof(hikashopFieldsJs['regexFieldsComp'][type]) != 'undefined' && found){
2207				myregexp = new RegExp(hikashopFieldsJs['regexValueFieldsComp'][type][found]);
2208				if(myregexp.test(elementToCheck.value)){
2209					isValid = true;
2210				}
2211			}else{
2212				isValid = true;
2213			}
2214		}
2215	} else {
2216		for(var a = elementToCheck.length - 1; a >= 0; a--) {
2217			 if(elementToCheck[a].checked && elementToCheck[a].value.length > 0)
2218			 	isValid = true;
2219		}
2220	}
2221
2222	// Case for the switcher display, ignore check according to the method selected
2223	// joomla 3 ids are differents than joomla 1.5...
2224	var simplified_pwd = d.getElementById('data_register_registration_method3');
2225	if(!simplified_pwd) simplified_pwd = d.getElementById('data[register][registration_method]3');
2226
2227	var simplified = d.getElementById('data_register_registration_method1');
2228	if(!simplified) simplified = d.getElementById('data[register][registration_method]1');
2229
2230	var guest = d.getElementById('data_register_registration_method2');
2231	if(!guest) guest = d.getElementById('data[register][registration_method]2');
2232
2233	if(!isValid && ((simplified && simplified.checked) || (guest && guest.checked) ) && (elementName == 'data[register][password]' || elementName == 'data[register][password2]')){
2234		window.Oby.addClass(elementToCheck, 'invalid');
2235		return true;
2236	}
2237
2238	if(!isValid && ( (simplified && simplified.checked) || (guest && guest.checked) || (simplified_pwd && simplified_pwd.checked) ) && (elementName == 'data[register][name]' || elementName == 'data[register][username]')) {
2239		window.Oby.addClass(elementToCheck, 'invalid');
2240		return true;
2241	}
2242	if(!isValid) {
2243		window.Oby.addClass(elementToCheck, 'invalid');
2244		alert(hikashopFieldsJs['validFieldsComp'][type][i]);
2245		return false;
2246	} else {
2247		window.Oby.removeClass(elementToCheck, 'invalid');
2248	}
2249	return true;
2250}
2251
2252window.hikashop.ready(function(){
2253	if(window.jQuery && typeof(jQuery.noConflict) == "function" && !window.hkjQuery) {
2254		window.hkjQuery = jQuery.noConflict();
2255	}
2256	if(window.hikaVotes && typeof(initVote) == 'function')
2257		initVote();
2258	// timeout to make sure that everything is rendered before triggering the height calculations
2259	window.setTimeout(
2260		function(){
2261			window.hikashop.checkConsistency();
2262		},
2263		50
2264	);
2265});
2266if(window.jQuery && typeof(jQuery.noConflict) == "function" && !window.hkjQuery) {
2267	window.hkjQuery = jQuery.noConflict();
2268}

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.