PageSourceSearch

https://skriduklaustur.is/media/com_hikashop/js/hikashop.js?v=516

js skriduklaustur.is collected 2026-09-25 00:04:53 UTC 73,138 bytes, 2,259 lines download raw bytes

1/**
2 * @package    HikaShop for Joomla!
3 * @version    5.1.6
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 += 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(') + '\n';
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 == '')
1578			return;
1579		try {
1580			var oNew = document.createElement("script");
1581			oNew.type = "text/javascript";
1582			oNew.textContent = code;
1583			document.getElementsByTagName("head")[0].appendChild(oNew);
1584		} catch (e) {
1585			if (e instanceof SyntaxError) {
1586				console.log(e.message + ' for ' + url);
1587				console.log(code);
1588			}
1589		}
1590	},	
1591	loadScripts: function(scripts, complete) {
1592		var xhr = window.Oby.getXHR();
1593		var loadScript = function( src ) {
1594			xhr.open("GET", src , true);
1595			xhr.send();
1596		};
1597		xhr.onreadystatechange = function() {
1598			if (xhr.readyState != 4)
1599				return;
1600			if (xhr.status == 200) {
1601				try {
1602					window.hikashop.addScript(xhr.responseText, xhr.responseURL);
1603				} catch (e) {
1604					if (e instanceof SyntaxError) {
1605						console.log(e.message + ' for ' + xhr.responseURL);
1606						console.log(xhr.responseText);
1607					}
1608				}
1609			}
1610			var next = scripts.shift();
1611			if ( next ) {
1612				loadScript(next);
1613			} else if ( typeof complete == 'function' ) {
1614				complete();
1615			}
1616		}
1617		loadScript( scripts.shift() );
1618	},
1619	refreshSync : function(params) {
1620		// the cart is empty so reset all the synched elements and refresh them
1621		if(params.resp.empty) {
1622			synchronizedEls = document.querySelectorAll('.synchronized_add_to_cart');
1623			for(var i=0; i < synchronizedEls.length; i++) {
1624				var el = synchronizedEls[i];
1625				el.value = 0;
1626				el.setAttribute('data-cart-product-id', 0);
1627				var id = el.getAttribute('data-id');
1628				window.hikashop.syncQuantity(id, el.value, el.value);
1629			}
1630		}
1631		// the cart is updated from the cart module
1632		else if(params.resp.products) {
1633			// loop on all the products on the page
1634			var els = document.querySelectorAll('.synchronized_add_to_cart');
1635
1636			if(!els.length)
1637				return;
1638			for(var k=0; k < els.length; k++) {
1639				var el = els[k];
1640				var id = el.getAttribute('data-id');
1641				var productId = el.getAttribute('data-product-id');
1642				var options = [];
1643				if(el.form) {
1644					var optionsTable = el.form.querySelector('.hikashop_product_options_table');
1645					if(optionsTable) {
1646						options = hikaProductOptions.getOptions();
1647					}
1648				}
1649				var found = false;
1650				// see if we have the product in the cart
1651				for(var i=0; i < params.resp.products.length; i++) {
1652					var result = params.resp.products[i];
1653					// get the current quantity from the response of the server and update the quantity for the quantity input of the current loop
1654					if(productId == result.product_id) {
1655						if(options.length || (result.options && result.options.length)) {
1656							// no options selected on the product page or no options selected in the product in the cart -> products are different
1657							if(!options.length || !result.options || !result.options.length)
1658								continue;
1659							var match = true;
1660							// check that both arrays contain the same elements
1661							for(var j=0; j < options.length; j++) {
1662								if(!result.options.includes(options[j])) {
1663									match = false;
1664									break;
1665								}
1666							}
1667							for(var j=0; j < result.options.length; j++) {
1668								if(!options.includes(result.options[j])) {
1669									match = false;
1670									break;
1671								}
1672							}
1673							if(!match)
1674								continue;
1675						}
1676						found = true;
1677						el.value = result.quantity;
1678					}
1679				}
1680				// TODO: add custom item fields
1681				if(!found) {
1682					el.value = 0;
1683					el.setAttribute('data-cart-product-id', 0);
1684				}
1685				window.hikashop.syncQuantity(id, el.value, el.value);
1686			}
1687		}
1688	},
1689	syncQuantity : function(id, qtyInCart, qtyInInput) {
1690		// refresh the quantity in the input field
1691		if(typeof qtyInInput !== 'undefined') {
1692
1693			var inputField = document.getElementById(id+'_select');
1694			if(!inputField)
1695				inputField = document.getElementById(id);
1696			if(inputField) {
1697				if(qtyInInput == 0) {
1698					var minQty = inputField.getAttribute('data-hk-qty-min');
1699					if(minQty == 0)
1700						qtyInInput = 1;
1701					else
1702						qtyInInput = minQty;
1703				}
1704				inputField.value = qtyInInput;
1705			}
1706		}
1707
1708		// update the display of the quantity input field and the buttons
1709		var quantityArea = document.getElementById(id + '_area');
1710		var cartButtonArea = document.getElementById(id + '_add_to_cart_button');
1711		var wishlistButtonArea = document.getElementById(id + '_add_to_wishlist_button');
1712		if(!quantityArea || !cartButtonArea)
1713			return;
1714		if(qtyInCart > 0) {
1715			quantityArea.style.display = '';
1716			cartButtonArea.style.display = 'none';
1717			if(wishlistButtonArea)
1718				wishlistButtonArea.style.display = 'none';
1719		} else {
1720			quantityArea.style.display = 'none';
1721			cartButtonArea.style.display = '';
1722			if(wishlistButtonArea)
1723				wishlistButtonArea.style.display = '';
1724		}
1725	},
1726	toggleOverlayBlock: function(el, type, state) {
1727		var t = this, d = document, w = window, o = w.Oby;
1728		if(typeof(el) == 'string')
1729			el = d.getElementById(el);
1730		if(!el)
1731			return false;
1732		var open = !!el.toggleOpen; // (el.style.display != 'none');
1733		if(type != 'hover' && type != 'toggle')
1734			type = 'click';
1735		if(type == 'hover' && (!state && open) || (state && !open))
1736			return;
1737		if(jQuery) {
1738			jQuery(el).slideToggle('fast');
1739		} else {
1740			el.style.display = (el.style.display == 'none')?'block':'none';
1741		}
1742		el.toggleOpen = !el.toggleOpen;
1743
1744		if(open) {
1745			if(type == 'hover') {
1746				o.removeEvent(el, "mouseout", el.toggleFunctionHover);
1747				el.toggleFunctionHover = null;
1748			}
1749			if(el.toggleFunction)
1750				o.removeEvent(document, "click", el.toggleFunction);
1751			el.toggleFunction = null;
1752			return true;
1753		}
1754		if(type == 'hover') {
1755			el.toggleFunctionHover = function(event) {
1756				if(event.target && this != event.target)
1757					return false;
1758				window.hikashop.toggleOverlayBlock(el, 'hover', true);
1759			};
1760			if(jQuery) {
1761				jQuery(el).mouseleave(el.toggleFunctionHover);
1762			} else {
1763				o.addEvent(el, "mouseout", el.toggleFunctionHover);
1764			}
1765		}
1766		var f = function(evt) {
1767			if (!evt) var evt = window.event;
1768			var trg = (window.event) ? evt.srcElement : evt.target;
1769			while(trg != null) {
1770				if(trg == el)
1771					return;
1772				trg = trg.parentNode;
1773			}
1774			t.toggleOverlayBlock(el);
1775			o.removeEvent(document, "click", f);
1776			el.toggleFunction = null;
1777		};
1778		el.toggleFunction = f;
1779		setTimeout(function(){ o.addEvent(document, "click", f); }, 100);
1780		return true;
1781	},
1782	addToCompare: function(el) {
1783		var t = this, d = document, w = window, o = w.Oby;
1784		if(!t.compare_list)
1785			t.compare_list = {};
1786
1787		if(el.disabled)
1788			return false;
1789
1790		var product_id = parseInt(el.getAttribute('data-addToCompare')),
1791			product_name = el.getAttribute('data-product-name'),
1792			css = el.getAttribute('data-addTo-class');
1793
1794		if(isNaN(product_id) || product_id <= 0)
1795			return false;
1796		if(!css || css == '')
1797			css = 'hika-compare';
1798
1799		var adding = !t.compare_list.hasOwnProperty(product_id);
1800		if(adding)
1801			t.compare_list[product_id] = product_name;
1802		else
1803			delete t.compare_list[product_id];
1804
1805		var elems = d.querySelectorAll('[data-addToCompare="'+product_id+'"]');
1806		if(elems && elems.forEach) {
1807			elems.forEach(function(e){
1808				if(e.nodeName.toLowerCase() == 'input' && e.type.toLowerCase() == 'checkbox')
1809					e.checked = adding;
1810				if(adding)
1811					o.addClass(e, css);
1812				else
1813					o.removeClass(e, css);
1814			});
1815		}
1816		var size = 0;
1817		if(Object.keys) {
1818			size = Object.keys(t.compare_list).length;
1819		} else {
1820			for(var k in t.compare_list) {
1821				if(compare_list.hasOwnProperty(k))
1822					size++;
1823			}
1824		}
1825		var triggers = window.Oby.fireAjax('compare.updated', {el: el, product_id: product_id, added: adding, list: t.compare_list, size: size});
1826		if(triggers !== false && triggers.length > 0)
1827			return false;
1828		return false;
1829	},
1830	toggleOptions: function() {
1831		var d = document, btnText = d.getElementById('openSearch_btn'),
1832		tagsDiv = d.getElementById('hikashop_listing_filters_id');
1833		if(tagsDiv.classList.contains("hidden-features") ) {
1834			tagsDiv.classList.remove("hidden-features");
1835			tagsDiv.classList.add("show-features");
1836			btnText.innerHTML = "<i class='fas fa-chevron-up'></i>";
1837		} else {
1838			tagsDiv.classList.remove("show-features");
1839			tagsDiv.classList.add("hidden-features");
1840			btnText.innerHTML = "<i class='fas fa-chevron-down'></i>";
1841		}
1842		return false;
1843	},
1844	clearOptions: function(options, defaults) {
1845		var d = document, btnText = d.getElementById('openSearch_btn'),
1846		tagsDiv = d.getElementById('hikashop_listing_filters_id');
1847		if(!options)
1848			return false;
1849		for(var i = options.length - 1; i >= 0; i--) {
1850			var name = 'filter_' + options[i];
1851			var el = d.getElementById(name);
1852			if(!el) {
1853				console.log('Filter option '+name+' not found');
1854				continue;
1855			}
1856			el.value = defaults[i];
1857		}
1858		var	clearEl = document.getElementById('hkclear');
1859		if(clearEl) {
1860			clearEl.value = 1;
1861		}
1862		return true;
1863	},
1864	clearSearch: function(el, id, all) {
1865		if(el.form.limitstart)
1866			el.form.limitstart.value = 0;
1867		var search = document.getElementById(id);
1868		if(search)
1869			search.value = '';
1870		if(all) {
1871			var v, els = el.form.querySelectorAll('[data-search-clear]');
1872			for(var i = els.length - 1; i >= 0; i--) {
1873				v = els[i].getAttribute('data-search-clear');
1874				els[i].value = v;
1875			}
1876		} else
1877			all = false;
1878		var triggers = window.Oby.fireAjax('search.cleared', {el: el, id: id, all: all});
1879		if(triggers !== false && triggers.length > 0)
1880			return false;
1881		el.form.submit();
1882		return true;
1883	},
1884	compareProducts: function(el, elems) {
1885		var t = this, params = '',
1886			url = el.getAttribute('data-compare-href');
1887		if(!url)
1888			return false;
1889		if(!elems)
1890			elems = t.compare_list;
1891		if(!elems)
1892			return false;
1893		for(var k in elems) {
1894			if(!elems.hasOwnProperty)
1895				continue;
1896			if(params != '') params += '&';
1897			params += 'cid[]=' + k;
1898		}
1899		el.href = url + ((url.indexOf('?') >= 0) ? '&' : '?') + params;
1900		return true;
1901	},
1902	toggleField: function(new_value, namekey, field_type, id, prefix, type) {
1903		var d = document, checked = 0, size = 0, obj = null, specialField = false,
1904			checkedGood = [], count = [], el = null,
1905			arr = d.getElementsByName('data['+field_type+']['+namekey+'][]');
1906
1907		// handle when this is passed in new_value
1908		// it allows for better handling of radios and checkboxes
1909		if(new_value instanceof Element) {
1910			if(new_value.type == 'radio' || new_value.type == 'checkbox') {
1911				elements = d.getElementsByName(new_value.name);
1912				for(cpt = 0; cpt < elements.length; cpt++) {
1913					if(elements[cpt].checked) {
1914						new_value = elements[cpt].value;
1915					}
1916				}
1917				if(new_value instanceof Element) {
1918					new_value = '';
1919				}
1920			} else {
1921				new_value = new_value.value;
1922			}
1923		} 
1924		if(!arr)
1925			return false;
1926
1927		if( new_value === null) {
1928			if(d.getElementById(type + namekey))
1929				new_value = d.getElementById(type + namekey).value;
1930			else {
1931				inputs = d.getElementsByName('data['+field_type+']['+namekey+']');
1932				for(var i = inputs.length - 1; i >= 0; i--) {
1933					if(inputs[i].checked)
1934						new_value = inputs[i].value;
1935				}
1936			}
1937		}
1938
1939		if(!this.fields_data && window.hikashopFieldsJs) {
1940			this.fields_data = window.hikashopFieldsJs;
1941		} else {
1942			for(var n in window.hikashopFieldsJs) {
1943				if(!window.hikashopFieldsJs.hasOwnProperty(n)) continue;
1944				if(this.fields_data[n]) continue;
1945				this.fields_data[n] = window.hikashopFieldsJs[n];
1946			}
1947		}
1948		if(this.fields_data === undefined || this.fields_data[field_type] === undefined) {
1949
1950		} else {
1951			size = (arr[0] && arr[0].length !== undefined) ? arr[0].length : arr.length;
1952
1953			if(prefix === undefined || !prefix || prefix.length == 0 || prefix.substr(-1) != '_')
1954				prefix = 'hikashop_';
1955
1956			var elementName = prefix + field_type + '_' + namekey;
1957			if(id)
1958				elementName = elementName + '_' + id;
1959			el = document.getElementById(elementName);
1960			var parentHidden = (el && el.style.display && el.style.display == 'none');
1961
1962			for(var c = 0; c < size; c++) {
1963				if(arr && arr[0] != undefined && arr[0].length != undefined)
1964					obj = d.getElementsByName('data['+field_type+']['+namekey+'][]').item(0).item(c);
1965				else
1966					obj = d.getElementsByName('data['+field_type+']['+namekey+'][]').item(c);
1967
1968				if(obj.checked || obj.selected)
1969					checked++;
1970
1971				if((obj.type && obj.type == 'checkbox') || obj.selected)
1972					specialField = true;
1973			}
1974			var data = this.fields_data[field_type][namekey];
1975
1976			for(var k in data) {
1977				if(typeof data[k] != 'object')
1978					continue;
1979
1980				for(var l in data[k]) {
1981					if(typeof data[k][l] != 'string')
1982						continue;
1983
1984					if (typeof count[k] == 'undefined') {
1985						count[k] = 0;
1986						checkedGood[k] = 0;
1987					}
1988					count[k]++;
1989					newEl = d.getElementById(namekey + '_' + k);
1990					if(newEl && (newEl.checked || newEl.selected)) {
1991						checkedGood[k]++;
1992						break;
1993					}
1994				}
1995			}
1996
1997			specialField = specialField || (arr[0] && arr[0].length && count.length > 1);
1998
1999			for(var j in data) {
2000				if(typeof data[j] != 'object')
2001					continue;
2002				for(var i in data[j]) {
2003					if(typeof data[j][i] != 'string')
2004						continue;
2005
2006					var elementName = prefix + field_type + '_' + data[j][i];
2007					if(id)
2008						elementName = elementName + '_' + id;
2009					el = document.getElementById(elementName);
2010					if(!el)
2011						continue;
2012					var condition = 'IS';
2013					if(data[j]['condition'] && data[j]['condition'][i])
2014						condition = data[j]['condition'][i];
2015					if( condition != 'IS NOT') {
2016						var display = 'none';
2017						var value = '';
2018					} else {
2019						var display = '';
2020						var value = el.value;
2021					}
2022					if(!parentHidden &&
2023						(
2024							(specialField && checkedGood[j] == count[j] && new_value != '')
2025							||
2026							(!specialField &&
2027								(
2028									j == new_value
2029									||
2030									(checkedGood[j] && count[j] && checkedGood[j] == count[j])
2031								)
2032							)
2033						)
2034					) {
2035						if(condition != 'IS NOT') {
2036							display = '';
2037							value = el.value;
2038						} else {
2039							display = 'none';
2040							value = '';
2041						}
2042					}
2043
2044					el.style.display = display;
2045					this.toggleField(value, data[j][i], field_type, id, prefix);
2046				}
2047			}
2048		}
2049		if(window.Oby && window.Oby.fireAjax)
2050			window.Oby.fireAjax("hkCustomFieldChanged", {field_type: field_type, namekey: namekey});
2051		return false;
2052	}
2053};
2054window.hikashop = hikashop;
2055
2056if(oldHikaShop && oldHikaShop instanceof Object) {
2057	for (var attr in oldHikaShop) {
2058		if (oldHikaShop.hasOwnProperty(attr) && !window.hikashop.hasOwnProperty(attr))
2059			window.hikashop[attr] = oldHikaShop[attr];
2060	}
2061}
2062})();
2063
2064function tableOrdering(order, dir, task) {
2065	var form = document.adminForm;
2066	form.filter_order.value = order;
2067	form.filter_order_Dir.value	= dir;
2068	submitform(task);
2069}
2070
2071function submitform(pressbutton) {
2072	var d = document;
2073	if(!d.adminForm)
2074		return false;
2075	if(pressbutton)
2076		d.adminForm.task.value = pressbutton;
2077
2078	// old codeMirror code
2079	if(typeof(CodeMirror) == 'function') {
2080		for(x in CodeMirror.instances) {
2081			d.getElementById(x).value = CodeMirror.instances[x].getCode();
2082		}
2083	}
2084	// Creating the event
2085	var event = new Event('submit', {
2086		'bubbles'    : true, // Whether the event will bubble up through the DOM or not
2087		'cancelable' : true  // Whether the event may be canceled or not
2088	});
2089	if(d.adminForm.dispatchEvent( event )) {
2090		d.adminForm.submit();
2091	}
2092	return false;
2093}
2094
2095if(!window.submitbutton) {
2096	window.submitbutton = function(name) { submitform(name); };
2097}
2098
2099function hikashopCheckChangeForm(type, form) {
2100	if(!form)
2101		return true;
2102	var varform = document[form];
2103
2104	if(typeof(hikashopFieldsJs) == 'undefined' || typeof(hikashopFieldsJs['reqFieldsComp']) == 'undefined' || typeof(hikashopFieldsJs['reqFieldsComp'][type]) == 'undefined' || hikashopFieldsJs['reqFieldsComp'][type].length <= 0)
2105		return true;
2106
2107	var d = document;
2108	for(var i = 0; i < hikashopFieldsJs['reqFieldsComp'][type].length; i++) {
2109		elementName = 'data['+type+']['+hikashopFieldsJs['reqFieldsComp'][type][i]+']';
2110		if(typeof(varform.elements[elementName]) == 'undefined')
2111			elementName = type+'_'+hikashopFieldsJs['reqFieldsComp'][type][i];
2112
2113		elementToCheck = varform.elements[elementName];
2114		elementId = 'hikashop_'+type+'_'+ hikashopFieldsJs['reqFieldsComp'][type][i];
2115		el = d.getElementById(elementId);
2116
2117		if(elementToCheck && (typeof el == 'undefined' || el == null || typeof el.style == 'undefined' || el.style.display!='none') && !hikashopCheckField(elementToCheck,type,i,elementName,varform.elements)) {
2118			if(typeof(hikashopFieldsJs['entry_id']) == 'undefined')
2119				return false;
2120
2121			for(var j = 1; j <= hikashop['entry_id']; j++) {
2122				elementName = 'data['+type+'][entry_'+j+']['+hikashopFieldsJs['reqFieldsComp'][type][i]+']';
2123				elementToCheck = varform.elements[elementName];
2124				elementId = 'hikashop_'+type+'_'+ hikashopFieldsJs['reqFieldsComp'][type][i] + '_' + j;
2125				el = d.getElementById(elementId);
2126				if(elementToCheck && (typeof el == 'undefined' || el == null || typeof el.style == 'undefined' || el.style.display != 'none') && !hikashopCheckField(elementToCheck,type,i,elementName,varform.elements)) {
2127					return false;
2128				}
2129			}
2130		}
2131	}
2132
2133	if(type == 'register') {
2134		// 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
2135		var register = d.getElementById('data_register_registration_method0');
2136		if(!register)
2137			register = d.getElementById('data[register][registration_method]0');
2138
2139		var simplified_pwd = d.getElementById('data_register_registration_method3');
2140		if(!simplified_pwd)
2141			simplified_pwd = d.getElementById('data[register][registration_method]3');
2142
2143		if((simplified_pwd && simplified_pwd.checked) || (register && register.checked) || (!simplified_pwd && !register)) {
2144			// check password
2145			if(typeof(varform.elements['data[register][password]']) != 'undefined' && typeof(varform.elements['data[register][password2]']) != 'undefined') {
2146				passwd = varform.elements['data[register][password]'];
2147				passwd2 = varform.elements['data[register][password2]'];
2148				if(passwd.value != passwd2.value) {
2149					alert(hikashopFieldsJs['password_different']);
2150					return false;
2151				}
2152			}
2153		}
2154
2155		//check email
2156		var emailField = varform.elements['data[register][email]'];
2157		emailField.value = emailField.value.replace(/ /g,"");
2158		var filter = /^([a-z0-9_'&\.\-\+])+\@(([a-z0-9\-])+\.)+([a-z0-9]{2,14})+$/i;
2159		if(!emailField || !filter.test(emailField.value)) {
2160			alert(hikashopFieldsJs['valid_email']);
2161			return false;
2162		}
2163	} else if(type == 'address' && typeof(varform.elements['data[address][address_telephone]']) != 'undefined') {
2164		var phoneField = varform.elements['data[address][address_telephone]'], filter = /[0-9]+/i;
2165		if(phoneField) {
2166			phoneField.value = phoneField.value.replace(/ /g,"");
2167			if(phoneField.value.length > 0 && !filter.test(phoneField.value)) {
2168				alert(hikashopFieldsJs['valid_phone']);
2169				return false;
2170			}
2171		}
2172	}
2173
2174	return true;
2175}
2176
2177function hikashopCheckField(elementToCheck, type, i, elementName, form) {
2178	if(!elementToCheck)
2179		return true;
2180
2181	var d = document, isValid = false;
2182	if(typeof(elementToCheck.value) != 'undefined') {
2183		if(elementToCheck.value == ' ' && typeof(form[elementName+'[]']) != 'undefined') {
2184			if(form[elementName+'[]'].checked) {
2185				isValid = true;
2186			} else {
2187				for(var a = form[elementName+'[]'].length - 1; a >= 0; a--) {
2188					if(form[elementName+'[]'][a].checked && form[elementName+'[]'][a].value.length > 0)
2189						isValid = true;
2190				}
2191			}
2192		} else if(elementToCheck.value.length > 0){
2193			var found = false;
2194			for(var j in hikashopFieldsJs['regexFieldsComp'][type]) {
2195				if(hikashopFieldsJs['regexFieldsComp'][type][j] == hikashopFieldsJs['reqFieldsComp'][type][i]) found = j;
2196			}
2197			if(typeof(hikashopFieldsJs['regexFieldsComp']) != 'undefined' && typeof(hikashopFieldsJs['regexFieldsComp'][type]) != 'undefined' && found){
2198				myregexp = new RegExp(hikashopFieldsJs['regexValueFieldsComp'][type][found]);
2199				if(myregexp.test(elementToCheck.value)){
2200					isValid = true;
2201				}
2202			}else{
2203				isValid = true;
2204			}
2205		}
2206	} else {
2207		for(var a = elementToCheck.length - 1; a >= 0; a--) {
2208			 if(elementToCheck[a].checked && elementToCheck[a].value.length > 0)
2209			 	isValid = true;
2210		}
2211	}
2212
2213	// Case for the switcher display, ignore check according to the method selected
2214	// joomla 3 ids are differents than joomla 1.5...
2215	var simplified_pwd = d.getElementById('data_register_registration_method3');
2216	if(!simplified_pwd) simplified_pwd = d.getElementById('data[register][registration_method]3');
2217
2218	var simplified = d.getElementById('data_register_registration_method1');
2219	if(!simplified) simplified = d.getElementById('data[register][registration_method]1');
2220
2221	var guest = d.getElementById('data_register_registration_method2');
2222	if(!guest) guest = d.getElementById('data[register][registration_method]2');
2223
2224	if(!isValid && ((simplified && simplified.checked) || (guest && guest.checked) ) && (elementName == 'data[register][password]' || elementName == 'data[register][password2]')){
2225		window.Oby.addClass(elementToCheck, 'invalid');
2226		return true;
2227	}
2228
2229	if(!isValid && ( (simplified && simplified.checked) || (guest && guest.checked) || (simplified_pwd && simplified_pwd.checked) ) && (elementName == 'data[register][name]' || elementName == 'data[register][username]')) {
2230		window.Oby.addClass(elementToCheck, 'invalid');
2231		return true;
2232	}
2233	if(!isValid) {
2234		window.Oby.addClass(elementToCheck, 'invalid');
2235		alert(hikashopFieldsJs['validFieldsComp'][type][i]);
2236		return false;
2237	} else {
2238		window.Oby.removeClass(elementToCheck, 'invalid');
2239	}
2240	return true;
2241}
2242
2243window.hikashop.ready(function(){
2244	if(window.jQuery && typeof(jQuery.noConflict) == "function" && !window.hkjQuery) {
2245		window.hkjQuery = jQuery.noConflict();
2246	}
2247	if(window.hikaVotes && typeof(initVote) == 'function')
2248		initVote();
2249	// timeout to make sure that everything is rendered before triggering the height calculations
2250	window.setTimeout(
2251		function(){
2252			window.hikashop.checkConsistency();
2253		},
2254		50
2255	);
2256});
2257if(window.jQuery && typeof(jQuery.noConflict) == "function" && !window.hkjQuery) {
2258	window.hkjQuery = jQuery.noConflict();
2259}

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.