(function() {
	var _rx1 = new RegExp('<script[^>]*>([\\S\\s]*?)<\/script>', 'img');
	var _rx2 = new RegExp('<script[^>]*>([\\S\\s]*?)<\/script>', 'im');
	
	var rclass = /[\n\t]/g,
		rspace = /\s+/,
		rreturn = /\r/g,
		rspecialurl = /href|src|style/,
		rtype = /(button|input)/i,
		rfocusable = /(button|input|object|select|textarea)/i,
		rclickable = /^(a|area)$/i,
		rradiocheck = /radio|checkbox/;
	
	$.fn.extend({
		val: function( value ) {
			if ( value === undefined ) {
				var elem = this[0];
				
				if ( elem ) {
					if ( jQuery.nodeName( elem, "option" ) ) {
						return (elem.attributes.value || {}).specified ? elem.value : elem.text;
					}
					
					// We need to handle select boxes special
					if ( jQuery.nodeName( elem, "select" ) ) {
						var index = elem.selectedIndex,
							values = [],
							options = elem.options,
							one = elem.type === "select-one";
						
						// Nothing was selected
						if ( index < 0 ) {
							return null;
						}
						
						// Loop through all the selected options
						for ( var i = one ? index : 0, max = one ? index + 1 : options.length; i < max; i++ ) {
							var option = options[ i ];
	
							if ( option.selected ) {
								// Get the specifc value for the option
								value = jQuery(option).val();
	
								// We don't need an array for one selects
								if ( one ) {
									return value;
								}
	
								// Multi-Selects return an array
								values.push( value );
							}
						}
	
						return values;
					}
	
					// Handle the case where in Webkit "" is returned instead of "on" if a value isn't specified
					if ( rradiocheck.test( elem.type ) && !jQuery.support.checkOn ) {
						return elem.getAttribute("value") === null ? "on" : elem.value;
					}
					
					if (elem.type == 'button' && jQuery(elem).hasClass('shop-checkbox')) {
						return (elem._value || "").replace(rreturn, "");
					}
					
					// Everything else, we just grab the value
					return (elem.value || "").replace(rreturn, "");
	
				}
	
				return undefined;
			}
	
			var isFunction = jQuery.isFunction(value);
	
			return this.each(function(i) {
				var self = jQuery(this), val = value;
	
				if ( this.nodeType !== 1 ) {
					return;
				}
	
				if ( isFunction ) {
					val = value.call(this, i, self.val());
				}
	
				// Typecast each time if the value is a Function and the appended
				// value is therefore different each time.
				if ( typeof val === "number" ) {
					val += "";
				}
	
				if ( jQuery.isArray(val) && rradiocheck.test( this.type ) ) {
					this.checked = jQuery.inArray( self.val(), val ) >= 0;
	
				} else if ( jQuery.nodeName( this, "select" ) ) {
					var values = jQuery.makeArray(val);
	
					jQuery( "option", this ).each(function() {
						this.selected = jQuery.inArray( jQuery(this).val(), values ) >= 0;
					});
	
					if ( !values.length ) {
						this.selectedIndex = -1;
					}
	
				} else {
					this.value = val;
				}
			});
		}

	});
	
	$.fn.extend({
		popup: function(url) {
			$('.shop-popup').popdown();
			var popupbg = $('#shop-popupbg');
			if (popupbg.length === 0) {
				$('body').append('<div id="shop-popupbg"></div>');
				popupbg = $('#shop-popupbg');
			}
			
			popupbg.show();
			if (url) {
				return this.each(function() {
					var self = $(this);
					$('body').append(self);
					$.ajax({
						url: url, 
						error: function() {
							self.popdown();
						},
						success: function(content) {
							$.removeUpdaterEvents();
							$.evalScripts(content);
							self.find('.shop-popup-content').html(content);
							$.updateEvents();
							self.show().find('.shop-popup-icon-close,.shop-popup-closer').bind('click', function(event) {
								event.stopPropagation();
								event.preventDefault();
								self.popdown();
							});
						}
					});
				});
			} else {
				return this.each(function() {
					var self = $(this);
					$('body').append(self);
					self.show().find('.shop-popup-icon-close,.shop-popup-closer').bind('click', function(event) {
						event.stopPropagation();
						event.preventDefault();
						self.popdown();
					});
				});
			}
		},
		
		simple_popup: function() {
			$('.shop-popup').popdown();
			return this.each(function() {
				var self = $(this);
				self.show().find('.shop-popup-icon-close,.shop-popup-closer').bind('click', function(event) {
					event.stopPropagation();
					event.preventDefault();
					self.popdown();
				});
			});
		},
		
		popdown: function() {
			$('#shop-popupbg').hide();
			return this.each(function() {
				$(this).hide().find('.shop-popup-icon-close,.shop-popup-closer').unbind('click');
			});
		}
	});
	
	$.evalScripts = function(s) {
		var list = [];
		for (var i = 0, a = s.match(_rx1) || [], l = a.length; i < l; i++) {
			list.push(eval((a[i].match(_rx2) || ['', ''])[1]));
		}
		
		return list;
	};
	
	$.hasFlash = function() {
		// look for a flag in the query string to bypass flash detection
		var pv = $.hasFlash.playerVersion().match(/\d+/g);
		var rv = String([arguments[0], arguments[1], arguments[2]]).match(/\d+/g) || String($.pluginOptions.version).match(/\d+/g);
		for(var i = 0; i < 3; i++) {
			pv[i] = parseInt(pv[i] || 0);
			rv[i] = parseInt(rv[i] || 0);
			// player is less than required
			if(pv[i] < rv[i]) return false;
			// player is greater than required
			if(pv[i] > rv[i]) return true;
		}
		// major version, minor version and revision match exactly
		return true;
	};
	
	$.hasFlash.playerVersion = function() {
		// ie
		try {
			try {
				// avoid fp6 minor version lookup issues
				// see: http://blog.deconcept.com/2006/01/11/getvariable-setvariable-crash-internet-explorer-flash-6/
				var axo = new ActiveXObject('ShockwaveFlash.ShockwaveFlash.6');
				try { axo.AllowScriptAccess = 'always';	} 
				catch(e) { return '6,0,0'; }				
			} catch(e) {}
			return new ActiveXObject('ShockwaveFlash.ShockwaveFlash').GetVariable('$version').replace(/\D+/g, ',').match(/^,?(.+),?$/)[1];
		// other browsers
		} catch(e) {
			try {
				if(navigator.mimeTypes["application/x-shockwave-flash"].enabledPlugin){
					return (navigator.plugins["Shockwave Flash 2.0"] || navigator.plugins["Shockwave Flash"]).description.replace(/\D+/g, ",").match(/^,?(.+),?$/)[1];
				}
			} catch(e) {}		
		}
		return '0,0,0';
	};
	
	if ($.browser.msie) {
		$.focused = function() {
			return document.activeElement;
		};
	} else if (document.activeElement) {
		$.focused = function() {
			return document.activeElement;
		};
	} else {
		var focusedElement = null;
		
		$('a, :input').live('focus', function() {
			focusedElement = this;
		});
		$('a, :input').live('blur', function() {
			focusedElement = null;
		});
		
		$.focused = function() {
			return focusedElement;
		};
	}
	
	var registeredUpdaters = [];
	$.updateEvents = function() {
		for (var i = 0, l = registeredUpdaters.length; i < l; i++) {
			//var x = new Date()-1;
			registeredUpdaters[i]();
			//console.log(new Date()-1 - x);
			//console.log(registeredUpdaters[i]);
		}
	};
	
	$.attachUpdater = function(updater) {
		registeredUpdaters.push(updater);
	};
	
	$.removeUpdaterEvents = function() {
		//var x = new Date()-1;
		$('*').unbind('.update');
		//console.log(new Date()-1 - x);
	};
	
	$.attachUpdater(function() {
		$('form.shop-form-enter:not(:has(input.shop-invisible-submit))').each(function() {
			var input = document.createElement('input');
			input.type = 'submit';
			input.name = '';
			input.value = '';
			input.className = 'shop-invisible-submit';
			this.appendChild(input);
		});
		
		$('input.shop-labeled-input').bind('focus.update', function(event) {
			if (this.title) {
				if (this.value == this.title) this.value = '';
			} else {
				if (this.value == this.defaultValue) this.value = '';
			}
		}).bind('blur.update', function() {
			if (this.title) {
				if ($.trim(this.value) == '') this.value = this.title;
			} else {
				if ($.trim(this.value) == '') this.value = this.defaultValue;
			}
		}).each(function() {
			if (this.title && this.value == '') this.value = this.title;
		});
		
		$('form').bind('reset.update', function(event) {
			$('input.shop-checkbox-checked', this).each(function() {
				this.checked = false;
				$(this).removeClass('shop-checkbox-checked').trigger('change');
			});
		}).find('a.shop-form-reset').bind('click.update', function(event) {
			event.preventDefault();
			event.stopPropagation();
			$(this).closest('form').get(0).reset();
		}).end().filter(':has(input.shop-labeled-input)').bind('submit.update', function(event) {
			$(this).find('input.shop-labeled-input').each(function() {
				if ((this.title && this.value == this.title) || this.value == this.defaultValue) this.value = '';
			});
		});
		
		$('a.shop-form-submit').bind('click.update', function(event) {
			event.preventDefault();
			event.stopPropagation();
			$($(this).attr('href')).submit();
		});
		
		$('a.shop-itemlist-item-toggler').bind('click.update', function(event) {
			event.preventDefault();
			event.stopPropagation();
			var self = $(this);
			self.hide().siblings('a.shop-itemlist-item-toggler').show();
			var ok = null;
			var hide = null;
			var o = self.closest('tr');
			o.parent().children('tr').each(function() {
				if (ok === null && this == o.get(0)) {
					ok = true;
				} else if (ok) {
					var tr = $(this);
					if (tr.find('td.shop-itemlist-subposition').length) {
						if (hide === null) {
							hide = tr.is(':visible');
						}
						tr[hide ? 'hide' : 'show']();
					} else {
						ok = false;
					}
				}
			});
		});
		
		$('div.shop-object-selection').each(function() {
			var self = $(this);
			self.find('a.shop-object-selector').bind('click.update', function(event) {
				event.preventDefault();
				event.stopPropagation();
				$('#' + $(this).attr('href').split('#').pop()).popup('/objects/select').get(0).target = self;
			});
		});
		
		$('table.shop-object-select>tbody>tr').bind('click.update', function(event) {
			var self = $(this);
			self.closest('div.shop-popup')
				.popdown()
				.get(0)
				.target
				.find('.shop-object-select-text').text(self.attr('title')).trigger('change').show().end()
				.find('.shop-object-select-id').val(self.attr('id').split('-')[1]).trigger('change');
		});
		
		$('a.shop-object-selection-resetter').bind('click.update', function(event) {
			event.preventDefault();
			event.stopPropagation();
			var self = $(this);
			self.closest('div.shop-popup')
				.popdown()
				.get(0)
				.target
				.find('.shop-object-select-text').text('').trigger('change').hide().end()
				.find('.shop-object-select-id').val('').trigger('change');
		});
		
		$('div.shop-project-selection').each(function() {
			var self = $(this);
			self.find('input.shop-project-select-text').bind('click.update', function(event) {
				event.preventDefault();
				event.stopPropagation();
				$('#' + $(this).attr('id').split('#').pop()).popup('/projects/project_selector').get(0).target = self;
			});
		});
		
		$('table.shop-project-select>tbody>tr').bind('click.update', function(event) {
			var self = $(this);
			self.closest('div.shop-popup').popdown();
			$('#orders-reset-project').show();
			$('div.shop-project-selection')
				.find('.shop-project-select-text').addClass('bd').html(self.attr('title')).end()
				.find('.shop-project-select-id').val(self.attr('id').split('-')[1]).trigger('change');
		});
		
		$('a.shop-project-selection-resetter').bind('click.update', function(event) {
			event.preventDefault();
			event.stopPropagation();
			var self = $(this);
			$('#orders-reset-project').hide();
			self.closest('div.shop-popup').popdown();
			$('div.shop-project-selection')	
				.find('.shop-project-select-text').html('').end()
				.find('.shop-project-select-id').val('').trigger('change');
		});
		
		$('div.shop-association-selection').each(function() {
			var self = $(this);
			self.find('a.shop-association-selector').bind('click.update', function(event) {
				event.preventDefault();
				event.stopPropagation();
				$('#' + $(this).attr('href').split('#').pop()).popup('/associations/select').get(0).target = self;
			});
		});
		
		$('table.shop-association-select>tbody>tr').bind('click.update', function(event) {
			var self = $(this);
			self.closest('div.shop-popup')
				.popdown()
				.get(0)
				.target
				.find('.shop-association-select-text').text(self.attr('title')).trigger('change').show().end()
				.find('.shop-association-select-id').val(self.attr('id').split('-')[1]).trigger('change');
		});
		
		$('a.shop-association-selection-resetter').bind('click.update', function(event) {
			event.preventDefault();
			event.stopPropagation();
			var self = $(this);
			self.closest('div.shop-popup')
				.popdown()
				.get(0)
				.target
				.find('.shop-association-select-text').text('').trigger('change').hide().end()
				.find('.shop-association-select-id').val('').trigger('change');
		});
		
		$('a.shop-address-selector').bind('click.update', function(event) {
			var self = $(this);
			event.preventDefault();
			event.stopPropagation();
			
			if($('#checkout_object_id').length && $('#checkout_object_id').val() != ''){
				$('#address-select-popup').popup('/addresses/select/' + encodeURIComponent(self.attr('href').split('#').pop()) + '/' + encodeURIComponent($('#checkout_object_id').val())).get(0).target = self.closest('.shop-address');
			} else {
				$('#address-select-popup').popup('/addresses/select/' + encodeURIComponent(self.attr('href').split('#').pop())).get(0).target = self.closest('.shop-address');
			}
		});
		
		$('table.shop-address-select>tbody>tr').bind('click.update', function(event) {
			var self = $(this);
			var address = {};
			var ids = self.attr('id').split('-');
			address.customer_id = ids.pop();
			address.customer_address_id = ids.pop();
			address.id = ids.pop();
			address.salutation = self.find('.shop-address-salutation').text();
			address.name1 = self.find('.shop-address-name1').text();
			address.name2 = self.find('.shop-address-name2').text();
			address.street1 = self.find('.shop-address-street1').text();
			address.street2 = self.find('.shop-address-street2').text();
			address.pob = self.find('.shop-address-pob').text();
			address.zip = self.find('.shop-address-zip').text();
			address.city = self.find('.shop-address-city').text();
			address.country_id = self.find('.shop-address-country_id').text();
			address.shipping_method_id = self.find('.shop-address-shipping_method_id').text();
			address.shipping_term_id = self.find('.shop-address-shipping_term_id').text();
			
			self.closest('div.shop-popup')
				.popdown()
				.get(0)
				.target
				.find('.address-customer-id-hidden').val(address.customer_id).trigger('change').end()
				.find('.address-customer-address-id-hidden').val(address.customer_address_id).trigger('change').end()
				.find('.address-salutation-hidden').val(address.salutation).trigger('change').end()
				.find('.address-name1-hidden').val(address.name1).trigger('change').end()
				.find('.address-name2-hidden').val(address.name2).trigger('change').end()
				.find('.address-street1-hidden').val(address.street1).trigger('change').end()
				.find('.address-street2-hidden').val(address.street2).trigger('change').end()
				.find('.address-pob-hidden').val(address.pob).trigger('change').end()
				.find('.address-zip-hidden').val(address.zip).trigger('change').end()
				.find('.address-city-hidden').val(address.city).trigger('change').end()
				.find('.address-country_id-hidden').val(address.country_id).trigger('change').end()
				.find('.address-shipping_method_id-hidden').val(address.shipping_method_id).trigger('change').end()
				.find('.address-shipping_term_id-hidden').val(address.shipping_term_id).trigger('change').end()
				.find('.address-salutation').text(address.salutation).end()
				.find('.address-name1').text(address.name1).end()
				.find('.address-name2').text(address.name2).end()
				.find('.address-street1').text(address.street1).end()
				.find('.address-street2').text(address.street2).end()
				.find('.address-pob').text(address.pob).end()
				.find('.address-zip').text(address.zip).end()
				.find('.address-city').text(address.city).end()
				.find('.address-country_id').text(address.country_id).end()
				.find('.address-country-dash')[address.country_id == '' ? 'hide' : 'show']().end()
				.find('.address-shipping_method_id').text(address.shipping_method_id).end()
				.find('.address-shipping_term_id').text(address.shipping_term_id).end()
				.find('.n')[$.trim(address.salutation) != '' ? 'show' : 'hide']().end()
				.find('.org')[$.trim(address.salutation) != '' ? 'hide' : 'show']().end()
				.find('.address-action-hidden').trigger('change').end()
				.find('.address-id-hidden').val(address.id).trigger('change').end();
		});
		
		$('input.shop-checkbox').each(function() {
			var self = $(this);
			this._value = this._value || this.value || '';
			this.value = '';
			this.checked = self.hasClass('shop-checkbox-checked');
			if (self.hasClass('shop-checkbox-checkall')) {
				var ok = true;
				var checkboxes = $(this.name);
				for (var i = 0, l = checkboxes.length; i < l; i++) {
					if (!checkboxes.get(i).checked) {
						ok = false;
						break;
					}
				}
				
				self[ok ? 'addClass' : 'removeClass']('shop-checkbox-checked').get(0).checked = ok;
			}
		}).bind('click.update', function(event) {
			var self = $(this);
			self.toggleClass('shop-checkbox-checked');
			this.checked = self.hasClass('shop-checkbox-checked');
			self.trigger('change');
			if (this.checked) {
				$('input.shop-checkbox-checkall').each(function() {
					var ok = true;
					var checkall = $(this);
					$(this.name).each(function() {
						if (!this.checked) {
							ok = false;
							return ok;
						}
					});
					
					if (ok) {
						checkall.addClass('shop-checkbox-checked').get(0).checked = true;
						this.checked = true;
					}
				});
			} else {
				$('input.shop-checkbox-checked.shop-checkbox-checkall').each(function() {
					var ok = true;
					var checkall = $(this);
					$(this.name).each(function() {
						if (!this.checked) {
							checkall.removeClass('shop-checkbox-checked').get(0).checked = false;
							this.checked = false;
							return false;
						}
					});
				});
			}
		}).filter('.shop-checkbox-checkall').bind('click.update', function(event) {
			if (this.checked) {
				$(this.name).addClass('shop-checkbox-checked').each(function() {
					this.checked = true;
				}).trigger('change');
			} else {
				$(this.name).removeClass('shop-checkbox-checked').each(function() {
					this.checked = false;
				}).trigger('change');
			}
		});
		
		$('input.shop-datepicker').bind('click.update', function(event) {
			$(this).datepicker('show');
		}).each(function() {
			$(this).datepicker({firstDay: 1,
								showOn: '',
								dateFormat: 'dd.mm.yy',
								minDate: $(this).hasClass('shop-datepicker-today') ? new Date() : null,
								maxDate: $(this).hasClass('shop-datepicker-lastday') ? new Date() : null,
								duration: '',
								dayNames: ['Sonntag', 'Montag', 'Dienstag', 'Mittwoch', 'Donnerstag', 'Freitag', 'Samstag'],
								dayNamesMin: ['So', 'Mo', 'Di', 'Mi', 'Do', 'Fr', 'Sa'],
								dayNamesShort: ['Son', 'Mon', 'Die', 'Mit', 'Don', 'Fre', 'Sam'],
								monthNames: ['Januar', 'Februar', 'M\u00E4rz', 'April', 'Mai', 'Juni', 'Juli', 'August', 'September', 'Oktober', 'November', 'Dezember'],
								monthNamesShort: ['Jan', 'Feb', 'M\u00E4r', 'Apr', 'Mai', 'Jun', 'Jul', 'Aug', 'Sep', 'Okt', 'Nov', 'Dez'],
								beforeShowDay: $(this).hasClass('shop-datepicker-no-weekends') ? $.datepicker.noWeekends : null});
			}
		);
		
		$('input.shop-button-datepicker').bind('click.update', function(event) {
			$('#' + this.name).datepicker('show');
		});
		
		var search_submitted = false;
		$('#shop-search').bind('submit.update', function(event) {
			event.preventDefault();
			event.stopPropagation();
			
			if (!search_submitted) {
				if ($.trim($('#shop-search-input').val()).length >= 2) {
					search_submitted = true;
					document.location.href = this.action + '?search_source_searchitems_q=' + encodeURIComponent($.trim($('#shop-search-input').val()));
				} else {
					$('#shop-search-input').focus();
				}
			}
		});
		
		$('ul.shop-tabs').bind('click.update', function(event) {
			var target = $(event.target);
			if (!target.is('a.shop-tab')) target = target.closest('a.shop-tab');
			if (target.length) {
				event.preventDefault();
				event.stopPropagation();
				
				var tabs = $(this);
				var self = target.get(0);
				var href = target.attr('href');
				var url = href.split('#')[0];
				var div = $('#' + href.split('#')[1]);
				if (url && div.get(0).loaded != url) {
					div.html('<div class="shop-loader-div"></div>');
					tabs.find('a.shop-tab').each(function() {
						var href = $(this).attr('href');
						var div = $('#' + href.split('#')[1]);
						if (this == self) {
							target.parent().addClass('shop-tab-active');
							div.show();
						} else {
							$(this).parent().removeClass('shop-tab-active');
							div.hide();
						}
					});
					$.ajax({url: url,
							success: function(content) {
								$.removeUpdaterEvents();
								div.get(0).loaded = url;
								div.html(content);
								$.updateEvents();
							}
						}
					);
				} else {
					tabs.find('.shop-tab').each(function() {
						var href = $(this).attr('href');
						var div = $('#' + href.split('#')[1]);
						if (this == self) {
							target.parent().addClass('shop-tab-active');
							div.show();
						} else {
							$(this).parent().removeClass('shop-tab-active');
							div.hide();
						}
					});
				}
			}
		}).find('li.shop-tab-active a.shop-tab').each(function() {
			var self = $(this);
			var href = self.attr('href');
			var url = href.split('#')[0];
			var div = $('#' + href.split('#')[1]);
			if (url && div.get(0).loaded != url) {
				div.html('<div class="shop-loader-div"></div>');
				$.ajax({url: url,
						success: function(content) {
							$.removeUpdaterEvents();
							div.get(0).loaded = url;
							div.html(content);
							$.updateEvents();
						}
					}
				);
			}
			$('#' + self.attr('href').split('#')[1]).show();				
		}).end().find('li:not(.shop-tab-active) a.shop-tab').each(function() {
			$('#' + $(this).attr('href').split('#')[1]).hide();
		});
		
		$('ul.shop-tree').bind('click.update', function(event) {
			var self = $(event.target);
			if (self.is('.shop-button-tree')) {
				if(self.hasClass('shop-button-tree-expanded')) {
					self.removeClass('shop-button-tree-expanded');
					self.closest('li').children('ul').hide();
				} else {
					self.addClass('shop-button-tree-expanded');
					self.closest('li').children('ul').show();
				}
			}
		});
		
		var bce = $('#shop-breadcrumb-extension');
		if (bce.length == 0) {
			$('.shop-breadcrumb-inner').first().parent().append('<ul id="shop-breadcrumb-extension" style="display: none;"></ul>');
			bce = $('#shop-breadcrumb-extension');
		}
		
		$('#shop-breadcrumb a.shop-breadcrumb-extend').bind('click.update', function(event) {
			event.preventDefault();
			event.stopPropagation();
			
			var left = $(this).position().left;
			var top = ($.browser.msie || $.browser.webkit) ? $(this).position().top : $(this).offset().top;
			$.ajax({
				url: $(this).attr('href'),
				data: {}, 
				dataType: 'json', 
				error: function() {
					self.popdown();
				},
				success: function(json) {
					$.removeUpdaterEvents();
					bce.html('');
					bce.css('left', left + 4 + 'px');
					bce.css('top', top + 19 + 'px');
					for (var i = 0, l = json.length; i < l; i++) {
						var li = document.createElement('li');
						var a = document.createElement('a');
						li.appendChild(a);
						a.href = json[i].link;
						a.title = json[i].title;
						a.innerHTML = json[i].text;
						bce.append(li);
					}
					bce.show();
					$.updateEvents();
				}
			});
		});
		
		$('a.shop-js-popupper').bind('click.update', function(event) {
			event.preventDefault();
			event.stopPropagation();
			
			var win = window.open(this.href, this.name, this.target);
			win.focus();
		});
		
		$('div.shop-flag-link').bind('click.update', function(event) {
			event.preventDefault();
			event.stopPropagation();
			var a = $(this).find('a');
			if (a.length) document.location.href = a.attr('href');
		});
		
	});
	
	(function() {
		var delay = 400;
		var offsetx = 0;
		var offsety = 21;
		var opacity = 0.8;
		var cache = {};
		var inprogress = null;
		var inprogress_url = null;
		
		var to = null;
		var h = $(document).height() - 10;
		var hintcontainer = $('#shop-hint-container');
		if (hintcontainer.length === 0) {
			$('body').append('<div id="shop-hint-container" style="display: none;"></div>');
			hintcontainer = $('#shop-hint-container');
		}
		
		var reposition = function(x, y) {
			var w = $(window).width();
			var l = $(window).scrollLeft();
			var ow = hintcontainer.outerWidth(), oh = hintcontainer.outerHeight();
			hintcontainer.css('left', (w + l - offsetx < x + ow + offsetx ? x - ow - offsetx : x + offsetx) + 'px');
			hintcontainer.css('top', (h - offsety < y + oh + offsety ? y - oh - offsety : y + offsety) + 'px');
		};
		
		var show = function(event) {
			if (to) clearTimeout(to);
			if (hintcontainer.css('display') != 'none') return;
			h = $(document).height();
			var content = '';
			if (this._title[0] == '#') {
				content = $(this._title).html();
			} else {
				if (this._title in cache) {
					content = cache[this._title];
				} else {
					if (inprogress && inprogress_url == this._title) return;
					var self = this;
					var time = (new Date()).getTime();
					inprogress_url = this._title;
					inprogress = $.ajax({
						url: this._title,
						error: function() {
							inprogress = null;
						},
						success: function(cnt) {
							inprogress = null;
							cache[self._title] = content = cnt;
							if (inprogress_url == this._title) {
								if ((new Date()).getTime() - time >= delay) {
									hintcontainer.html(content);
									hintcontainer.css('opacity', opacity);
									hintcontainer.show();
									reposition(event.pageX, event.pageY);
								} else {
									to = setTimeout(function() {
										hintcontainer.html(content);
										hintcontainer.css('opacity', opacity);
										hintcontainer.show();
										reposition(event.pageX, event.pageY);
									}, delay - ((new Date()).getTime() - time));
								}
							}
						}
					});
					
					return;
				}
			}
			to = setTimeout(function() {
				hintcontainer.html(content);
				hintcontainer.css('opacity', opacity);
				hintcontainer.show();
				reposition(event.pageX, event.pageY);
			}, delay);
		};
		
		var hide = function(event) {
			if (to) clearTimeout(to);
			hintcontainer.hide();
		};
		
		$.attachUpdater(function() {
			$('.shop-hint-target').each(function() {
				if (!this._title) {
					this._title = this.title;
					this.title = '';
				}
				$(this).bind('mousemove.update', show).bind('mouseout.update', hide).bind('mousedown.update', hide);
			});
		});
	})();
	
	(function() {
		var to = null, x = null, y = null, target = null;
		var delay = 400;
		var h = $(document).height() - 10;
		
		var reposition = function(obj) {
			var w = $(window).width();
			var l = $(window).scrollLeft();
			var ow = obj.outerWidth(), oh = obj.outerHeight();
			obj.css('left', (w + l < x + ow ? x - ow : x) + 'px');
			obj.css('top', (h < y + oh ? y - oh : y) + 'px');
		};
		
		if ($('#nice-title').length == 0) {
			$('body').append('<span id="nice-title"></span>');
		}
		
		if ($('#nice-title-text').length == 0) {
			$('body').append('<span id="nice-title-text"></span>');
		}
		
		var showTitle = function() {
			if (target._title.substr(0, 4) == 'img:') {
				var img = document.createElement('img');
				img.src = target._title.substr(4);
				reposition($('#nice-title').html(img).show());
				$('#nice-title-text').hide();
			} else if (target._title.substr(0, 5) == 'html:') {
				reposition($('#nice-title-text').html(target._title.substr(5)).show());
				$('#nice-title').hide();
			} else if (target._title.substr(0, 5) == 'text:') {
				reposition($('#nice-title-text').text(target._title.substr(5)).show());
				$('#nice-title').hide();
			} else {
				reposition($('#nice-title-text').text(target._title).show());
				$('#nice-title').hide();
			}
		}
		
		$.attachUpdater(function() {
			$('.shop-nice-title').bind('mousemove.update', function(event) {
				if ($('#nice-title').css('display') == 'none' && $('#nice-title-text').css('display') == 'none') {
					if (to) clearTimeout(to);
					target = this;
					target._title = target.title || target._title;
					target.title = '';
					if (target._title) {
						x = event.pageX;
						y = event.pageY;
						to = setTimeout(showTitle, delay);
					}
				}
			}).bind('mouseout.update', function(event) {
				if (to) clearTimeout(to);
				target = x = y = null;
				$('#nice-title').hide();
				$('#nice-title-text').hide();
			});
		});
	})();
	
	var to_nav = null;
	function hide_nav() {
		if (to_nav) clearTimeout(to_nav);
		var main = $('#shop-main-subnavigation');
		if (main.css('display') != 'hidden') {
			main.hide();
			$('.shop-main-navigation-open').removeClass('shop-main-navigation-open');
		}
	}
	
	$(document).bind('mousedown', function(event) {
		if ($(event.target).closest('#shop-main-navigation').length > 0) return;
		if ($(event.target).closest('#shop-main-subnavigation').length > 0) return;
		if ($(event.target).closest('#shop-breadcrumb-extension').length > 0) return;
		
		$('#shop-breadcrumb-extension').hide();
		hide_nav();
	});
	
	$.ajaxSetup({type: 'POST', cache: false});
	jQuery.ajaxSettings.traditional = true;
	$(document).ajaxStart(function() {
		$._ajaxRequests += 1;
	});
	$(document).ajaxStop(function() {
		$._ajaxRequests -= 1;
	});
	
	var Base64 = {
	    // private property
	    _keyStr : "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",
	
	    // public method for encoding
	    encode : function (input) {
	        var output = "";
	        var chr1, chr2, chr3, enc1, enc2, enc3, enc4;
	        var i = 0;
	
	        input = Base64._utf8_encode(input);
	
	        while (i < input.length) {
	
	            chr1 = input.charCodeAt(i++);
	            chr2 = input.charCodeAt(i++);
	            chr3 = input.charCodeAt(i++);
	
	            enc1 = chr1 >> 2;
	            enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
	            enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
	            enc4 = chr3 & 63;
	
	            if (isNaN(chr2)) {
	                enc3 = enc4 = 64;
	            } else if (isNaN(chr3)) {
	                enc4 = 64;
	            }
	
	            output = output +
	            this._keyStr.charAt(enc1) + this._keyStr.charAt(enc2) +
	            this._keyStr.charAt(enc3) + this._keyStr.charAt(enc4);
	
	        }
	
	        return output;
	    },
	
	    // public method for decoding
	    decode : function (input) {
	        var output = "";
	        var chr1, chr2, chr3;
	        var enc1, enc2, enc3, enc4;
	        var i = 0;
	
	        input = input.replace(/[^A-Za-z0-9\+\/\=]/g, "");
	
	        while (i < input.length) {
	
	            enc1 = this._keyStr.indexOf(input.charAt(i++));
	            enc2 = this._keyStr.indexOf(input.charAt(i++));
	            enc3 = this._keyStr.indexOf(input.charAt(i++));
	            enc4 = this._keyStr.indexOf(input.charAt(i++));
	
	            chr1 = (enc1 << 2) | (enc2 >> 4);
	            chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
	            chr3 = ((enc3 & 3) << 6) | enc4;
	
	            output = output + String.fromCharCode(chr1);
	
	            if (enc3 != 64) {
	                output = output + String.fromCharCode(chr2);
	            }
	            if (enc4 != 64) {
	                output = output + String.fromCharCode(chr3);
	            }
	
	        }
	
	        output = Base64._utf8_decode(output);
	
	        return output;
	
	    },
	
	    // private method for UTF-8 encoding
	    _utf8_encode : function (string) {
	        string = string.replace(/\r\n/g,"\n");
	        var utftext = "";
	
	        for (var n = 0; n < string.length; n++) {
	
	            var c = string.charCodeAt(n);
	
	            if (c < 128) {
	                utftext += String.fromCharCode(c);
	            }
	            else if((c > 127) && (c < 2048)) {
	                utftext += String.fromCharCode((c >> 6) | 192);
	                utftext += String.fromCharCode((c & 63) | 128);
	            }
	            else {
	                utftext += String.fromCharCode((c >> 12) | 224);
	                utftext += String.fromCharCode(((c >> 6) & 63) | 128);
	                utftext += String.fromCharCode((c & 63) | 128);
	            }
	
	        }
	
	        return utftext;
	    },
	
	    // private method for UTF-8 decoding
	    _utf8_decode : function (utftext) {
	        var string = "";
	        var i = 0;
	        var c = c1 = c2 = 0;
	
	        while ( i < utftext.length ) {
	
	            c = utftext.charCodeAt(i);
	
	            if (c < 128) {
	                string += String.fromCharCode(c);
	                i++;
	            }
	            else if((c > 191) && (c < 224)) {
	                c2 = utftext.charCodeAt(i+1);
	                string += String.fromCharCode(((c & 31) << 6) | (c2 & 63));
	                i += 2;
	            }
	            else {
	                c2 = utftext.charCodeAt(i+1);
	                c3 = utftext.charCodeAt(i+2);
	                string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
	                i += 3;
	            }
	
	        }
	
	        return string;
	    }
	}
	
	$(document).ajaxSuccess(function(e, content, settings) {
		try {
			var i = 0, cnt = '';
			var header = content.getResponseHeader('_debug0');
			while (header) {
				cnt += header;
				i++;
				header = content.getResponseHeader('_debug' + i);
			}
			
			if (cnt) {
				$('#shop-service-trace').prepend('<br /><br />');
				$('#shop-service-trace').prepend(Base64.decode(cnt.replace(/%%%n%%%/g, '\n')));
				$('#shop-service-trace').prepend((new Date()).toLocaleString().split(' ').pop() + ' - ' + settings.url + '<hr />');
			}
		} catch(e) {}
	});
	$._ajaxRequests = 0;
	
	$(window).load(function() {
		$.updateEvents();
		var onclick_only = !$('#shop-main-navigation').hasClass('shop-main-navigation-auto');
		
		var nav_open = function(event) {
			if (to_nav) clearTimeout(to_nav);
			var self = $(event.target);
			var li = self.parent();
			var main = $('#shop-main-subnavigation');
			
			event.preventDefault();
			event.stopPropagation();
			
			if (event.type == 'click' && li.hasClass('shop-main-navigation-open')) {
				li.removeClass('shop-main-navigation-open');
				main.hide();
			} else {
				$('.shop-main-navigation-open').removeClass('shop-main-navigation-open');
				if (self.get(0).subnavdata) {
					try {
						main.css('left', li.position().left - parseInt(main.css('border-left-width'), 10) + 'px');
						main.css('min-width', li.width() - parseInt(main.css('padding-left'), 10) * 2 + 'px');
					} catch (e) {
						main.css('left', li.position().left);
					}
					main.html(self.get(0).subnavdata).show();
					li.addClass('shop-main-navigation-open');
					li.find('.shop-main-subnavigation-top').width(li.width() - 2);
				} else {
					$.ajax({url: self.attr('rev'),
						error: function(req, errorType) {},
						success: function(content) {
							self.get(0).subnavdata = content;
							try {
								main.css('left', li.position().left - parseInt(main.css('border-left-width'), 10) + 'px');
								main.css('min-width', li.width() - parseInt(main.css('padding-left'), 10) * 2 + 'px');
							} catch (e) {
								main.css('left', li.position().left);
							}
							main.html(content).show();
							li.addClass('shop-main-navigation-open');
							li.find('.shop-main-subnavigation-top').width(li.width() - 2);
						}
					});
				}
			}
		}
		
		$('#shop-main-navigation:not(.top-level-link) a[rev][href="#"]').bind('click', nav_open);
		if (!onclick_only) {
			$('#shop-main-navigation a[rev]').bind('mouseenter', nav_open);
			$('#shop-main-navigation a[rev], #shop-main-subnavigation').bind('mouseleave', function() {
				if (to_nav) clearTimeout(to_nav);
				to_nav = setTimeout(hide_nav, 300);
			});
			$('#shop-main-subnavigation').bind('mouseenter', function() {
				if (to_nav) clearTimeout(to_nav);
			});
		}
		
		$('#shop-shortcuts-profile').bind('mouseenter', function(event) {
			event.preventDefault();
			event.stopPropagation();
			var popup = $('#shop-shortcuts-profile-popup');
			popup.css('left', $(this).offset().left);
			popup.show();
		}).bind('mouseleave', function(event) {
			event.preventDefault();
			event.stopPropagation();
			$('#shop-shortcuts-profile-popup').hide();
		});
		
		if (!$('#shop-portlet-login').length) {
			$('#shop-logout-link').bind('click.update', function(event) {
				event.preventDefault();
				event.stopPropagation();
				$.ajax({url: '/portlet/login',
						data: 'auth:logout=1',
						dataType: 'json', 
						success: function(json) {
							$.evalScripts(json.content);
						}
					}
				);
			});
		}
		
		if ($('#shop-portlet-login-login').length) {
			$('#shop-portlet-login-login').select().focus();
		}
		
	});
})();

