/* >> jQuery $ recover and other jquery global stuff */
	$ = jQuery.noConflict();
	jQuery.ajaxSettings.traditional = true;
/* << */


/* >> jQuery extensions */
	;(function($){
		$.fn.extend({
			allAttrs: function(withoutList){
				var set = this;
				var attrsObjsList = [];
				withoutList = withoutList || [];
				set.each(
					function(n){
						var obj = {};
						for (var i = 0; i < this.attributes.length; ++i){
							var a = this.attributes[i];
							if ($.inArray(a.nodeName, withoutList) == -1){
								obj[a.nodeName] = a.nodeValue;
							}
						}
						attrsObjsList.push(obj);
					}
				);
				return attrsObjsList;
			},
			// if value is a jquery object .html() will be used to handle value.
			// Otherwise a dom xhtml string representation will be produced.
			xhtml: function(value){
				var i, j, node, nodeName, nodeType, attr, attrName, attrValue, str,
				singleTags = [
					'img', 'br', 'hr', 'area', 'base', 'basefont', 'col', 'frame', 
					'input', 'isindex', 'link', 'meta', 'param'
				],
				encodeSpecialChars = function(s){
					s = s.replace(/&/, '&amp;');
					s = s.replace(/</, '&lt;');
					s = s.replace(/>/, '&gt;');
					//s = s.replace(/"/, '&quote;');
					return s;
				};
				if (value === undefined){
					// wrap value into root.
					node = this.get(0);
					nodeName = node.nodeName.toLowerCase();
					nodeType = node.nodeType;
					if (nodeType === 1){ // element node
						str = '<' + nodeName;
						if (node.attributes.length){
							for (j = 0; j < node.attributes.length; j += 1){
								attr = node.attributes[j];
								attrName = attr.nodeName.toLowerCase();
								attrValue = attr.nodeValue;
								str += ' ' + attrName + '="' + encodeSpecialChars(attrValue) + '"';
							}
						}
						if (jQuery.inArray(nodeName, singleTags) > -1){
							str += ' />';
						}else{
							str += '>';
							for (i = 0; i < node.childNodes.length; i += 1){
								str += jQuery.fn.xhtml.call($(node.childNodes[i]));
							}
							str += '</' + nodeName + '>';
						}
						return str;
					}else if (nodeType === 3){
						return encodeSpecialChars(node.nodeValue);
					}else if (nodeType === 8){
						return '<!--' + encodeSpecialChars(node.nodeValue) + '-->';
					}
					return '';
				}else{
					jQuery.fn.html(value);
				}
			}
		});
	
		// get iso date and get iso time
		$.extend({
			getISODate: function(gmtDateStr, lang){
				var dateBox = {
					'de': {'month': ['Januar', 'Februar', 'März', 'April', 'Mai', 'Juni', 'Juli', 'August', 'September', 'Oktober', 'November', 'Dezember'], 'separator': '.'},
					'en': {'month': ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'], 'separator': '/'}
				}
				if (arguments.length == 0){
					var date = new Date();
					var lang = 'en';
				}else if (arguments.length == 1){
					var arg = arguments[0];
					if (typeof arg == 'string' && arg.length == 2){
						var lang = arg;
						var date = new Date();
					}else{
						var lang = 'en';
						var date = new Date(gmtDateStr);
					}
				}else{
					var date = new Date(gmtDateStr);
				}
				var sep = dateBox[lang].separator;
				var y = date.getYear() - 100;
				var fy = date.getFullYear();
				var m = date.getMonth();
				var d = date.getDate();
				var md = d < 10 ? '0' + d : d;
				var mm = m + 1 < 10 ? '0' + (m + 1) : m + 1;
				var my = y < 10 ? '0' + y : y;
				if (lang == 'de'){
					return {
						'short': d + sep + (m + 1) + sep + y,
						'_short': d + sep + (m + 1) + sep + y,
						'middle': md + sep + mm + sep + my,
						'_middle': md + sep + mm + sep + my,
						'long': md + sep + dateBox[lang].month[m] + sep + fy,
						'_long': md + sep + dateBox[lang].month[m] + sep + fy
					}
				}
				return {
					'short': (m + 1) + sep + d + sep + y,
					'_short': (m + 1) + sep + d + sep + y,
					'middle': mm + sep + md + sep + my,
					'_middle': mm + sep + md + sep + my,
					'long': dateBox[lang].month[m] + sep + md + sep + fy,
					'_long': dateBox[lang].month[m] + sep + md + sep + fy
				}
			},
			getISOTime: function(gmtDateStr){
				if (gmtDateStr) var date = new Date(gmtDateStr);
				var date = new Date();
				var h = date.getHours();
				if (h < 10) h = '0' + h;
				var m = date.getMinutes();
				if (m < 10) m = '0' + m;
				var s = date.getSeconds();
				if (s < 10) s = '0' + s;
				return h + ':' + m + ':' + s;
			}
		});

		$.extend({
			formatDate: function(gmtDateStr, lang){
				var dateBox = {
					'de': {'month': ['Januar', 'Februar', 'März', 'April', 'Mai', 'Juni', 'Juli', 'August', 'September', 'Oktober', 'November', 'Dezember'], 'separator': '.'},
					'en': {'month': ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'], 'separator': '/'}
				}
				if (arguments.length == 0){
					var date = new Date();
					var lang = 'en';
				}else if (arguments.length == 1){
					var arg = arguments[0];
					if (typeof arg == 'string' && arg.length == 2){
						var lang = arg;
						var date = new Date();
					}else{
						var lang = 'en';
						var date = new Date(gmtDateStr);
					}
				}else{
					var date = new Date(gmtDateStr);
				}
				var sep = dateBox[lang].separator;
				var y = date.getFullYear() - 2000;
				var fy = date.getFullYear();
				var m = date.getMonth();
				var d = date.getDate();
				var md = d < 10 ? '0' + d : d;
				var mm = m + 1 < 10 ? '0' + (m + 1) : m + 1;
				var my = y < 10 ? '0' + y : y;
				if (lang == 'de'){
					return {
						'_short': d + sep + (m + 1) + sep + y,
						'_middle': md + sep + mm + sep + my,
						'_long': md + sep + dateBox[lang].month[m] + sep + fy
					}
				}
				return {
					'_short': (m + 1) + sep + d + sep + y,
					'_middle': mm + sep + md + sep + my,
					'_long': dateBox[lang].month[m] + sep + md + sep + fy
				}
			},
			formatTime: function(gmtDateStr){
				var date = gmtDateStr ? new Date(gmtDateStr) : new Date();
				var h = date.getHours();
				if (h < 10) h = '0' + h;
				var m = date.getMinutes();
				if (m < 10) m = '0' + m;
				var s = date.getSeconds();
				if (s < 10) s = '0' + s;
				return h + ':' + m + ':' + s;
			}
		});
		
		// setter and getter for language resources
		$.extend({
			lang: function(name, lang){
				if (arguments.length > 1){
					if (typeof lang == 'object'){
						if (! $.lang._res) $.lang._res = {};
						$.lang._res[name] = lang;
						return lang;
					}else{
						if ($.lang._res && $.lang._res[name] && $.lang._res[name][lang]){
							return $.lang._res[name][lang];
						}
					}
					return '?-invalid-language-resource-?';
				}else if (arguments.length == 1){
					lang = $('html').attr('lang');
					if (!lang) lang = 'en';
					if ($.lang._res) return $.lang._res[name][lang];
					return '?-invalid-language-resource-?';
				}
				return $('html').attr('lang');
			}
		});
	
		// scroll to plugin easing type elasout
		$.easing.elasout = function(x, t, b, c, d) {
			var s=1.70158;var p=0;var a=c;
			if (t==0) return b;  if ((t/=d)==1) return b+c;  if (!p) p=d*.3;
			if (a < Math.abs(c)) { a=c; var s=p/4; }
			else var s = p/(2*Math.PI) * Math.asin (c/a);
			return a*Math.pow(2,-10*t) * Math.sin( (t*d-s)*(2*Math.PI)/p ) + c + b;
		};
	
		// serialize json data
		$.extend({
			toJson: function(o){
				var type = typeof o;
				if (type == 'undefined')
					return 'undefined';
				else if (type == 'number' || type == 'boolean')
					return o + "";
				else if (o === null)
					return 'null';
				else if (type == 'string'){
					var escapeable = /["\\\x00-\x1f\x7f-\x9f]/g;
					var meta = {
							'\b': '\\b',
							'\t': '\\t',
							'\n': '\\n',
							'\f': '\\f',
							'\r': '\\r',
							'"' : '\\"',
							'\\': '\\\\'
					};
					if (escapeable.test(o)){
						return '"' + o.replace(escapeable, function (a){
							var c = meta[a];
							if (typeof c === 'string') {
									return c;
							}
							c = a.charCodeAt();
							return '\\u00' + Math.floor(c / 16).toString(16) + (c % 16).toString(16);
						}) + '"';
					}
					return '"' + o + '"';
				}else if (type == 'function')
					return;
				else if (type == 'object' && typeof o.toJson == 'function')
					return o.toJson();
				else if (type == 'object' && typeof o.length == 'number'){
					var tempList = [];
					for (var i = 0; i < o.length; i++){
						tempList.push($.toJson(o[i]));
					}
					return '[' + tempList.join(',') + ']';
				}
				
				var tempList = [];
				if (typeof o.toJsonAttrs == 'object' && typeof o.toJsonAttrs.length == 'number'){
					for (var i = 0; i < o.toJsonAttrs.length; i++){
						var k = o.toJsonAttrs[i];
						if (typeof o[k] != 'function'){
							tempList.push($.toJson(k) + ':' + $.toJson(o[k]));
						}
					}
				}else{
					for (var k in o){
						if (typeof o[k] != 'function'){
							tempList.push($.toJson(k) + ':' + $.toJson(o[k]));
						}
					}
				}
				return '{' + tempList.join(',') + '}';
			}
		});
	
		// object clone
		$.extend({
			clone: function(o){
				function F(){};
				F.prototype = o;
				var result = new F();
				result.__prototype__ = o;
				return result;
			}
		});
		
		// reduce property from list
		$.extend({
				reduce: function(props, name){
					if (typeof props == 'object'){
						var realProps = {};
						for (var k in props){
							if (k != name){
								realProps[k] = props[k];
							}
						}
						return realProps;
					}
					return props;
				}
		});
	})(jQuery);
/* << */


/* >> utilities requires jQuery 1.2.6 Version: rel-1-6-0 */
	doNothing = function(){}
	Utils = {
		pixelPath: '/xist4c/px/spc.gif',
		pixel: function(){
			return $('<img src="' + this.pixelPath + '" height="1" width="1" border="0" alt=""/>');
		},
		pixelAsString: function(){
			return '<img src="' + this.pixelPath + '" height="1" width="1" border="0" alt=""/>';
		},
		getRecalculatedImage: function(args){
			var img = args.image;
			if ($.browser.msie){
				var w = img.width;
				var h = img.height;
			}else{
				var w = img.attr('width');
				var h = img.attr('height');
			}
			var mw = args.maxWidth;
			var mh = args.maxHeight;
			var nw, nh;
			var f = 1;
			if (args.proportional){
				f = mw / w;
				var nw = mw;
				var nh = h * f;
				if (nh > mh){
					f = mh / nh;
					var nh = mh;
					var nw = nw * f;
				}
				if ($.browser.msie){
					img.width = nw;
					img.height = nh;
				}else{
					img.attr('width', nw);
					img.attr('height', nh);
				}
				return img;
			}
			if ($.browser.msie){
				img.width = mw;
				img.height = mh;
			}else{
				img.attr('width', mw);
				img.attr('height', mh);
			}
			return img;
		},
		getUrlParamsAsJson: function(url, dontDecode){
			var self = this, urlParams;
			if (!url){
				url = window.location.href;
			}
			if (url.search(/\?/) > -1){
				urlParams = url.substring(url.search(/\?/) + 1 , url.length);
				urlParams = urlParams.split('&');
				jParams = {};
				$(urlParams).each(function(i){
					var parVal = this.split('='), record, k = parVal[0], v = parVal[1];
					if (!dontDecode){
						k = decodeURI(parVal[0]);
						v = decodeURI(parVal[1]);
					}
					if (jParams[k] && typeof jParams[k] !== 'undefined'){
						if (self.isArray(jParams[k])){
							jParams[k].push(v);
						}else{
							jParams[k] = [jParams[k]];
							jParams[k].push(v);
						}
					}else{
						jParams[k] = v;
					}
				});
				return jParams;
			}
			return null;
		},
		getUrlParamsFromJson: function(params, noEmptyParams){
			var paramStr = '?', i, self = this, k;
			if (params && typeof params === 'object'){
				for (k in params){
					if (params[k] && self.isArray(params[k])){
						for (i = 0; i < params[k].length; i+=1){
							paramStr += [encodeURIComponent(k),'=',encodeURIComponent(params[k][i]),'&'].join('');
						}
					}else{
						if (noEmptyParams){
							if (params[k]){
								paramStr += [encodeURIComponent(k),'=',encodeURIComponent(params[k]),'&'].join('');
							}
						}else{
							paramStr += [encodeURIComponent(k),'=',encodeURIComponent(params[k]),'&'].join('');
						}
					}
				}
				return paramStr.substring(0, paramStr.length - 1);
			}
			return null;
		},
		stripTags: function(str){
			if (typeof str == 'string') return str.replace(/<\/?[^>]+>/gi, '');
			return null;
		},
		clipStringAfter: function(str, len, opts){
			var rStr = '', defaults = {
				endChar: null,
				decorator: null
			}, i;
			if (opts && this.isObject(opts)){
				$.extend(defaults, opts);
			}
			if (str.length > len){
				rStr = str.substring(0, len);
				if (typeof defaults.endChar === 'string'){
					if (str.substr(len, 1) != defaults.endChar){
						for (i = 0; i < str.substr(len, str.length).length; i+=1){
							if (str.substr(len + i, 1) == defaults.endChar){
								rStr += str.substr(len, i);
								break;
							}
						}
					}
				}
				if (typeof defaults.decorator === 'string'){
					rStr += defaults.decorator;
				}
				return rStr;
			}
			return str;
		},
		parseDeFloat: function(f){
			var f = f.replace(/\./g, '');
			f = f.replace(/\,/, '.');
			return f;
		},
		getUrlSession: function(keyString){
			var sidKeyLength = 12, sidKeyRex = /;jsessionid=/, sid = null,
					loc = window.location.href, params = Utils.getUrlParamsAsJson(), paramStartRex = /\?/, endPos,
					ks = keyString || '';
			if (sidKeyRex.test(loc)){
				if (params){
					endPos = loc.search(paramStartRex);
				}else{
					endPos = loc.length;
				}
				return ks + loc.substring(loc.search(sidKeyRex) + sidKeyLength, endPos);
			}
			return '';
		},
		isObject: function(obj){
			return (
				obj && 
				(typeof(obj) === 'object') && 
				!(typeof(obj.length) === 'number')
			);
		},
		isArray: function(obj){
			return (
				obj && 
				!(typeof(obj) === 'string') && 
				(typeof(obj) === 'object') && 
				(typeof(obj.length) === 'number')
			);
		},
		isFunction: function(obj){
			return typeof(obj) === 'function';
		},
		isString: function(obj){
			return typeof(obj) === 'string';
		},
		busyWait: function(condition, interval, maxloops, callback){
			var ivFunc, cnt = 0, self = this, stdInterval = 1000, intervalObj = null;
			if (parseInt(Number(interval)) !== 'NaN' && parseInt(Number(interval)) > 0){
				stdInterval = parseInt(interval);
			}
			if (Utils.isFunction(condition)){
				if (!intervalObj){
					ivFunc = function(){
						var ready = condition.call(self);
						if (ready){
							clearInterval(intervalObj);
							intervalObj = null;
							if (Utils.isFunction(callback)){
								callback.call(self);
							}
						}
						cnt +=1;
						if (cnt == maxloops){
							clearInterval(intervalObj);
							intervalObj = null;
							return null;
						}
					}
					intervalObj = setInterval(ivFunc, stdInterval);
				}
			}
		},
		getXist4cSessionId: function(opts){
			var defaults = {
				sessionPrefix: ';jsessionid',
				sessionCookieName: 'JSESSIONID',
				returnOnlyUrlSession: false,
				returnWithPrefix: false
			}, u = window.location.href, c = $.cookie(defaults.sessionCookieName), end,
			sessionPrefix = defaults.sessionPrefix;
			if (opts && typeof opts === 'object'){
				$.extend(defaults, opts);
			}
			if (u.search(sessionPrefix) > -1){
				if (u.indexOf('?') === -1){
					end = u.length;
				}else{
					end = u.indexOf('?');
				}
				if (defaults.returnWithPrefix){
					return u.substring(u.search(sessionPrefix), end);
				}
				return u.substring(u.search(sessionPrefix) + (sessionPrefix.length + 1), end);
			}else if (!defaults.returnOnlyUrlSession){
				if (c){
					if (defaults.returnWithPrefix){
						return [sessionPrefix,'=',c].join('');
					}
					return c;
				}
			}
			return null;
		},
		// used with modified function context (call, apply)!
		// a calling object must provide a "defaults" member
		getDefault: function(name){
			var dv;
			if (typeof this.defaults === 'object'){
				if (typeof name === 'string'){
					dv = this.defaults[name];
					if (typeof dv === 'undefined'){
						return null;
					}
					return dv;
				}
				return this.defaults;
			}
			return null;
		}
	}
/* << */


/* >> livinglogic extended object with own prototype extension Version: rel-1-0-0 */
	LLObject = {
		__prototype__: null,
		create: function(){
			return $.clone(this);
		},
		instanceOf: function(type){
			if (this == type)
				return true;
			else if (this.__prototype__ == null)
				return false;
			else
				return this.__prototype__.instanceOf(type);
		}
	}
/* << */


window.CREATIVEPILOT_FORMAT_MAPPER = {
	"fo_4610":38,
	"fo_3300":26,
	"fo_4220":37,
	"fo_3030":6,
	"fo_3040":7,
	"fo_3340":30,
	"fo_3020":5,
	"fo_3100":12,
	"fo_3060":8,
	"fo_3140":16,
	"fo_3000":3,
	"fo_3420":36,
	"fo_3320":28,
	"fo_2990":2,
	"fo_3090":11,
	"fo_3390":33,
	"fo_3270":23,
	"fo_5990":40,
	"fo_3310":27,
	"fo_3080":10,
	"fo_3290":25,
	"fo_3230":19,
	"fo_3210":17,
	"fo_3010":4,
	"fo_3110":13,
	"fo_2950":1,
	"fo_3330":29,
	"fo_3070":9,
	"fo_3400":34,
	"fo_3130":15,
	"fo_3120":14,
	"fo_3250":21,
	"fo_6000":41,
	"fo_3410":35,
	"fo_3240":20,
	"fo_5980":39,
	"fo_3220":18,
	"fo_3370":31,
	"fo_3260":22,
	"fo_3380":32,
	"fo_3280":24
};


/* >> project language resources for i18n */
	$.lang('shoppingcartOverlayHint', {
		'de': 'Sie haben folgenden Artikel in den Warenkorb gelegt:',
		'en': 'You have put the following article to the shopping cart:'
	});
	$.lang('choose', {
		'de': 'auswählen',
		'en': 'choose'
	});
	$.lang('setCustomFormat', {
		'de': 'Eigenes Format festlegen',
		'en': 'Set your own format'
	});
	$.lang('weight', {
		'de': 'Stärke',
		'en': 'Weight'
	});
	$.lang('width', {
		'de': 'Breite',
		'en': 'Width'
	});
	$.lang('heigth', {
		'de': 'Höhe',
		'en': 'Height'
	});
	$.lang('hintXxlMaxWidth', {
		'de': 'max. 160cm',
		'en': 'max. 160cm'
	});
	$.lang('hintXxlMaxHeight', {
		'de': 'max. 300cm',
		'en': 'max. 300cm'
	});
	$.lang('infoTextPmt', {
		'de': 'Info',
		'en': 'Info'
	});
	$.lang('choosePattern', {
		'de': 'Vorlage auswählen',
		'en': 'Choose pattern'
	});
	$.lang('page', {
		'de': 'Seite',
		'en': 'Page'
	});
	$.lang('from', {
		'de': 'von',
		'en': 'from'
	});
	$.lang('previewOverall', {
		'de': 'Vorlagen insgesamt',
		'en': 'Previews overall'
	});
	$.lang('pagerInfoNoItems', {
		'de': 'Keine Vorlagen vorhanden',
		'en': 'No Previews exists'
	});
	$.lang('productInfoPrompt', {
		'de': 'Information: ',
		'en': 'Information: '
	});
	$.lang('noSuperSpecial', {
		'de': 'Streng limitierte Sonderangebote &mdash;<br/>nur <span>250</span> Stück von Montag bis Freitag!',
		'en': '???'
	});
	$.lang('withLandscapeMsg', {
		'de': 'Dieses Format ist auch als Querformat gestaltbar!\n\nKlicken Sie auf "OK" um mit einem Querformat zu starten, oder auf "Abbrechen" um mit einem Hochformat zu starten.',
		'en': 'Information: '
	});
	$.lang('searchPhraseProposalTitle', {
		'de': 'Unsere Vorschläge für Sie...',
		'en': 'Our proposals for you...'
	});
	$.lang('productProposalTitle', {
		'de': 'Unsere Produktvorschläge...',
		'en': 'Our product proposals...'
	});
	$.lang('creativePilotMergedUserDocuments', {
		'de': 'Es wurde festgestellt, das bereits Dokumente gespeichert wurden.\nDiese werden jetzt in Ihren Benutzer-Account verschoben\nund stehen Ihnen weiterhin zur Verfügung!',
		'en': 'We have found saved documents.\nThis documents are now moved to your user-account\nand can be used furtheremore!'
	});
	$.lang('creativePilotBufferError', {
			'de': 'Fehler: Die Kreation konnte nicht gespeichert werden!\nBitte versuchen Sie es zu einem späteren Zeitpunkt noch einmal.',
			'en': 'Error: The creation couldn\'t be saved! Please try again later.'
	});
	$.lang('searchFacetPanelItemBack', {
		'de': '< Alle anzeigen',
		'en': '< Show all'
	});
	$.lang('searchInfoPrompt1', {
		'de': 'Seite',
		'en': 'Page'
	});
	$.lang('searchInfoPrompt2', {
		'de': 'von',
		'en': 'from'
	});
	$.lang('startpageNewsPanelEnhancerTitleMore', {
		'de': 'Mehr News anzeigen',
		'en': 'Show more news'
	});
	$.lang('startpageNewsPanelEnhancerTitleLess', {
		'de': 'Weniger News anzeigen',
		'en': 'Show less news'
	});
	$.lang('startpageSeoPanelEnhancerTitleMore', {
		'de': 'Ganzen Text anzeigen',
		'en': 'Show all info'
	});
	$.lang('startpageSeoPanelEnhancerTitleLess', {
		'de': 'Weniger Text anzeigen',
		'en': 'Show less info'
	});
	$.lang('pleaseChoose', {
		'de': 'Bitte wählen',
		'en': 'Please choose'
	});
	$.lang('displayPilotAddOptionsHeader', {
		'de': 'Zusatzoptionen und Zubehör',
		'en': 'Additional options and accessory'
	});
	$.lang('displayPilotDownloadHeader', {
		'de': 'Downloads',
		'en': 'Downloads'
	});
	$.lang('displayPilotDownloadDatasheet', {
		'de': 'Datenblatt',
		'en': 'Datasheet'
	});
	$.lang('displayPilotDownloadTemplate', {
		'de': 'Formatvorlage',
		'en': 'Template'
	});
/* << */


/* >> AJAX URL Manager jQuery 1.2.6 Version: rel-1-0-0 */
	AjaxURLManager = {
		mode: 'static',
		URL: {},
		sessionData: null,
		baseURL: '/backend/',
		baseURLStatic: '../static/',
		setBaseURL: function(url){
			this.baseURL = url;
		},
		setBaseURLStatic: function(url){
			this.baseURLStatic = url;
		},
		setMode: function(mode){
			this.mode = APP_MODE = mode;
		},
		registerKey: function(key, attrs, staticFile, allwaysStatic){
			this.URL[key] = {'attrs': attrs, 'staticFile': staticFile, 'allwaysStatic': allwaysStatic};
		},
		getUrlWithKey: function(key, attrs){
			if (this.URL[key]){
				var data = this.URL[key];
				if (data.attrs || attrs){
					if (data.attrs) attrs = $.extend(data.attrs, attrs);
					var realAttrs = {};
					for (var k in attrs){
						if (attrs[k] != null) realAttrs[k] = attrs[k];
					}
					if (this.sessionData) realAttrs = $.extend(realAttrs, this.sessionData);
					attrs = '?' + $.param(realAttrs);
				}else{
					if (this.sessionData){
						var attrs = $.extend(data.attrs, this.sessionData);
						attrs = '?' + $.param(this.sessionData);
					}
				}
				if (this.mode == 'static' && data.staticFile || data.allwaysStatic && data.staticFile){
					return [this.baseURLStatic,data.staticFile,attrs].join('');
				}
				return [this.baseURL,key,attrs].join('');
			}
			return null;
		}
	}
	AjaxURLManager.setMode('live');
	AjaxURLManager.registerKey('configarticle', null, 'slotMachineConfig2.text', false);
	AjaxURLManager.registerKey('classicconfigarticle', null, 'classicModeConfig.text', true);
	AjaxURLManager.registerKey('posterproduct', null, 'stepFilteredConfigurationColumnData.text', false);
	AjaxURLManager.registerKey('posterproductoverview', null, 'posteroverview1.text', false);
	AjaxURLManager.registerKey('posterproductlayouttool', null, null, false);
	AjaxURLManager.registerKey('xxlproduct', null, 'stepFilteredConfigurationRowData.text', false);
	AjaxURLManager.registerKey('xxlproduct_dev', null, 'stepFilteredConfigurationRowData.text', false);
	AjaxURLManager.registerKey('search', null, null, false);
	AjaxURLManager.registerKey('creativepilotconfigarticle', null, 'creativePilotSlotMachineSelectVariantConfig.text', true);
	AjaxURLManager.registerKey('creativepilot_panel', null, 'creativePilotCategoryProductList.text', false);
	AjaxURLManager.registerKey('creativepilotgetparams', null, 'creativePilotCategoryProductList.text', false);
	AjaxURLManager.registerKey('creativepilotbuffer', null, null, false);
	AjaxURLManager.registerKey('weeklyspecial', null, null, false);
	AjaxURLManager.registerKey('formattemplate4article', null, null, false);
	AjaxURLManager.registerKey('datasheet', null, null, false);
	AjaxURLManager.registerKey('mediagallery', null, null, false);
	AjaxURLManager.registerKey('weeklyspecial', null, null, false);
	AjaxURLManager.registerKey('sharedproductselect', null, null, true);
	AjaxURLManager.registerKey('get_shipping_options', null, null, true);
/* << */


/* >> background animator requires jQuery 1.2.6 Version: rel-1-0-0 */
	BgAnimate = {
		animations: [],
		registerAnimation: function(name, obj, options){
			var defaults = {
				path: '/xist4c/web/standard/01/img/',
				prefix: 'rotorBigAni_',
				extension: 'png',
				bgPosition: 'center center',
				imgCount: 8,
				duration: 80
			};
			var d = options ? $.extend(defaults, options) : defaults;
			var ani = {};
			ani.name = name;
			ani.options = d;
			ani.target = obj;
			ani.imgs = [];
			ani.interval = null;
			ani.frame = 0;
			ani.start = function(){
				this.frame = (this.frame % this.imgs.length);
				var t = this.target;
				var img = this.imgs[this.frame];
				t.css({
					'background-image': ['url(',img.src,')'].join(''),
					'background-repeat': 'no-repeat',
					'background-position': this.options.bgPosition
				});
				this.frame++;
				if (!this.interval){
					var self = this;
					this.interval = setInterval(function(){self.start()}, this.options.duration);
				}
			};
			ani.stop = function(){
				if (this.interval) clearInterval(this.interval);
				this.interval = null;
			};
			for (var i = 0; i < d.imgCount; i++){
				var img = new Image();
				img.src = [d.path, d.prefix, i, '.', d.extension].join('');
				img.alt = '';
				ani.imgs.push(img);
			}
			this.animations.push(ani);
		},
		createAnimation: function(name, obj){
			var ani = null;
			$(this.animations).each(function(i){
				if (this.name == name){
					ani = this;
				}
			});
			if (ani){
				var cAni = $.clone(ani);
				cAni.target = obj;
				return cAni;
			}
			return null;
		},
		start: function(name, obj){
			var ani = this.getAnimation(name);
			if (ani){
				if (obj) ani.target = obj;
				ani.start();
			}
		},
		stop: function(name){
			var ani = this.getAnimation(name);
			if (ani) ani.stop();
		}
	}
/* << */


/* >> XIST4C Globals */
	XIST4C_GLOBALS = {};
/* << */


/* >> LivingLogic DropDown Node (requires jQuery 1.2.6) Version: rel-1-0-0 */
	Node = function(Args){
		for (var name in Args){
			this[name] = Args[name];
		}
		this.children = [];
	}
	
	Node.prototype.childrenLayer = function(level){
		var layerId = ['childrenLevelContainer_',this.level].join('');
		if (level) layerId = ['childrenLevelContainer_',level].join('');
		return layer = $('<div></div>').css(
			{
				'position': 'absolute',
				'right': ['-',LL_DropDownNavi.layerWidth,'px'].join(''),
				'top': 0,
				'z-index': this.level * 10,
				'width': [LL_DropDownNavi.layerWidth,'px'].join('')
			}
		).attr({'id': layerId}).hide();
	}

	Node.prototype.nodeChildrenShell = function(){
		var cs = $('<div></div>').attr({'class': ['navCHS_',this.level+1].join('')});
		var self = this;
		if (this.styName){
			var sty = ['co_',this.styName].join('');
			var d = $('<div></div>').attr({'class': sty});
			if (this.children.length > 0){
				$(this.children).each(function(i){
					var Args = {};
					if (i == 0) Args.first = true;
					if (i == self.children.length -1) Args.last = true;
					d.append(this.nodeShell(Args));
				});
			}
			cs.append(d);
			return cs;
		}
		if (this.children.length > 0){
			$(this.children).each(function(i){
				var Args = {};
				if (i == 0) Args.first = true;
				if (i == self.children.length -1) Args.last = true;
				cs.append(this.nodeShell(Args));
			});
		}
		return cs;
	}
	
	Node.prototype.nodeFirstLevelShell = function(){
		var ns = $('<div></div>').attr({'class': ['navNS_',this.level].join(''), 'id': this.id})
		var node = this.node();
		ns.append(this.childrenLayer(1));
		if (this.styName){
			var sty = ['co_',this.styName].join('');
			var d = $('<div></div>').attr({'class': sty});
			d.append(node);
			if (this.children.length > 0){
				var cs = this.nodeChildrenShell();
				d.append(cs);
			}
			ns.append(d);
			return ns;
		}
		ns.append(node);
		if (this.children.length > 0){
			var cs = this.nodeChildrenShell();
			ns.append(cs);
		}
		return ns;
	}

	Node.prototype.nodeShell = function(Args){
		var ns = $('<div></div>').attr({'class': ['navNS_',this.level].join(''), 'id': this.id})
		var csOffset = $('<div></div>').css({'position': 'relative'}).attr({'id': [this.id,'_layerOffset'].join('')});
		ns.append(csOffset);
		var node = this.node();
		if (Args){
			var origClassName = node.attr('class');
			var newClassName = '';
			if (Args.first) newClassName += [' ',origClassName,'_first'].join('');
			if (Args.last) newClassName += [' ',origClassName,'_last'].join('');
			node.attr('class', origClassName + ' ' + newClassName);
		}
		if (this.styName){
			var sty = ['co_',this.styName].join('');
			var d = $('<div></div>').attr({'class': sty});
			d.append(node);
			ns.append(d);
			return ns;
		}
		ns.append(node);
		return ns;
	}

	Node.prototype.node = function(){
		var outer = $('<div></div>')
			.attr({'class': ['navEl_',this.level,'_',this.type].join('')});
		var n = $('<div></div>')
			.attr({'class': 'outer'});
		var text = $('<span></span>').attr({'class': 'inner'}).text(this.title);
		if (this.href){
			if (this.type == 'here'){
				text = $('<div></div>').attr({'class': 'noLink'}).append(text).css('cursor', 'hand');
			}else if(this.type == 'inPath'){
				text = $('<a></a>').attr({'href': this.href}).append(text).css('cursor', 'hand');
			}else if(this.type == 'normal'){
				text = $('<a></a>').attr({'href': this.href}).append(text).css('cursor', 'hand');
			}
		}
		n.append(text);
		outer.append(n);
		outer.css('cursor', 'hand');
		var self = this;
		if (this.children.length > 0 && this.level > 0){
			outer.bind('mouseover', function(e){
				var levelCont = ['#childrenLevelContainer_',self.level].join('');
				if ($(levelCont).size() == 0) $('body').append(self.childrenLayer());
				var layerOffset = ['#',self.id,'_layerOffset'].join('');
				$(levelCont).empty().append(self.nodeChildrenShell()).hide();
				$(layerOffset).append($(levelCont));
				$(levelCont).fadeIn(200);
			});
		}else{
			var level = self.level == 0 ? self.level + 1 : self.level;
			outer.bind('mouseover', function(e){
				 $('#childrenLevelContainer_' + level).fadeOut(200);
			});
		}
		return outer;
	}
	
/* << */


/* >> LivingLogic DropDown Navigation (requires jQuery 1.2.6) Version: rel-1-0-0 */
	LL_DropDownNavi = {
		path: [],
		layerWidth: 160,
		lay: {
			pixel: function(){
				return $('<img />').attr({'src': '/xist4c/px/spc.gif', 'width': 1, 'height': 1, 'alt': ''});
			},
			nodesOuterShell: function(content){
				var nos = $(
					'<div class="navOuterShell">' +
						'<div class="noDes1">' +
							'<div class="noDes2">' +
								'<div class="topImg">' +
									'<div class="bottomImg">' +
									'</div>' +
								'</div>' +
							'</div>' +
						'</div>' +
					'</div>'
				);
				nos.find('div.topImg').append(LL_DropDownNavi.lay.pixel())
				nos.find('div.bottomImg').append(content);
				nos.find('div.bottomImg').append(LL_DropDownNavi.lay.pixel());
				nos.bind('mouseleave', function(){
					$('div[id^=childrenLevelContainer_]').fadeOut(500);
				});
				return nos;
			}
		},
		sitemap: null,
		init: function(Args){
			this.sitemap = this.buildTreeFromArray(XIST4C_GLOBALS.sitemap);
			lay = LL_DropDownNavi.lay;
			var homeNode = this.sitemap[0].nodeFirstLevelShell();
			if (Args && Args.target){
				var target = $(['#',Args.target].join(''));
				target.append(lay.nodesOuterShell(homeNode));
			}else{
				$('div.navOuterShell').find('div.navNS_0').remove().end().find('div.noDes2').append(homeNode).bind('mouseleave', function(){
					$('div[id^=childrenLevelContainer_]').fadeOut(500);
				});
			}
		},
		renderFirstLevel: function(){
			var lay = LL_DropDownNavi.lay;
			var nodes = [];
			$(this.sitemap[1]).each(function(i){
				var node = this;
				if (typeof node == 'object' && typeof node.length != 'number'){
					var node = lay.nodeShell(node, lay.node(node))
					nodes.push(node);
				}
			});
			return lay.nodeChildrenShell(this.sitemap[0], nodes);
		},
		getChildren: function(id, level){
		},
		renderChildrenLayer: function(id, level){
			for (var i = 0; i < this.sitemap[1].length; i++){
				var node = this.sitemap[1][i];
				if (node.id == id){
					//if (i)
				}
			}
		},
		buildTreeFromArray: function(arr){
			var newArr = [];
			for (var i = 0; i < arr.length; i++){
				var data = arr[i];
				if (typeof data == 'object' && typeof data.length != 'number'){
					newArr.push(new Node(data));
				}else{
					newArr[newArr.length-1].children = this.buildTreeFromArray(data);
				}
			}
			return newArr;
		}
	}
/* << */


/* >> DEPRECATED */
	function hideInputBg(field)
	{
		ipField = document.getElementById(field);
		ipField.style.background = "#fff";
	}
/* << */


/* >> IE Refresh */
	function IE_Refresh(){
		if (document.all) location.reload();
	}
	window.onresize = IE_Refresh;
/* << */


/* >> Standard Popup functions Version: rel-1-0-0 */
	function StandardPopup(Attrs){
		// @params IE and Gecko-Browser compatible window parameter attributes.
		this.params = ['left', 'top', 'location', 'menubar', 'resizable', 'scrollbars', 'status', 'toolbar', 'height', 'width'];
		this.href = Attrs.href ? Attrs.href : 'http://www.google.de'; // url to the popup content
		this.name = Attrs.name ? Attrs.name : 'standardPopup'; // standard window name
		this.height = Attrs.height ? Attrs.height : '550'; // standard height opened window
		this.width = Attrs.width ? Attrs.width : '650'; // standard width opened window
		this.left = Attrs.left ? Attrs.left : null; // window left position from the upper left corner of the client screen
		this.top = Attrs.top ? Attrs.top : null; // window top position from the top of the client screen
		this.locationbar = Attrs.location ? Attrs.location : 'no'; // ['yes', 'no'] display the locationbar
		this.menubar = Attrs.menubar ? Attrs.menubar : 'no'; // ['yes', 'no'] display the menubar
		this.resizable = Attrs.resizable ? Attrs.resizable : 'yes'; // ['yes', 'no'] allows the user to change the window size
		this.scrollbars = Attrs.scrollbars ? Attrs.scrollbars : 'yes'; // ['yes', 'no'] show scrollbars if necessary
		this.status = Attrs.status ? Attrs.status : 'no'; // ['yes', 'no'] show statusbar
		this.toolbar = Attrs.toolbar ? Attrs.toolbar : 'no'; // ['yes', 'no'] show toolbar
		this.blank = Attrs.blank ? Attrs.blank : 'false'; // ['true', 'false'] show window as popup or blank window
		this.wRef = null // window reference to make changes on the opened windowe
	}
	
	StandardPopup.prototype._formatParams = function()
	{
		var str = '\'';
		var objParam;
		for (var i = 0; i < this.params.length; ++i){
			objParam = this.params[i] == 'location' ? 'locationbar' : this.params[i];
			p = eval("this." + objParam);
			if (p){
				str += this.params[i] + '=' + p + ',';
			}
		}
		str = str.substring(0, str.length -1);
		str += '\'';
		return str;
	}
	
	StandardPopup.prototype.open = function(){
		if (this.blank){
			this.wRef = window.open(this.href);
		}else{
			var paraStr = this._formatParams();
			this.wRef = window.open(this.href, this.name, paraStr);
		}
		if (this.wRef)
			this.wRef.focus();
		return false;
	}
/* << */


/* >> rss publisher, (requires jQuery 1.2.6) Version: rel-2-0-0 */
	RSSPublisher = {
		publishers: false,
		register: function(args){
			this.append(args);
		},
		append: function(args){
			var RSSObj = new RSS();
			RSSObj.target = args.target;
			RSSObj.source = args.source;
			RSSObj.tags = args.tags;
			RSSObj.descLength = args.descLength;
			RSSObj.descLengthEnding = args.descLengthEnding
			RSSObj.pubDateFormat = args.pubDateFormat;
			RSSObj.refresh = args.refresh;
			RSSObj.itemsCount = args.itemsCount ? args.itemsCount : 5;
			RSSObj.staticTest = args.staticTest;
			if (args.acceptMimeTypes && typeof args.acceptMimeTypes == 'object'){
				RSSObj.acceptMimeTypesCgiStr = this.createMimeTypeCgiStr(args.acceptMimeTypes);
			}
			if (typeof this.publishers != 'boolean'){
				this.publishers.push(RSSObj);
			}else{
				this.publishers = [RSSObj];
			}
			RSSObj.getSource();
		},
		createMimeTypeCgiStr: function(mtList){
			var str = '&mimetypes=';
			for (var i = 0; i < mtList.length; ++i){
				str += encodeURIComponent(this.strTrim(mtList[i])) + ',';
			}
			return str.substring(0, str.length -1);
		},
		strTrim: function(str){
			var ccSpace = 32;
			var ps = 0;
			var pe = 0;
			var psLock = false;
			var peLock = false;
			for (var i = 0; i < str.length; ++i){
				if (str.charCodeAt(i) == ccSpace){
					if (! psLock) ps++;
					if (str.charCodeAt(str.length - 1 - i) == ccSpace){
						if (! peLock) pe++;
					}else{
						peLock = true;
					}
				}else{
					psLock = true;
					if (str.charCodeAt(str.length - 1 - i) == ccSpace){
						if (! peLock) pe++;
					}else{
						peLock = true;
					}
				}
			}
			var string = str.substring(ps, str.length);
			return string.substring(0, str.length - pe - ps);
		}
	}


	function RSS(){
		this.root = $('<div></div>');
		this.target = null;
		this.source = null;
		this.tags = ['title', 'description'];
		this.descLength = null;
		this.descLengthEnding = 32;
		this.pubDateFormat = 2;
		this.refresh = null;
		this.itemsCount = null;
		this.staticTest = false;
		this.acceptMimeTypesCgiStr = null;
		this.charCount = 0;
		this.stop = false;
	}
	
	RSS.prototype.getSource = function(){
		this.charCount = 0;
		this.stop = false;
		this.root.empty();
		if (this.staticTest){
			var url = this.source;
		}else{
			var url = '/urlfetcher/?url=' + encodeURIComponent(this.source);
		}
		if (this.acceptMimeTypesCgiStr && ! this.staticTest) url += this.acceptMimeTypesCgiStr;
		var self = this;
		$.ajax({
			type: 'GET',
			url: url,
			success: function(data, msg){self.handleSource(data, msg)},
			error: function(req, status, error){self.handleSourceError(req, status, error)}
		});
		if (this.refresh) setTimeout(function(){self.getSource();}, this.refresh * 1000);
	}
	
	RSS.prototype.handleSource = function(data, msg){
		var xmlElements = data;
		var items = $('item', xmlElements);
		var count = items.size();
		if (this.itemsCount <= items.size()) count = this.itemsCount;
		var tags = this.tags;
		var self = this;
		for (var i = 0; i < count; ++i){
			var href = self.getLink(items.get(i));
			self.appendElement(self.getItem(items.get(i), tags, href, i), self.root);
		}
		this.publish();
	}
	
	RSS.prototype.handleSourceError = function(def){
		console.log(def.message);
		$('#' + this.target).html('<div>Service ist voruebergehend nicht verfuegbar.</div>');
	}
	
	RSS.prototype.appendElement = function(elm, root){
		if (elm){
			$(root).append(elm);
			return true;
		}
		return false;
	}

	RSS.prototype.cloneXML2DOM = function(src, tar, igRoot, len, correctHyphen){
		for (var i = 0; i < src.childNodes.length; i++){
			var node = src.childNodes[i];
			switch (node.nodeType){
				case 1:
					if (! igRoot){
						var newNode = tar.appendChild(document.createElement(node.nodeName));
						for (var j = 0; j < node.attributes.length; j++){
							newNode.setAttribute(node.attributes[j].nodeName, node.attributes[j].nodeValue);
						}
						this.cloneXML2DOM(node, newNode, false, correctHyphen);
						break;
					}else{
						this.cloneXML2DOM(node, tar, false, correctHyphen);
						break;
					}
				case 3:
					if (len){
						var text = node.nodeValue;
						if (this.charCount + text.length < len){
							this.charCount += text.length;
						}else{
							var pos = 0;
							var t = '';
							while(1){
								t += text.substr(pos, 1);
								if (t.length + this.charCount >= len){
									var cCode = t.charCodeAt(t.length -1);
									if (cCode == this.descLengthEnding || pos == t.length){
										this.charCount += t.length;
										if (cCode == this.descLengthEnding){
											t += cCode == 32 ? '....' : ' ....';
											this.stop = true;
										}else{
											this.stop = false;
										}
										text = t;
										break;
									}
								}else if(text.length + this.charCount < len){
									var cCode = text.charCodeAt(text.length -1);
									this.charCount += text.length;
									text += cCode == 32 ? '....' : ' ....';
									this.stop = true;
									break;
								}
								pos++;
							}
						}
					}else{
						text = node.nodeValue;
					}
					if (correctHyphen) text = this.correctHyphenatedText(text);
					subNode = document.createTextNode(text);
				tar.appendChild(subNode);
			}
			if (this.stop){
				this.charCount = 0;
				break;
			}
		}
	}
	
	RSS.prototype.correctHyphenatedText = function(text){
		return text.replace(/-/g, '- ');
	}
	
	RSS.prototype.cloneContent = function(src, len, correctHyphen){
		var root = $('<div></div>').get(0);
		if (len){
			this.charCount = 0;
			this.stop = false;
		}
		this.cloneXML2DOM(src, root, false, len, correctHyphen);
		return root.childNodes;
	}

	RSS.prototype.getFirstNodeMatch = function(nName, parent, type){
		var n = parent.childNodes;
		var nName = nName.toLowerCase();
		type = type ? type : 1;
		for (var i = 0; i < n.length; ++i){
			if (n[i].nodeType == type && n[i].nodeName.toLowerCase() == nName){
				return n[i];
			}
		}
		return false;
	}
	
	RSS.prototype.getLink = function(item){
		return $('link', item).text();
	}
	
	RSS.prototype.getItem = function(item, tags, href, count){
		var sty = count % 2 == 0 ? 'item' : 'item odd';
		var itemShell = $('<div></div>').attr({'class': sty}).get(0);
		for (var j = 0; j < tags.length; ++j){
			switch (tags[j]){
				case 'title':
					this.appendElement(this.getTitle(item, href), itemShell);
					break;
				case 'description':
					this.appendElement(this.getDescription(item), itemShell);
					break;
				case 'pubDate':
					this.appendElement(this.getPubDate(item), itemShell);
					break;
			}
		}
		return itemShell;
	}

	RSS.prototype.getTitle = function(item, href){
		var title = $('title', item).get(0);
		if (title && title.childNodes.length > 0){
			return Layout.getTitle(this.cloneContent(title, false, true), href);
		}
		return false;
	}
	
	RSS.prototype.getDescription = function(item){
		var description = $('description', item).get(0);
		if (description && description.childNodes.length > 0) {
			return Layout.getDescription(this.cloneContent(description, this.descLength, true));
		}
		return false;
	}
	
	RSS.prototype.getPubDate = function(item){
		var pubDate = $('pubDate', item).get(0);
		if (pubDate && pubDate.childNodes.length > 0) {
			var dateGMT = pubDate.childNodes[0].nodeValue;
			pubDate.childNodes[0].nodeValue = this.formatDate(dateGMT);
			return Layout.getPubDate(this.cloneContent(pubDate, false, false));
		}
		return false;
	}
	
	RSS.prototype.formatDate = function(dateStr){
		var lang = $('html').attr('lang');
		var date = $.getISODate(new Date(dateStr), lang);
		var time = $.getISOTime(new Date(dateStr));
		if (this.pubDateFormat == 1){
			return date._short;
		}else if (this.pubDateFormat == 2){
			return date._middle;
		}else if (this.pubDateFormat == 3){
			return date._long;
		}else if (this.pubDateFormat == 4){
			return date._long + ' ' + time;
		}
	}
	
	RSS.prototype.publish = function(){
		$('#' + this.target).empty().html($(this.root).html());
	}
	
	Layout = {
		getTitle: function(t, href){
			if (href) t = $('<a></a>').attr({'href': href, 'target': '_blank'}).append(t);
			return $('<div></div>').attr({'class': 'rssElementTitle'}).append(
				$('<h3></h3>').append($('<span></span>').append(t))
			).get(0);
		},
		getDescription: function(desc){
			return $('<div></div>').attr({'class': 'rssElementDesc'}).append(
				$('<div></div>').attr({'class': 'inner'}).append(desc)
			).get(0);
		},
		getPubDate: function(d){
			return $('<div></div>').attr({'class': 'rssElementPubDate'}).append(
				$('<span></span>').append(d)
			).get(0);
		}
	}
/* << */


/* >> Generic Multimedia CMS tool, (requires jQuery 1.2.6) Version: rel-2-0-0 */
	function GenericMultimedia(args){
		this.lang = this.getLang();
		this.altText = args.altText;
		this.altImg = args.altImg;
		this.data = args.data;
		this.htmlSrcDom = this.getHtmlSrcDom(args.htmlSrc);
		this.javaApplet = this.isJavaApplet();
		this.modifyAndWriteDocumentElements();
	}
	
	GenericMultimedia.prototype.getLang = function(){
		var htmlEl = $('html');
		if (htmlEl.attr('lang')){
			return this.formatLang(htmlEl.attr('lang'));
		}else if(htmlEl.attr('xml:lang')){
			return this.formatLang(htmlEl.attr('xml:lang'));
		}
		return 'en';
	}
	
	GenericMultimedia.prototype.formatLang = function (lang){
		if (lang.search(/-/) > -1) return lang.substring(0, lang.search(/-/));
		return lang;
	}
	
	GenericMultimedia.prototype.getHtmlSrcDom = function(htmlSrc){
		if (typeof htmlSrc == 'string' && htmlSrc.length > 0){
			return $('<div><xml>' + htmlSrc + '</xml></div>').get(0);
		}
		return null;
	}
	
	GenericMultimedia.prototype.isJavaApplet = function(){
		var isJavaApp = false;
		$('xml > *', this.htmlSrcDom).each(
			function(n){
				if (this.nodeType == 1 && this.nodeName.toLowerCase() == 'object'){
					if($(this).attr('classid')){
						isJavaApp = $(this).attr('classid').search('java:') > -1;
					}
				}
			}
		);
		return isJavaApp;
	}
	
	GenericMultimedia.prototype.modifyAndWriteDocumentElements = function(){
		var output = '';
		var onlyEmbed = false;
		var model;
		var self = this;
		$('xml > *', this.htmlSrcDom).each(
			function(n){
				if (self.javaApplet || (! self.useEmbed() && ! self.javaApplet)){
					if (this.nodeType == 1 && this.nodeName.toLowerCase() == 'object'){
						model = false;
						output += self.startElement('object', self.getNodeAttributes(this), model);
						$('*', this).each(
							function(n){
								if (this.nodeType == 1 && this.nodeName.toLowerCase() == 'param'){
									model = true;
									output += self.startElement('param', self.getNodeAttributes(this), model);
								}
								if (this.nodeType == 1 && this.nodeName.toLowerCase() == 'embed'){
									model = true;
									output += self.startElement('embed', self.getNodeAttributes(this), model);
								}
							}
						);
					}
				}else{
					onlyEmbed = true;
					$('param, embed', this).each(
						function(n){
							if (this.nodeType == 1 && this.nodeName.toLowerCase() == 'embed'){
								model = true;
								output += self.startElement('embed', self.getNodeAttributes(this), model);
							}
						}
					);
				}
				if (self.altText || self.altImg){
					var text = '';
					var img = '';
					if (self.altText) var text = '<p>' + self.altText + '</p>';
					if (self.altImg) var img = '<img src="' + self.altImg + '" alt="" title="" />';
					if (!$.browser.safari){ //Workarround for safari 3.2.1 which interpreted the standard wrong.
						if (self.useEmbed() && ! self.javaApplet){
							output += '<noembed>' + text + img + '</noembed>';
						}else{
							output += text + img;
						}
					}
				}
				if (! onlyEmbed) output += self.endElement('object');
			}
		);
		document.write(output);
		
		
		
		/*var elms = this.htmlSrcDom.childNodes[0].childNodes;
		var onlyEmbed = false;
		var model;
		if (elms.length > 0){
			for (var i = 0; i < elms.length; ++i){
				var node = elms[i];
				var name = elms[i].nodeName.toLowerCase();
				var type = elms[i].nodeType;
				if (this.javaApplet || (! this.useEmbed() && ! this.javaApplet)){
					if (type == 1 && name == 'object'){
						model = false;
						output += this.startElement('object', this.getNodeAttributes(node), model);
						var objChilds = node.childNodes;
						for (var j = 0; j < objChilds.length; ++j){
							node = objChilds[j];
							name = objChilds[j].nodeName.toLowerCase();
							type = objChilds[j].nodeType;
							if (type == 1 && name == 'param'){
								model = true;
								output += this.startElement('param', this.getNodeAttributes(node), model);
							}
							if (type == 1 && name == 'embed'){
								model = true;
								output += this.startElement('embed', this.getNodeAttributes(node), model);
							}
						}
					}
				}else{
					onlyEmbed = true;
					var objChilds = node.childNodes;
					for (var j = 0; j < objChilds.length; ++j){
						node = objChilds[j];
						name = objChilds[j].nodeName.toLowerCase();
						type = objChilds[j].nodeType;
						if (type == 1 && name == 'embed'){
							model = true;
							output += this.startElement('embed', this.getNodeAttributes(node), model);
						}
					}
				}
			}
			if (this.altText || this.altImg){
				if (this.altText) var text = '<p>' + this.altText + '</p>';
				if (this.altImg) var img = '<img src="' + this.altImg + '" alt="" title="" />';
				if (this.useEmbed() && ! this.javaApplet){
					output += '<noembed>' + text + img + '</noembed>';
				}else{
					output += text + img;
				}
			}
			if (! onlyEmbed) output += this.endElement('object');
		}
		document.write(output);*/
	}
	
	GenericMultimedia.prototype.useEmbed = function(){
		var agent = navigator.userAgent;
		if (agent.search(/MSIE | Safari/) > -1) return false;
		return true;
	}
	
	GenericMultimedia.prototype.getNodeAttributes = function(node){
		var name = node.nodeName.toLowerCase();
		var codebase = false;
		if (node.attributes.length > 0){
			var attrs = {};
			var attrValue = '';
			for (var i = 0; i < node.attributes.length; ++i){
				var attrName = node.attributes[i].nodeName.toLowerCase();
				var attrValue = node.attributes[i].nodeValue;
				if (name == 'object' && (attrName == 'classid' || attrName == 'movie' || attrName == 'data')){
					if (attrName == 'classid'){
						attrs[attrName] = this.makeClassidAttribute(attrValue);
					}else if (this.javaApplet && attrName == 'codebase'){
						codebase = true;
						attrs[attrName] = this. makeJavaAppletCodebaseAttribute();
					}else{
						if (attrName == 'codebase') codebase = true;
						attrs[attrName] = this.data + this.copyCgiArgs(attrValue);
					}
				}else if (name == 'embed' && attrName == 'src'){
					attrs[attrName] = this.data + this.copyCgiArgs(attrValue);
				}else{
					attrs[attrName] = attrValue;
				}
			}
			if (this.javaApplet && ! codebase){
						codebase = true;
						attrs['codebase'] = this. makeJavaAppletCodebaseAttribute();
			}
			if (name == 'param'){
				attrNameValue = attrs.name.toLowerCase();
				attrValueValue = attrs.value;
				if (attrNameValue == 'filename' || attrNameValue == 'movie' || attrNameValue == 'src'){
					attrs.value = this.data + this.copyCgiArgs(attrValueValue);
				}
			}
			return attrs;
		}
		return null;
	}
	
	GenericMultimedia.prototype.copyCgiArgs = function(value){
		if (value.lastIndexOf('?') > -1){
			return value.substring(value.lastIndexOf('?'), value.length);
		}
		return '';
	}
	
	GenericMultimedia.prototype.startElement = function(name, attrs, single){
		var element = '<' + name;
		for (var attrName in attrs){
			element += ' ' + attrName + '="' + attrs[attrName] + '"';
		}
		if (single) return element += '/>';
		return element += '>';
	}

	GenericMultimedia.prototype.endElement = function(name){
		return '</' + name + '>';
	}

	GenericMultimedia.prototype.makeClassidAttribute = function(value){
		var data = this.data;
		if (value.search('java:') > -1){
			return 'java:' + data.substring(data.lastIndexOf('/') +1, data.length) + this.copyCgiArgs(value);
		}
		return value;
	}
	
	GenericMultimedia.prototype.makeJavaAppletCodebaseAttribute = function(){
		var data = this.data;
		return data.substring(0, data.lastIndexOf('/') +1);
	}
/* << */


/* >> bookmarking tool (requires jQuery 1.2.6 and ll StandardPopup) Version: rel-2-0-0 */
	function BookmarkStoreAt(args){
		this.targetName = null;
		this.container = null;
		this.titleHTML = null;
		this.textHTML = null;
		this.descSliceStandard = ' ...';
		this.imgPath = null;
		this.bmItems = ['delicious', 'mrwong', 'blinklist', 'yahoo', 'yigg', 'furl', 'oneview', 'folkd', 'linkarena', 'google', 'webnews'];
		this.bmURL = null;
		this.bmTitle = null;
		this.bmTargets = {};
		this.init(args);
	}
	
	BookmarkStoreAt.prototype.init = function(args){
		this.targetName = args.targetName;
		if ($('#' + args.targetName).size() > 0) this.container = $('#' + args.targetName);
		if (args.bmItems) this.bmItems = args.bmItems;
		this.imgPath = args.imgPath;
		this.titleHTML = args.titleHTML;
		this.textHTML = args.textHTML;
		this.bmURL = encodeURIComponent(location.href);
		this.bmTitle = encodeURIComponent(document.title);
		this.bmTargets['delicious'] = {'title': 'del.icio.us', 'desc': 'del.icio.us', 'url': 'http://del.icio.us/post?url=' + this.bmURL + '&title=' + this.bmTitle};
		this.bmTargets['mrwong'] = {'title': 'Mister Wong', 'desc': 'Mister Wong', 'url': 'http://www.mister-wong.de/index.php?action=addurl&bm_url=' + this.bmURL + '&bm_description=' + this.bmTitle};
		this.bmTargets['blinklist'] = {'title': 'BlinkList', 'desc': 'BlinkList', 'url': 'http://www.blinklist.com/index.php?Action=Blink/addblink.php&Description=&Url=' + this.bmURL + '&Title=' + this.bmTitle};
		this.bmTargets['yahoo'] = {'title': 'Yahoo MyWeb', 'desc': 'Yahoo MyWeb', 'url': 'http://myweb2.search.yahoo.com/myresults/bookmarklet?u=' + this.bmURL + '&t=' + this.bmTitle};
		this.bmTargets['yigg'] = {'title': 'YiGG', 'desc': 'YiGG', 'url': 'http://yigg.de/neu?exturl=' + this.bmURL + '&exttitle=' + this.bmTitle};
		this.bmTargets['furl'] = {'title': 'Furl', 'desc': 'Furl', 'url': 'http://www.furl.net/storeIt.jsp?u=' + this.bmURL + '&t=' + this.bmTitle};
		this.bmTargets['oneview'] = {'title': 'OneView', 'desc': 'OneView', 'url': 'http://beta.oneview.de:80/quickadd/neu/addBookmark.jsf?URL=' + this.bmURL + '&title=' + this.bmTitle};
		this.bmTargets['folkd'] = {'title': 'Folkd', 'desc': 'Folkd', 'url': 'http://www.folkd.com/submit/page/' + this.bmURL};
		this.bmTargets['linkarena'] = {'title': 'Linkarena', 'desc': 'Linkarena', 'url': 'http://linkarena.com/bookmarks/addlink/?url=' + this.bmURL + '&title=' + this.bmTitle + '&desc=&tags='};
		this.bmTargets['google'] = {'title': 'Google', 'desc': 'Google', 'url': 'http://www.google.com/bookmarks/mark?op=add&hl=de&bkmk=' + this.bmURL + '&title=' + this.bmTitle};
		this.bmTargets['webnews'] = {'title': 'Webnews', 'desc': 'Webnews', 'url': 'http://www.webnews.de/einstellen?url=' + this.bmURL + '&title=' + this.bmTitle};
		this._createLayout();
	}

	BookmarkStoreAt.prototype.store = function(target){
		this.open(this.bmTargets[target].url);
	}
	
	BookmarkStoreAt.prototype.open = function(url){
		if (typeof StandardPopup == 'function'){
			var p = new StandardPopup({'href': url, 'blank': true})
			p.open();
		}else{
			window.open(url);
		}
	}
	
	BookmarkStoreAt.prototype.changeDescSlice = function(key){
		var el = '#bmDescSlice_' + this.targetName;
		var slice = this.descSliceStandard;
		if (key) slice = '<span>' + this.bmTargets[key].desc + '</span>';
		$(el).html(slice);
	}
	
	BookmarkStoreAt.prototype._getTitle = function(){
		return $('<div class="bookmarkTitleOuter"><h3>' + this.titleHTML + '</h3></div>');
	}

	BookmarkStoreAt.prototype._getText = function(){
		return $(
			'<div class="bookmarkTextOuter"><p>' +
			this.textHTML + '<span id="bmDescSlice_' +
			this.targetName + '" class="bmDescSlice">' +
			this.descSliceStandard + '</span></p></div>'
		);
	}

	BookmarkStoreAt.prototype._getImageItems = function(){
		var bmi = this.bmItems;
		var imgOuter = $('<div class="imgOuter"></div>');
		var img;
		var self = this;
		for (var i = 0; i < bmi.length; ++i){
			function x(bmImgId){
				img = $('<img/>').attr({
						'src': self.imgPath + '/' + bmImgId + '.gif',
						'alt': self.bmTargets[bmImgId].title,
						'title': self.bmTargets[bmImgId].title
				}).click(
					function(e){self.store(bmImgId)}
				);
				if (self.textHTML.length > 0){
					img.mouseover(
						function(e){self.changeDescSlice(bmImgId)}
					).mouseout(
						function(e){self.changeDescSlice(false)}
					);
				}
				return img;
			};
			imgOuter.append(x(bmi[i]));
		}
		return imgOuter;
	}

	BookmarkStoreAt.prototype._createLayout = function(){
		var outer = $('<div id="bookmarksOuter"></div>');
		if (this.titleHTML.length > 0) outer.append(this._getTitle());
		if (this.textHTML.length > 0) outer.append(this._getText());
		outer.append(this._getImageItems());
		this.container.append(outer);
	}
/* << */


/* >> login teaser (requires jQuery 1.2.6) Version: rel-2-0-0 */
	function handleFieldPrompt(fieldList){
		$(function(){
			for (var i = 0; i < fieldList.length; ++i){
				function x(f){
					var elm = $('#' + f);
					if (elm.length === 0) {
						elm = $(f);
					}
					elm.focus(
						function(e){hidePrompt($(this), e)}
					).blur(
						function(e){
							if ($(this).val() == ''){
								showPrompt($(this), e)
							}
						}
					)
					if (elm.val() != '') hidePrompt(elm);
				}
				x(fieldList[i]);
			}
		});
	}
	
	function hidePrompt(field, e){
		field.css({'background-image': 'none'});
	}

	function showPrompt(field, e){
		field.removeAttr('style');
	}
/* << */


/* >> client current date (requires jQuery 1.2.6) Version: rel-2-0-0 */
	function getCurrentDate(id){
		$(function(){
			//getElement(id).innerHTML = '';
			var week = ['Sonntag', 'Montag', 'Dienstag', 'Mittwoch', 'Donnerstag', 'Freitag', 'Samstag'];
			//var month = ['Januar', 'Februar', 'März', 'April', 'Mai', 'Juni', 'Juli', 'August', 'September', 'Oktober', 'November', 'Dezember'];
			var date = new Date();
			var d = week[date.getDay()];
			var dom = date.getDate();
			//var m = month[date.getMonth()];
			var m = date.getMonth()+1;
			var y = date.getFullYear();
			var std = date.getHours();
			var min = date.getMinutes();
			var sec = date.getSeconds();
			//if (dom < 10) dom = '0' + dom;
			if (min < 10) min = '0' + min;
			if (sec < 10) sec = '0' + sec;
			var timeSection = $('<span class="timeSection"><span class="inner"></span></span>');
			var timeSectionInner = timeSection.find('.inner');
			timeSectionInner.append('<span class="sepYT">|</span>')
				.append('<span class="hour">' + std + '</span>')
				.append('<span class="sepHM">:</span>')
				.append('<span class="min">' + min + '</span>')
				//.append('<span class="sepHM">:</span>')
				//.append('<span class="sec">' + sec + '</span>')
				.append('<span class="clock">CEST</span>')
			$('#' + id).empty().append(
				$('<div></div>')
					//.append('<span class="weekday">' + d + '</span>')
					//.append('<span class="sepWD">,</span>')
					//.append('<span class="text">den </span>')
					.append('<span class="day">' + dom + '.</span>')
					.append('<span class="month">' + m + '.</span>')
					.append('<span class="year">' + y + '</span>')
					.append(timeSection)
			)
			setTimeout(function(){getCurrentDate(id)}, 1000);
		});
	}
/* << */


/* >> LL_TableColumnEnhancer (require jQuery 1.2.6) Version: rel-2-0-0 */
	LL_TableColumnEnhancer = function(){
		this.table = null;
		this.colConfig = [0,1,2,-3,-2,-1];
		this.tableFullWidth = 0;
		this.tableFullHeight = 0;
		this.tableCurrentWidth = 0;
		this.tableCurrentHeight = 0;
		this.variantsWidth = 0;
		this.variantsHeight = 0;
		this.moved = false;
		this.columns = []; // holds to hide columns with there cells
		this.idOuter = null;
		$('#variants').hide();
	}
	
	LL_TableColumnEnhancer.prototype.setColumnConfig = function(){
		if (arguments.length > 0){
			var conf = [];
			for (var i = 0; i < arguments.length; ++i){
				if (! isNaN(parseInt(arguments[i]))) conf.push(arguments[i]);
			}
			if (conf.length > 0) this.colConfig = conf;
			return this.colConfig;
		}
		return null;
	}
	
	LL_TableColumnEnhancer.prototype.init = function(id, idOuter, display){
		var t = $('#' + id).get(0);
		this.idOuter = idOuter;
		var columnsIndex = [];
		var self = this;
		if (t.nodeName.toLowerCase() == 'table'){
			this.table = t;
			this.tableFullWidth = t.offsetWidth;
			this.tableFullHeight = t.offsetHeight;
			var tbody = this.getElementChildNodeWithName(t, 'tbody', null);
			for (var i = 0; i < this.getElementChildNodesCount(tbody, 1); ++i){
				var row = this.getElementChildNodeWithName(tbody, 'tr', i);
				for (var j = 0; j < this.getElementChildNodesCount(row, 1); ++j){
					columnsIndex = this.getColumnsIndex(this.getElementChildNodesCount(row, 1), this.colConfig);
					var cell = this.getElementChildNodeWithName(row, 'td', j);
					if (! this._inArray(j, columnsIndex)){
						if (this.columns[j] instanceof DefaultTableColumn){
							this.columns[j].addCell(cell);
						}else{
							this.columns[j] = new DefaultTableColumn(j);
							this.columns[j].addCell(cell);
						}
					}
				}
			}
		}
		$('#variantsButtons').show();
		this.updateDisplay(display);
		$('#variantsViewAllButton').click(function(e){self.openInlinePopup()});
		$('#variantsViewLessButton').click(function(e){self.closeInlinePopup()});
		$('#variants').show();
		this.tableCurrentWidth = this.getContentAreaDimensions().w;
		this.tableCurrentHeight = t.offsetHeight;
		this.variantsWidth = $('#' + this.idOuter).width();
		this.variantsHeight = $('#' + this.idOuter).height();
	}

	LL_TableColumnEnhancer.prototype.getContentAreaDimensions = function(){
		var ca, dims;
		ca = $('td.contentColumn');
		return {'w': ca.width(), 'h': ca.height()};
	}
	
	LL_TableColumnEnhancer.prototype.openInlinePopup = function(){
		var contOrig = $('#variantsOuterShell');
		var cont = $('#variantsPopupContainer');
		var elm = $('#' + this.idOuter);
		if (elm){
			cont.empty().append(elm);
			contOrig.empty().append(
				$('<img/>').attr({
					'src': '/xist4c/px/spc.gif',
					'height': this.variantsHeight + 32,
					'width': 1,
					'class': 'variantsDvShellDummy'
				})
			);
			this.updateDisplay(true);
			$('#variantsInlinePopupOuter').show();
			this.tableFullWidth = this.table.offsetWidth;
			if (this.tableFullWidth <= this.tableCurrentWidth){
				this.tableFullWidth = this.tableCurrentWidth;
				setNodeAttribute(this.table, 'style', {'width': this.tableCurrentWidth + 'px'});
			}
			var distance = ((this.tableFullWidth - this.tableCurrentWidth) / 2) + 12;
			$('#variantsPopupShell').css('left', '-' + distance + 'px');
			this.moved = true;
			var self = this;
			$('#variantsViewLessButton').click(function(e){self.closeInlinePopup()});
		}
	}
	
	LL_TableColumnEnhancer.prototype.closeInlinePopup = function(){
		var cont = $('#variantsOuterShell').get(0);
		$('#variantsInlinePopupOuter').hide();
		var elm = $('#' + this.idOuter);
		if (elm.size() > 0){
			this.updateDisplay(false);
			cont.replaceChild(elm.get(0), this.getElementChildNodeWithName(cont, 'img', null));
		}
		var self = this;
		$('#variantsViewAllButton').click(function(e){self.openInlinePopup()});
	}

	LL_TableColumnEnhancer.prototype.updateDisplay = function(display, e){
		if (e) e.stop();
		this.hidden = true;
		if (display) this.hidden = false;
		for (var i = 0; i < this.columns.length; ++i){
			var col = this.columns[i];
			if (col instanceof DefaultTableColumn) col.setDisplay(display);
		}
		if (this.hidden){
			$('#variantsViewAllButton').css({'display': 'inline'});
			$('#variantsViewLessButton').css({'display': 'none'});
		}else{
			$('#variantsViewAllButton').css({'display': 'none'});
			$('#variantsViewLessButton').css({'display': 'inline'});
		}
	}
	
	LL_TableColumnEnhancer.prototype._inArray = function(needle, arr){
		for (var i = 0; i < arr.length; ++i){
			if (needle == arr[i]) return true;
		}
		return false;
	}
	
	LL_TableColumnEnhancer.prototype.getElementChildNodeWithName = function(parent, name, pos){
		var pos = pos ? pos : 0;
		var count = 0;
		var childs = parent.childNodes;
		if (childs){
			for (var i = 0; i < childs.length; ++i){
				var c = childs[i];
				if (c.nodeType == 1){
					var nname = c.nodeName.toLowerCase();
					var n = name.toLowerCase();
					if (n = nname && count == pos) return c;
					++count;
				}
			}
		}
		return null;
	}
	
	LL_TableColumnEnhancer.prototype.getElementChildNodesCount = function(parent, type){
		var childs = parent.childNodes;
		var count = 0;
		if (childs){
			for (var i = 0; i < childs.length; ++i){
				var c = childs[i];
				if (c.nodeType == type) ++count;
			}
		}
		return count;
	}

	LL_TableColumnEnhancer.prototype.getColumnsIndex = function(colCount, permCols){
		for (var i = 0; i < permCols.length; ++i){
			if (permCols[i] < 0) permCols[i] += colCount;
		}
		return permCols;
	}


	DefaultTableColumn = function(cid){
		this.cid = cid;
		this.cells = [];
		this.hidden = false;
	}
	
	DefaultTableColumn.prototype.addCell = function(Cell){
		if (Cell.nodeName.toLowerCase() == 'td' || Cell.nodeName.toLowerCase() == 'th'){
			this.cells.push(new DefaultTableCell(Cell));
		}
	}
	
	DefaultTableColumn.prototype.setDisplay = function(display){
		this.hidden = true;
		if (display) this.hidden = false;
		for (var i = 0; i < this.cells.length; ++i){
			this.cells[i].setDisplay(display);
		}
	}


	DefaultTableCell = function(domel){
		this.domel = domel;
		this.hidden = false;
		this.attrs = {};
		this.children = null;
		this.content = null;
		this._backupAttrsAndChildren();
		this._backupContent();
	}
	
	DefaultTableCell.prototype._backupAttrsAndChildren = function(){
		var elm = this.domel;
		this.children = elm.childNodes;
		for (var i = 0; i < elm.attributes.length; ++i){
			var attr = elm.attributes[i];
			var name = attr.nodeName;
			var value = attr.nodeValue;
			this.attrs[name] = value;
		}
	}
	
	DefaultTableCell.prototype._backupContent = function(){
		var node = this.domel;
		while (node.nodeType == 1){
			node = node.childNodes[0];
			if (node && node.nodeType == 3){
				this.content = node.nodeValue;
				break;
			}else{
				if (! node) break;
			}
		}
	}
	
	DefaultTableCell.prototype.setDisplay = function(display){
		if (display){
			this.hidden = false;
			$(this.domel).css({'display': ''});
			return true;
		}
		this.hidden = true;
		$(this.domel).css({'display': 'none'});
		return true;
	}
/* << */


/* >> LL_CookieTool (require jQuery 1.2.6+) Version: rel-1-1-0  **-Deprecated-** use jquery cookie plugin instead */
	LL_CookieTool = {
		isCookieEnabled: function(){
			if (navigator.cookieEnabled == true) return true;
			return false;
		},
		setCookies: function(cObjs){
			for (var i = 0; i < arguments.length; ++i){
				var c = arguments[i];
				c.setCookie();
			}
		},
		getCookie: function(name){
			var cstr = document.cookie;
			if (cstr.length > 0){
				cookies = cstr.split('; ');
				for (var i = 0; i < cookies.length; ++i){
					var cook = cookies[i];
					if (cook.substring(0, cook.lastIndexOf('=')) == name){
						return cook.substring(cook.lastIndexOf('=') + 1 , cook.length);
					}
				}
			}
			return null;
		},
		eraseCookie: function(name, domain, path){
			var c = new CookieData(name, null, domain, path, null, null);
			c.eraseCookie();
		}
	}
	
	CookieData = function(name, value, domain, path, expires, secure){
		this.name = name;
		this.value = value;
		this.domain = domain;
		this.path = path;
		this.expires = expires;
		this.secure = secure;
	}
	
	CookieData.prototype.setCookie = function(){
		var cook = this.name + '=' + unescape(this.value);
		cook += this.domain ? '; domain=' + this.domain : '';
		cook += this.expires ? '; expires=' + this.expires : '';
		cook += this.path ? '; path=' + this.path : '/';
		cook += this.secure ? '; secure' : '';
		document.cookie = cook;
	}
	
	CookieData.prototype.eraseCookie = function(){
		var cook = this.name + '=; expires=Thu, 01-Jan-70 00:00:01 GMT';
		cook += this.domain ? '; domain=' + this.domain : '';
		cook += this.path ? '; path=' + this.path : '/';
		document.cookie = cook;
	}
/* << */


/* >> LL_FontSizeAdjust (require jQuery 1.2.6, plugins: cookie 1.0) Version: rel-2-0-0 */
	LL_FontSizeAdjust = {
		symbols: [],
		currentFS: 0,
		domain: location.hostname,
		customerPath: 'standard/xx/',
		coId: -1,
		init: function(path, coId){
			// path: Specifies the image and css path
			// coId: The content object id of a special startpage with different css rules.
			if (coId) this.coId = coId;
			this.connectAndGetSymbols();
			this.setCustomerPath(path);
			this.handleFontSize(this.getFontSize());
		},
		connectAndGetSymbols: function(){
			var self = this;
			$('div[id*=font_adjust_symbol_]').each(
				function(n){
					self.symbols.push(this);
					$(this).click(function(){self.handleFontSize(n)});
				}
			);
		},
		setCustomerPath: function(path){
			var p = path ? path : this.customerPath;
			this.customerPath = p;
		},
		getFontSize: function(){
			var size = $.cookie('FontSizeAdjust');
			if (size) return size;
			return this.currentFS;
		},
		setFontSize: function(size){
			$.cookie('FontSizeAdjust', size, {path: '/', expires: 100});
			return size;
		},
		isStartpage: function(){
			var ps = location.href.search(/_id_/);
			if (ps > -1){
				var url = location.href;
				var slice1 = url.substring(ps + 4, url.length);
				var coId = slice1.substring(0, slice1.indexOf('_'));
				if (this.coId == coId) return true;
				return false;
			}
			return false;
		},
		handleFontSize: function(size, e){
			if (navigator.cookieEnabled){
				this.currentFS = this.setFontSize(size);
				var head = $('head').get(0);
				$('#fontSizeAdjustCssLink').remove();
				$('#fontSizeAdjustCssLink_startpage').remove();
				var l1 = document.createElement('link');
				l1.href = this.customerPath + 'layout_fontSize' + this.currentFS + '.css';
				l1.type = 'text/css';
				l1.rel = 'stylesheet';
				l1.id = 'fontSizeAdjustCssLink';
				head.appendChild(l1);
				if(this.isStartpage()){
					var l2 = document.createElement('link');
					l2.href = this.customerPath + 'layout_fontSizeStartpage' + this.currentFS + '.css';
					l2.type = 'text/css';
					l2.rel = 'stylesheet';
					l2.id = 'fontSizeAdjustCssLink_startpage';
					head.appendChild(l2);
				}
			}
			this.switchStyleSheet(this.currentFS);
		},
		switchStyleSheet: function(size){
			// change the stylesheet element at the head element.
			if (this.symbols.length > 0){
				for (var i = 0; i < this.symbols.length; ++i){
					var s = this.symbols[i];
					if (i == size){
						this.updateSymbol(s, 'act');
					}else{
						this.updateSymbol(s, 'pass');
					}
				}
			}
		},
		updateSymbol: function(sym, status){
			var className = sym.className;
			var pref = className.substring(0, className.lastIndexOf('_') + 1);
			var suff = className.substring(className.lastIndexOf('_') + 1, className.length).toLowerCase();
			if (status){
				sym.className = pref + status;
				return sym;
			}else{
				if (suff == 'pass'){
					sym.className = pref + 'act';
					return sym;
				}
				sym.className = pref + 'pass';
				return sym;
			}
			return null;
		},
		handleSymbolStyle: function(){
			// switch the symbol css rules to get an active or passive symbol.
		}
	}
/* << */


/* >> LL_RelationshipManager (require jQuery 1.2.6+) Version: rel-2-0-0 */
	LL_RelationshipManager = function(){
		this.relHandler = [];
	}
	
	LL_RelationshipManager.prototype.addRelHandler = function(Handler){
		if (Handler instanceof DefaultRelationHandler){
			this.relHandler.push(Handler);
			if (Handler.elms.length > 0 && Handler.autoAction) Handler.action();
		}
	}

	// abstract relation handler
	DefaultRelationHandler = function(){
		this.name = 'testDefaultHandler';
		this.links = document.links;
		this.autoAction = false;
		this.filter(this.name);
		this.elms = []; // holds the elements and the rel attrs as a json object
	}
	
	// filter links wih rels with a given name and allocates the attributes.
	DefaultRelationHandler.prototype.filter = function(name){
		var links = this.links;
		for (var i = 0; i < links.length; ++i){
			this.addElementAndGetRelAttrs(links[i]);
		}
	}
	
	DefaultRelationHandler.prototype.addElementAndGetRelAttrs = function(elm){
		var attr = $(elm).attr('rel');
		if (attr){
			if (attr.toLowerCase() == this.name || attr.substring(0, attr.indexOf('[')).toLowerCase() == this.name){
				var relAttrs = null;
				if (attr.search(/\[/) > -1 && attr.search(/\]/) > -1){
					relAttrs = attr.substring(attr.indexOf('[') + 1, attr.lastIndexOf(']'));
					relAttrs = relAttrs.split(',');
				}
				var obj = {'elm': elm, 'relAttrs': relAttrs};
				this.elms.push(obj);
				return obj;
			}
		}
		return null;
	}
	
	DefaultRelationHandler.prototype.action = function(){} // do something with the rels


	// Use the xpopup functionality to display detail information
	XPopupHandler = function(){
		this.name = 'xpopup';
		this.autoAction = true;
		this.filter(this.name);
	}
	XPopupHandler.prototype = new DefaultRelationHandler();
	
	XPopupHandler.prototype.action = function(){
		var self = this;
		setTimeout(
			function(){
				for (var i = 0; i < self.elms.length; ++i){
					var TAttrs = {};
					var TAttrsArr = [];
					var elm = self.elms[i].elm;
					var eAttrs = self.elms[i].relAttrs;
					if (eAttrs && eAttrs.length == 6){
						TAttrs.url = elm.href;
						TAttrs.height = 'auto';
						TAttrs.width = 'auto';
					}else{
						var TAttrsRaw = eAttrs.slice(6);
						for (var j = 0; j < TAttrsRaw.length; ++j){
							var TAttrRawSplitted = TAttrsRaw[j].split(',');
							for (var k = 0; k < TAttrRawSplitted.length; ++k){
								var tAttrRaw = TAttrRawSplitted[k];
								var key = tAttrRaw.substring(0, tAttrRaw.indexOf(':'));
								var value = tAttrRaw.substring(tAttrRaw.indexOf(':') + 1, tAttrRaw.length);
								TAttrs[key] = value;
							}
						}
						if (! TAttrs.url) TAttrs.url = elm.href;
					}
					LL_XPopup.registerPopup(
						elm,
						eAttrs[0],
						eAttrs[1],
						eAttrs[2],
						eAttrs[3],
						eAttrs[4],
						eAttrs[5],
						TAttrs
					);
				}
			},
			10
		);
	}
	
	// use the xpopup to display lightbox photogalleries
	LightboxHandler = function(){
		this.name = 'lightbox';
		this.autoAction = true;
		this.filter(this.name);
	}
	LightboxHandler.prototype = new DefaultRelationHandler();
	
	LightboxHandler.prototype.action = function(){
		var self = this;
		setTimeout(
			function(){
				for (var i = 0; i < self.elms.length; ++i){
					var TAttrs = {};
					var TAttrsArr = [];
					var elm = self.elms[i].elm;
					var eAttrs = self.elms[i].relAttrs;
					if (eAttrs && eAttrs.length == 1){
						TAttrs.group = eAttrs[0];
					}
					TAttrs.url = elm.href;
					TAttrs.background = 'true';
					TAttrs.fixedPosition = 'true';

					LL_XPopup.registerPopup(
						elm,
						'click',
						'IMAGE',
						'p_c',
						'c',
						0,
						0,
						TAttrs
					);
				}
			},
			10
		);
	}
/* << */


/* >> LL_XPopup (require jQuery 1.2.6 and LL_RelationshipManager with XPopupHandler) Version: rel-2-0-1 */
	/*
		Possible positions for the source and popup element:
		nw, w, sw, n, c, s, ne, e, se, p_nw, p_w, p_sw, p_n, p_c, p_s, p_ne, p_e, p_se, cursor (only for the source element)
		
		possible types: IMAGE, WEBPAGE, AJAX
			IMAGE: Display images in a special gallery mode.
			WEBPAGE: Sisplay a web page in an iframe.
			AJAX: Load ajax-content into a div container with a given url.
		
		Example for rel-Attributes: xpopup[onmouseenter,WEBPAGE,ne,nw,10,10,height:300,width:200]
			identfier[event, type, source position, popup position, popup margin width, popup margin height,--mode attributes--]
			--mode attributes--:
				A commata separated list with key:value items.
				Note: Each mode can have different attributes.
	*/
	LL_XPopup = {
		xpopups: [],
		popup: null,
		initScrollPos: 0,
		preparedGallery: [],
		currentGalleryIdx: -1,
		galleryOverall: -1,
		slideshowBusy: 0,
		slideshowInterval: null,
		nextConnect: null,
		previousConnect: null,
		closeConnect: null,
		registerPopup: function(elm, event, type, spos, ppos, margin_w, margin_h, TypeAttrs, callback){
			//type = 'AJAX';
			var self = this, cb = callback || null;
			setTimeout(function(){self.makePopup()}, 1);
			switch (type){
				case 'IMAGE':
					this.xpopups.push(new ImageXPopup(elm, event, spos, ppos, margin_w, margin_h, TypeAttrs, cb));
					break;
				case 'WEBPAGE':
					this.xpopups.push(new WebpageXPopup(elm, event, spos, ppos, margin_w, margin_h, TypeAttrs, cb));
					break;
				case 'AJAX':
					this.xpopups.push(new AjaxXPopup(elm, event, spos, ppos, margin_w, margin_h, TypeAttrs, cb));
					break;
			}
		},
		makePopup: function(){
			if (! this.popup){
				this.popup = $('<div></div>').append(
						this.makeCloseButton()
					).append(
						$('<div>').attr(
							{'id': 'xpopupContent'}
						)
					).append(
						$('<div>').attr(
							{'id': 'xpopupAddOns'}
						)
					).attr(
						{'id': 'xpopup', 'class': 'xpopup'}
					).css(
						{'display': 'none'}
					).get(0);
				$('body').append(this.popup);
			}
			return this.popup;
		},
		makeCloseButton: function(){
			var self = this;
			$(document).keydown(function(e){self.destruct(e)});
			return $('<div>').append(
				$('<div>').append(
					$('<img>').attr(
						{'src': '/xist4c/px/spc.gif', 'alt': '', 'id': 'xpopupCloseGfx'}
					).click(
						function(e){self.destruct(e)}
					)
				).attr(
					{'class': 'inner'}
				)
			).attr(
				{'id': 'xpopupCloseButton'}
			).get(0)
		},
		showBodyScrollbars: function(){
			$('body').css('overflow', 'auto');
		},
		cleanUp: function(){
			var self = this;
			var bg = $('#xpopup_background');
			if (bg.size() > 0){
				bg.fadeOut(
					function(){
						bg.remove();
						self.showBodyScrollbars();
					}
				)
			}else{
				this.showBodyScrollbars();
			}
			$('#xpopupGalleryOverview').remove();
			$('#xpopup').unbind('.specials');
			with(this){
				initScrollPos = 0;
				preparedGallery = [];
				currentGalleryIdx = -1;
				galleryOverall = -1;
				slideshowBusy = 0;
				if (slideshowInterval) clearTimeout(slideshowInterval);
			}
		},
		destruct: function(e){
			var pupData = $(this.popup).find('#xpopupContent').data('xpopupContent');
			if (this.popup){
				if(e){
					if (e.type == 'keydown'){
						if (e.keyCode == 27){
							if (Utils.isObject(pupData) && Utils.isFunction(pupData.callback)){
								pupData.callback.call(pupData, 'close');
							}
							$(this.popup).fadeOut();
							this.cleanUp();
						}
					}else if (e.type == 'click' || e.type == 'mouseleave' || e.type == 'mouseout'){
						if (e.type == 'click'){
							if (Utils.isObject(pupData) && Utils.isFunction(pupData.callback)){
								pupData.callback.call(pupData, 'close');
							}
							$(this.popup).fadeOut();
							this.cleanUp();
						}else{
							if (Utils.isObject(pupData) && Utils.isFunction(pupData.callback)){
								pupData.callback.call(pupData, 'close');
							}
							$(this.popup).hide();
							this.cleanUp();
						}
					}
				}else{
					if (Utils.isObject(pupData) && Utils.isFunction(pupData.callback)){
						pupData.callback.call(pupData, 'close');
					}
					$(this.popup).fadeOut();
					this.cleanUp();
				}
			}
		}
	}
	
	DefaultXPopup = function(src, event, spos, ppos, margin_w, margin_h, TypeAttrs, callback){
		this.src = src;
		this.event = event;
		this.spos = spos; // layer position on the connected source element
		this.ppos = ppos; // position of the popup layer relative to the layer position of the source element
		this.mw = margin_w; // margin width of the popup from the connected source element (negative integer values allowed)
		this.mh = margin_h; // margin height of the popup from the connected source element (negative integer values allowed)
		this.Attrs = TypeAttrs;
		this.srcDeferred = null;
		this.srcOutDeferred = null;
		this.callback = callback || null;
		if (arguments.length >= 6){
			this.connectSrcElement();
		}
	}

	DefaultXPopup.prototype.connectSrcElement = function(){
		var self = this;
		$(this.src).bind(this.event, function(e){self.show(e)});
	}

	DefaultXPopup.prototype.pushContentIntoPopup = function(){
		$('#xpopupContent').empty().append(this.getContent())
			.data('xpopupContent', this);
	}
	
	DefaultXPopup.prototype.getContent = function(){
		return $('<span>Test Content of the default xpopup!</span>').get(0);
	}

	DefaultXPopup.prototype.getAttr = function(name){
		if (this.Attrs){
			for (var k in this.Attrs){
				if (k.toLowerCase() == name.toLowerCase()) return this.Attrs[name];
			}
		}
		return null;
	}

	DefaultXPopup.prototype.setPopupPosition = function(src, mousePos){
		var self = this;
		var p = LL_XPopup.popup;
		var srcDims = {'w': $(src).outerWidth(), 'h': $(src).outerHeight()};
		var srcPos = {'x': $(src).offset().left, 'y': $(src).offset().top}
		var mCords = mousePos;
		var pDims = {'w': $(p).width(), 'h': $(p).height()};
		var vpDims = {'w': $(window).width(), 'h': $(window).height()};
		var vpPos = {'x': $(document).scrollLeft(), 'y': $(document).scrollTop()}
		var pWidth = pDims.w;
		var pHeight = pDims.h;
		var buffer = 0;
		var xPos, yPos, x, y;

		LL_XPopup.initScrollPos = vpPos;
		if (this.spos.substring(0, 2) == 'p_'){
			srcDims = vpDims;
			if(! this.isIE()){
				if (this.isFixedPosition()) vpPos = {'x': 0, 'y': 0};
			}
			srcPos = vpPos;
		}else{
			if(! this.isIE()){
				if (this.isFixedPosition()){
					srcPos.x = srcPos.x - vpPos.x;
					srcPos.y = srcPos.y - vpPos.y;
					vpPos = {'x': 0, 'y': 0};
				}
			}
		}
		if (this.spos == 'nw' || this.spos == 'w' || this.spos == 'sw' || this.spos == 'p_nw' || this.spos == 'p_w' || this.spos == 'p_sw'){
			x = srcPos.x;
		}else if (this.spos == 'n' || this.spos == 'c' || this.spos == 's' || this.spos == 'p_n' || this.spos == 'p_c' || this.spos == 'p_s'){
			x = srcPos.x + (srcDims.w / 2);
		}else if (this.spos == 'ne' || this.spos == 'e' || this.spos == 'se' || this.spos == 'p_ne' || this.spos == 'p_e' || this.spos == 'p_se'){
			x = srcPos.x + srcDims.w;
		}else if (this.spos == 'cursor'){
			x = mCords.x;
		}else{
			x = 0;
		}
		
		if (this.spos == 'nw' || this.spos == 'n' || this.spos == 'ne' || this.spos == 'p_nw' || this.spos == 'p_n' || this.spos == 'p_ne'){
			y = srcPos.y;
		}else if (this.spos == 'w' || this.spos == 'c' || this.spos == 'e' || this.spos == 'p_w' || this.spos == 'p_c' || this.spos == 'p_e'){
			y = srcPos.y + (srcDims.h / 2);
		}else if (this.spos == 'sw' || this.spos == 's' || this.spos == 'se' || this.spos == 'p_sw' || this.spos == 'p_s' || this.spos == 'p_se'){
			y = srcPos.y + srcDims.h;
		}else if (this.spos == 'cursor'){
			y = mCords.y;
		}else{
			y = 0;
		}
		
		relPopPos = this.getRelativePopupPosition(x, y, srcDims, pDims, this.ppos);
		xPos = relPopPos.x;
		yPos = relPopPos.y;
		if (xPos + pWidth > vpDims.w + vpPos.x) xPos = vpDims.w + vpPos.x - (pWidth + buffer);
		if (yPos + pHeight > vpDims.h + vpPos.y) yPos = vpDims.h + vpPos.y - (pHeight + buffer);
		if (xPos <= vpPos.x) xPos = vpPos.x + buffer;
		if (yPos <= vpPos.y) yPos = vpPos.y + buffer;

		$(LL_XPopup.popup).animate({'left': xPos, 'top': yPos}, 'fast', 'swing', function(){
				self.handlePopupPositionMode();
		});
	}
	
	DefaultXPopup.prototype.setPopupWidth = function(){
		$('#xpopup, #xpopupContent').css({'width': null});
	}
	
	DefaultXPopup.prototype.isIE = function(){
		if(window.clientInformation){
			if (window.clientInformation.appName == 'Microsoft Internet Explorer') return true;
		}
		return false;
	}
	
	DefaultXPopup.prototype.isFixedPosition = function(){
		var fp = this.getAttr('fixedPosition');
		if (fp){
			if (fp.toLowerCase() == 'true' || fp == 1) return true;
		}
		return false;
	}
	
	DefaultXPopup.prototype.handlePopupPositionMode = function(e){
		if (! this.isIE()){
			if (this.isFixedPosition()){
				return $(LL_XPopup.popup).attr('class', 'xpopup_fixed');
			}
		}
		return $(LL_XPopup.popup).attr('class', 'xpopup');
	}
	
	DefaultXPopup.prototype.getRelativePopupPosition = function(xPos, yPos, srcDims, pDims, ppos){
		if (!ppos || ppos == 'nw'){
			xPos += this.mw / 1;
			yPos += this.mh / 1;
			return {'x': xPos, 'y': yPos};
		}else if(ppos == 'w'){
			xPos += this.mw / 1;
			return {'x': xPos, 'y': yPos - (pDims.h / 2)};
		}else if(ppos == 'sw'){
			xPos += this.mw / 1;
			yPos -= this.mh / 1;
			return {'x': xPos, 'y': yPos - pDims.h};
		}else if(ppos == 'n'){
			yPos += this.mh / 1;
			return {'x': xPos - (pDims.w / 2), 'y': yPos};
		}else if(ppos == 'c'){
			return {'x': xPos - (pDims.w / 2), 'y': yPos - (pDims.h / 2)};
		}else if(ppos == 's'){
			yPos -= this.mh / 1;
			return {'x': xPos - (pDims.w / 2), 'y': yPos - pDims.h};
		}else if(ppos == 'ne'){
			xPos -= this.mw / 1;
			yPos += this.mh / 1;
			return {'x': xPos - pDims.w, 'y': yPos};
		}else if(ppos == 'e'){
			xPos -= this.mw / 1;
			return {'x': xPos - pDims.w, 'y': yPos - (pDims.h / 2)};
		}else if(ppos == 'se'){
			xPos -= this.mw / 1;
			yPos -= this.mh / 1;
			return {'x': xPos - pDims.w, 'y': yPos - pDims.h};
		}
	}
	
	DefaultXPopup.prototype.handleSrcAndPopupConnect = function(){
		if (this.event != 'click' && this.spos != this.ppos){
			$(this.src).bind('mouseleave', function(e){LL_XPopup.destruct(e)});
		}else if (this.event != 'click' && this.spos == this.ppos){
			$(LL_XPopup.popup).bind('mouseleave', function(e){LL_XPopup.destruct(e)});
		}
	}
	
	DefaultXPopup.prototype.makeAddOns = function(e){
		$('#xpopupAddOns').empty();
	}
	
	DefaultXPopup.prototype.makeBackground = function(r,g,b){
		var red, green, blue;
		rv = r ? r : 0;
		gv = g ? g : 0;
		bv = b ? b : 0;
		var bg = $('<div> </div>').attr(
			'id', 'xpopup_background'
		).css(
			{
				'display': 'none',
				'position': 'absolute',
				'z-index': 500000,
				'left': 0,
				'top': 0,
				'background-color': 'rgb(' + rv + ',' + gv + ',' + bv + ')',
				'width': $('body').get(0).scrollWidth + 'px',
				'height': $('body').get(0).scrollHeight + 'px'
			}
		);
		if ($('#xpopup_background').size() == 0){
			var bg = $(bg).click(function(e){LL_XPopup.destruct(e)})
			$('body').append(bg);
			bg.css({'display': 'block', 'opacity': 0}).fadeTo('fast', 0.9);
		}
	}
	
	DefaultXPopup.prototype.hideBodyScrollbars = function(){}

	DefaultXPopup.prototype.show = function(e){
		var mousePos = {'x': 0, 'y': 0};
		if (e){
			e.preventDefault();
			mousePos = {'x': e.pageX, 'y': e.pageY};
		}
		var aos = $('#xpopupAddOns');
		aos.hide();
		src = this.src;
		this.hideBodyScrollbars();
		this.pushContentIntoPopup();
		this.handleSrcAndPopupConnect();
		this.makeAddOns();
		aos.show();
		var self = this;
		setTimeout(
			function(){
				var pupData = $(LL_XPopup.popup).find('#xpopupContent').data('xpopupContent');
				self.setPopupPosition(src, mousePos);
				$(LL_XPopup.popup).fadeIn();
				if (Utils.isObject(pupData) && Utils.isFunction(pupData.callback)){
					pupData.callback.call(pupData, 'show');
				}
			},
			1
		);
	}

	// Image xpopup
	ImageXPopup = function(src, event, spos, ppos, margin_w, margin_h, TypeAttrs, callback){
		/* TypeAttrs: url, href, jsFunc, height, width, background
		 * url: Source of the image to display.
		 * group: An identifier for group related images.
		 * href: Link reference for the image.
		 * jsFunc: Mochikit bind or partial functions.
		 * height: Popup height.
		 * width: Popup width.
		 * background: The popup stay on a dark background
		 * fixedPosition: The popup is position fixed and has no response on scroll events.
		 */
		this.constructor(src, event, spos, ppos, margin_w, margin_h, TypeAttrs, callback);
		this.image = this.makeImage(this.getAttr('url'), {'border': 0, 'alt': '', 'title': ''});
		this.appearingHud = null;
		this.activeHud = false;
	}
	ImageXPopup.prototype = new DefaultXPopup();
	
	ImageXPopup.prototype.setPopupWidth = function(w){
		var p = $('#xpopup');
		var pc = $('#xpopupContent');
		var imgWidth = w.substring(0, w.length -2) / 1;
		var pl = pc.css('padding-left');
		pl = pl.substring(0, pl.length -2) / 1;
		var pr = pc.css('padding-right');
		pr = pr.substring(0, pr.length -2) / 1;
		p.css({'width': (imgWidth + pl + pr) + 'px'});
	}
	
	ImageXPopup.prototype.getSrcImage = function(){
		nodes = $('img', this.src);
		if (nodes.size() > 0) return nodes.get(0);
		return null;
	}
	
	ImageXPopup.prototype.getSrcImageTitle = function(){
		var elm = this.getSrcImage();
		if (elm && elm.title && elm.title != '') return elm.title;
		return null;
	}

	ImageXPopup.prototype.prepareGalleryByGroup = function(){
		LL_XPopup.preparedGallery = [];
		LL_XPopup.currentGalleryIdx = -1;
		LL_XPopup.galleryOverall = -1;
		var grp = this.getAttr('group');
		if (grp){
			var xpopups = LL_XPopup.xpopups;
			var idx = -1;
			for (var i = 0; i < xpopups.length; ++i){
				var xp = xpopups[i];
				if (xp instanceof ImageXPopup){
					if (xp.getAttr('group') == grp){
						idx++;
						if (xp === this) LL_XPopup.currentGalleryIdx = idx;
						LL_XPopup.preparedGallery.push(xp);
					}
				}
			}
			if(LL_XPopup.preparedGallery.length > 0) LL_XPopup.galleryOverall = LL_XPopup.preparedGallery.length;
		}
	}
	
	ImageXPopup.prototype.makeImage = function(src, attrs){
		var img = new Image();
		img.src = src;
		for (var k in attrs){
			if (k == 'class'){
				img.className = attrs[k];
			}else{
				img[k] = attrs[k];
			}
		}
		return img;
	}
	
	ImageXPopup.prototype.resizeImgOnOverflow = function(img, maxHeight, maxWidth){
		var h = img.height;
		var w = img.width;
		var ah = maxHeight;
		var aw = maxWidth;
		if (ah && aw){
			if (h > ah){
				w = Math.floor(w * ah / h);
				h = ah;
			}
			if (w > aw){
				h = Math.floor(h * aw / w);
				w = aw;
			}
			img.height = h;
			img.width = w;
		}
		return img;
	}
	
	ImageXPopup.prototype.makeImageTitleIfAny = function(){
		var t = this.getSrcImageTitle();
		if (t){
			return $('<div>').append(
				$('<span>' + t + '</span>')
			).attr(
				{'id': 'xpopupImgTitle', 'class': 'xpopupImgTitle'}
			).get(0);
		}
		return null;
	}
	
	ImageXPopup.prototype.activateHud = function(e){
		if (! this.appearingHud && ! this.activeHud){
			this.appearingHud = 1;
			this.activeHud = true;
			var self = this;
			$('#xpopupHoverMenuOuter').fadeIn('fast');
			self.appearingHud = null;
		}
		this.activeHud = true;
	}
	
	ImageXPopup.prototype.deactivateHud = function(e){
		if (this.activeHud){
			$('#xpopupHoverMenuOuter').hide();
		}
		this.activeHud = false;
	}

	ImageXPopup.prototype.makeHudAndPrepareGallery = function(){
		var self = this;
		$(LL_XPopup.popup).unbind('mousemove.special');
		$(LL_XPopup.popup).bind('mousemove.special', function(e){
			e.preventDefault();
			e.stopPropagation();
			self.activateHud(e);
		});
		$('#xpopup_background').bind('mouseover.special', function(e){
			e.preventDefault();
			e.stopPropagation();
			self.deactivateHud(e);
		});
		this.prepareGalleryByGroup();
		var hm = $('<div>').append(
			$('<div>').append(
				$('<div>').append(
					this.getPlayPauseButton(),
					this.getPreviousButton(),
					this.getNextButton(),
					this.getThumbsButton(),
					this.getCloseButton()
				).attr(
					{'id': 'xpopupHoverMenu'}
				)
			).attr(
				{'id': 'xpopupHoverMenuPos'}
			)
		).attr(
			{'id': 'xpopupHoverMenuOuter'}
		).get(0);
		return hm;
	}
	
	ImageXPopup.prototype.buttonsStateController = function(){
		var buttons = [
			'xpopupHoverMenuPlayPauseButton',
			'xpopupHoverMenuPreviousButton',
			'xpopupHoverMenuNextButton',
			'xpopupHoverMenuThumbsButton',
			'xpopupHoverMenuCloseButton'
		];
	
		if (LL_XPopup.galleryOverall > 1){
			this.updateButton(buttons[0], 'act');
			if (LL_XPopup.slideshowBusy){
				this.updateButton(buttons[0], 'act', 'pauseButton');
			}
			this.updateButton(buttons[3], 'act'); // Thumb not connected now.
		}else{
			this.updateButton(buttons[0], 'pass');
			this.updateButton(buttons[3], 'pass');
		}

		if (LL_XPopup.galleryOverall > 1 && LL_XPopup.currentGalleryIdx > 0){
			this.updateButton(buttons[1], 'act');
		}else{
			this.updateButton(buttons[1], 'pass');
		}
		
		if (LL_XPopup.galleryOverall > 1 && LL_XPopup.currentGalleryIdx < LL_XPopup.preparedGallery.length - 1){
			this.updateButton(buttons[2], 'act');
		}else{
			this.updateButton(buttons[2], 'pass');
		}
		this.updateButton(buttons[4], 'act');
	}
	
	ImageXPopup.prototype.getPlayPauseButton = function(){
		var self = this;
		return $('<div>').attr(
			{'class': 'playButton_pass', 'id': 'xpopupHoverMenuPlayPauseButton'}
		).click(
			function(e){
				self.handleSlideshow(e);
				self.activeHud = false;
			}
		).get(0);
	}
	
	ImageXPopup.prototype.getPreviousButton = function(){
		var self = this;
		return $('<div>').attr(
			{'class': 'previousButton_pass', 'id': 'xpopupHoverMenuPreviousButton'}
		).click(
			function(e){
				self.changeImage(-1, 'pager', e);
				self.activeHud = false;
			}
		).get(0);
	}
	
	ImageXPopup.prototype.getNextButton = function(){
		var self = this;
		return $('<div>').attr(
			{'class': 'nextButton_pass', 'id': 'xpopupHoverMenuNextButton'}
		).click(
			function(e){
				self.changeImage(1, 'pager', e)
				self.activeHud = false;
			}
		).get(0);
	}

	ImageXPopup.prototype.getThumbsButton = function(){
		var self = this;
		return $('<div>').attr(
			{'class': 'thumbsButton_pass', 'id': 'xpopupHoverMenuThumbsButton'}
		).click(
			function(e){
				self.handleGalleryOverview(e)
				self.activeHud = false;
			}
		).get(0);
	}

	ImageXPopup.prototype.getCloseButton = function(){
		var self = this, lay = $('<div>').attr(
			{'class': 'closeButton_pass', 'id': 'xpopupHoverMenuCloseButton'}
		).click(
			function(e){
				if (Utils.isFunction(self.callback)){
					self.callback.call(self, 'close');
				}
				LL_XPopup.destruct(e);
				self.activeHud = false;
			}
		).get(0);
		return lay;
	}

	ImageXPopup.prototype.updateButton = function(id, state, cnPrefix){
		var button = $('#' + id);
		if (arguments.length < 3){
			var cn = button.attr('class');
			cnPrefix = cn.substring(0, cn.lastIndexOf('_'));
		}
		button.attr({'class': cnPrefix + '_' + state});
	}
	
	ImageXPopup.prototype.isButtonActive = function(e, className){
		var cn = e.target.className;
		if (className) cn = className;
		var state = cn.substring(cn.lastIndexOf('_') + 1, cn.length).toLowerCase();
		if (state == 'act') return true;
		return false;
	}

	ImageXPopup.prototype.makeAddOns = function(e){
		var aos = $('#xpopupAddOns');
		aos.empty();
		aos.append(this.makeHudAndPrepareGallery());
		$('#xpopupHoverMenu').css({'left': (this.image.width / 2 - 132) + 'px'});
		var title = this.makeImageTitleIfAny();
		aos.append(title);
		this.buttonsStateController();
	}
	
	ImageXPopup.prototype.changeImage = function(idx, modeStr, e){
		if (LL_XPopup.slideshowBusy > 0){
			if (e && this.isButtonActive(e) && modeStr == 'pager'){
				var idx = LL_XPopup.currentGalleryIdx += idx;
				var xpopup = LL_XPopup.preparedGallery[idx];
				xpopup.show();
			}else if (modeStr == 'slideshow'){
				var idx = LL_XPopup.currentGalleryIdx += idx;
				if (idx == LL_XPopup.preparedGallery.length) idx = LL_XPopup.currentGalleryIdx = 0;
				var xpopup = LL_XPopup.preparedGallery[idx];
				var self = this;
				$('#xpopup').fadeOut(
					'fast',
					function(){
						xpopup.pushContentIntoPopup();
						xpopup.makeAddOns();
						setTimeout(
							function(){
								var mousePos = {'x': 0, 'y': 0};
								xpopup.setPopupPosition(xpopup.src, mousePos);
								$('#xpopup').fadeIn();
							},
							500
						);
					}
				);
			}
			if (LL_XPopup.slideshowInterval) clearTimeout(LL_XPopup.slideshowInterval);
			var self = this;
			LL_XPopup.slideshowInterval = setTimeout(function(){self.changeImage(1, 'slideshow')}, 7000);
		}else{
			if (e && this.isButtonActive(e) && modeStr == 'pager'){
				var idx = LL_XPopup.currentGalleryIdx += idx;
				var xpopup = LL_XPopup.preparedGallery[idx];
				xpopup.show();
			}else if(modeStr == 'gallery'){
				var idx = LL_XPopup.currentGalleryIdx = idx;
				var xpopup = LL_XPopup.preparedGallery[idx];
				xpopup.show();
			}
		}
	}
	
	ImageXPopup.prototype.getContent = function(){
		var img = null;
		var href, jsFunc;
		if (this.Attrs){
			var Attrs = this.Attrs;
			img = this.resizeImgOnOverflow(this.image, this.getAttr('height'), this.getAttr('width'));
			height = Attrs.height ? Attrs.height + 'px' : img.height + 'px' ;
			width = Attrs.width ? Attrs.width + 'px' : img.width + 'px';
			if (Attrs.href && ! Attrs.jsFunc){
				href = Attrs.href;
				img = $('<a>').append(img).attr({'href': Attrs.href}, img);
			}
			if (Attrs.jsFunc){
				$(img).css({'cursor': 'pointer'}).click(Attrs.jsFunc)
			}
			if (this.Attrs.background){
				if (this.Attrs.background.toLowerCase() == 'true' || this.Attrs.background == 1) this.makeBackground();
			}
		}
		this.setPopupWidth(width);
		return $('<div>').append(img).css({'height': height, 'width': width, 'overflow': 'auto', 'text-align': 'center'})
	}
	
	ImageXPopup.prototype.changeSlideshowPopupCSS = function(){
		if (LL_XPopup.slideshowBusy){
			var xPopupClass = 'xpopup_slideshow';
			var xPopupTitleClass = 'xpopupImgTitle_slideshow';
			if (! this.isIE() && this.isFixedPosition()) xPopupClass = 'xpopup_slideshow_fixed';
		}else{
			var xPopupClass = 'xpopup';
			var xPopupTitleClass = 'xpopupImgTitle';
			if (! this.isIE() && this.isFixedPosition()) xPopupClass = 'xpopup_fixed';
		}
		$('#xpopup').attr({'class': xPopupClass});
		if($('#xpopupImgTitle').size() > 0) $('#xpopupImgTitle').attr({'class': xPopupTitleClass});
	}

	ImageXPopup.prototype.hideBodyScrollbars = function(){
		$('body').css({'overflow': 'hidden'});
	}
	
	ImageXPopup.prototype.handleSlideshow = function(e){
		if (this.isButtonActive(e)){
			if (LL_XPopup.slideshowBusy){
				var buttonClass = 'playButton';
				LL_XPopup.slideshowBusy = 0;
				clearTimeout(LL_XPopup.slideshowInterval);
			}else{
				var buttonClass = 'pauseButton';
				LL_XPopup.slideshowBusy = 1;
				var self = this;
				LL_XPopup.slideshowInterval = setTimeout(function(){self.changeImage(1, 'slideshow')}, 7000);
			}
			this.updateButton('xpopupHoverMenuPlayPauseButton', 'act', buttonClass);
		}
	}
	
	ImageXPopup.prototype.handleGalleryImgClick = function(idx, e){
		e.preventDefault();
		e.stopPropagation();
		var self = this;
		$('#xpopupGalleryOverview').fadeOut('fast', function(){$('#xpopupGalleryOverview').remove()});
		this.changeImage(idx, 'gallery');
	}
	
	ImageXPopup.prototype.handleGalleryOverview = function(e){
		if (LL_XPopup.slideshowBusy) this.handleSlideshow({'target': $('#xpopupHoverMenuPlayPauseButton').get(0)});
		$('#xpopup').hide();
		var images = this.getOverviewImagesWithDeco();
		var vpDims = {'w': $(window).width(), 'h': $(window).height()};
		var vpPos = {'x': $(document).scrollLeft(), 'y': $(document).scrollTop()}
		var px = null;
		var py = null;
		var h = vpDims.h;
		var w = vpDims.w;
		var position = 'fixed';
		if (this.isIE()){
			px = vpPos.x;
			py = vpPos.y;
			var position = 'absolute';
		}
		var container = $('<div>').attr(
			{'id': 'xpopupGalleryOverview', 'class': 'xpopupGalleryOverview'}
		).css(
		{'height': '100%', 'width': '100%', 'position': position, 'left': px, 'top': py}
		).click(
			function(e){LL_XPopup.destruct(e)}
		);
		for (var i = 0; i < images.length; ++i){
			container.append(images[i]);
		}
		$('body').append(container);
		$('#xpopupGalleryOverview').fadeIn('fast');
	}

	ImageXPopup.prototype.getOverviewImagesWithDeco = function(){
		var pg = LL_XPopup.preparedGallery;
		var images = [];
		var mw= 135;
		var mh = 90;
		for (var i = 0; i < pg.length; ++i){
			function x(self, idx){
				var srcImg = pg[idx].getSrcImage();
				var paddingTop = '0';
				if (srcImg.height < mh) paddingTop = parseInt((mh - srcImg.height) / 2) + 'px';
				var img = self.makeImage(srcImg.src, {'width': srcImg.width, 'height': srcImg.height, 'border': 0, 'alt': srcImg.alt, 'title': srcImg.title});
				var img = self.resizeImgOnOverflow(img, mh, mw);
				var imgWrapped = $('<span></span>').append(img).css({'padding-top': paddingTop});
				images.push(
					$('<div>').append(
						$('<a></a>').append(
							$('<span></span>').append(imgWrapped).attr({'class': 'image'})
						).attr({'class': 'inner1', 'href': '#'})
					).attr({'class': 'xpopupGalleryImageDeco'}).click(
						function(e){self.handleGalleryImgClick(idx, e)}
					).get(0)
				);
				return images;
			}
			images = x(this, i);
		}
		return images;
	}


	// Webpage xpopup
	WebpageXPopup = function(src, event, spos, ppos, margin_w, margin_h, TypeAttrs, callback){
		/* TypeAttrs: url, href, jsFunc, height, width, background
		 * url: Source of the image to display.
		 * height: Popup height.
		 * width: Popup width.
		 * background: The xpopup stay on a dark background
		 * fixedPosition: The popup is position fixed and has no response on scroll events.
		 */
		this.constructor(src, event, spos, ppos, margin_w, margin_h, TypeAttrs, callback);
	}
	WebpageXPopup.prototype = new DefaultXPopup();

	WebpageXPopup.prototype.getContent = function(){
		this.setPopupWidth();
		var height = parseInt($(window).height() / 1.5);
		var width = parseInt($(window).width() / 1.5);
		var url = 'http://www.example.com';
		if (this.Attrs){
			height = this.Attrs.height == 'auto'? height : this.Attrs.height;
			width = this.Attrs.width == 'auto'? width : this.Attrs.width;
			url = this.Attrs.url ? this.Attrs.url : url;
			if (this.Attrs.background){
				if (this.Attrs.background.toLowerCase() == 'true' || this.Attrs.background == 1) this.makeBackground();
			}
		}
		return $('<iframe>').attr({'src': url, 'frameborder': 0, 'height': height, 'width': width}).get(0);
	}
	
	WebpageXPopup.prototype.makeBackground = function(r,g,b){
		var red, green, blue;
		rv = r ? r : 0;
		gv = g ? g : 0;
		bv = b ? b : 0;
		var bg = $('<div> </div>').attr(
			'id', 'xpopup_background'
		).css(
			{
				'display': 'none',
				'position': 'absolute',
				'z-index': 500000,
				'left': 0,
				'top': 0,
				'background-color': 'rgb(' + rv + ',' + gv + ',' + bv + ')',
				'width': $('body').get(0).scrollWidth + 'px',
				'height': $('body').get(0).scrollHeight + 'px'
			}
		);
		if ($('#xpopup_background').size() == 0){
			var bg = $(bg).click(function(e){LL_XPopup.destruct(e)})
			$('body').append(bg);
			bg.css({'display': 'block', 'opacity': 0}).fadeTo('fast', 0.5);
		}
	}

	// Ajax xpopup
	AjaxXPopup = function(src, event, spos, ppos, margin_w, margin_h, TypeAttrs, callback){
		/* TypeAttrs: url, href, jsFunc, height, width, background
		 * url: Source of the image to display.
		 * height: Popup height.
		 * width: Popup width.
		 * background: The popup stay on a dark background
		 * fixedPosition: The popup is position fixed and has no response on scroll events.
		 */
		this.constructor(src, event, spos, ppos, margin_w, margin_h, TypeAttrs, callback);
		this.def = null;
	}
	AjaxXPopup.prototype = new DefaultXPopup();

	AjaxXPopup.prototype.getContent = function(){
		this.setPopupWidth();
		var height = parseInt($(window).height() / 3);
		var width = parseInt($(window).width() / 2);
		var url = '/';
		if (this.Attrs){
			height = this.Attrs.height == 'auto'? height : this.Attrs.height + 'px';
			width = this.Attrs.width == 'auto'? width : this.Attrs.width + 'px';
			url = this.Attrs.url ? this.Attrs.url : url;
			if (this.Attrs.background){
				if (this.Attrs.background.toLowerCase() == 'true' || this.Attrs.background == 1) this.makeBackground();
			}
		}
		var container = $('<div>').css({ 'height': height, 'width': width, 'overflow': 'auto'}).load(url);
		return container.get(0);
	}
	
	AjaxXPopup.prototype.loadContent = function(container, def){
		var pupData = $(LL_XPopup.popup).find('#xpopupContent').data('xpopupContent');
		if (Utils.isObject(pupData) && Utils.isFunction(pupData.callback)){
			pupData.callback.call(pupData, 'load');
		}
		container.innerHTML = def.responseText;
	}

	AjaxXPopup.prototype.loadContentError = function(def){
		var pupData = $(LL_XPopup.popup).find('#xpopupContent').data('xpopupContent');
		if (Utils.isObject(pupData) && Utils.isFunction(pupData.callback)){
			pupData.callback.call(pupData, 'loadError');
		}
		/* LOGGING >> */
		if (window.console){
			console.log('Fehler beim Abruf von AJAX content:', def.message);
		}
		/* << LOGGING */
	}
/* << */


/* >> tabbed elements (requires jQuery 1.2.6) Version: rel-1-0-0 */
	TabbedElements = {
		tabGroups: [],
		tabsCont: null,
		tabsOuter: null,
		register: function(tabEl, activeId){
			this.tabsCont = $('#' + tabEl).get(0);
			var tOut = this.tabsOuter = this.tabsCont.parentNode;
			tOutChilds = this._getTabContainerChildNodes('div', tOut);
			var titlesOuter = this._getTabContainerElementsTitleShells(tOutChilds);
			var grp = {'id': tabEl, 'tabs': [], 'elements': [], 'hereId': -1};
			for (var i = 1; i < tOutChilds.length -1; ++i){
				grp.tabs.push(this._getTab(this._getTabTitleAndDeleteShell(titlesOuter[i -1]), this.tabGroups.length, i -1));
				grp.elements.push(tOutChilds[i]);
			}
			this.tabGroups.push(grp);
			var actGrpId = this.tabGroups.length -1;
			this._fillTabsElement(actGrpId);
			this._prepareParagraphShells(actGrpId);
			this.show(actGrpId, activeId);
		},
		_getTabGroupId: function(id){
			if (! isNaN(id)){
				return id;
			}else{
				for (var i = 0; i < this.tabGroups.length; ++i){
					var strId = this.tabGroups[i].id.substring(this.tabGroups[i].id.indexOf('_') + 1, this.tabGroups[i].id.length).toLowerCase();
					if (strId == id.toLowerCase()) return i;
				}
			}
			return false;
		},
		_getTabTitleAndDeleteShell: function(titleEl){
			t = titleEl.getElementsByTagName('h3')[0];
			$(titleEl).remove();
			return t.innerHTML;
		},
		_getTabContainerChildNodes: function(elmName, parent){
			var nList = [];
			for (var i = 0; i < parent.childNodes.length; ++i){
				var n = parent.childNodes[i];
				if (n.nodeType == 1 && n.nodeName.toLowerCase == elmName.toLowerCase){
					nList.push(n);
				}
			}
			return nList;
		},
		_getFirstMatchChildNode: function(node, tag, nodeType){
			if (! nodeType) var nodeType = 1;
			for (var i = 0; i < node.childNodes.length; ++i){
				if (node.childNodes[i].nodeType == nodeType){
					if (tag && node.childNodes[i].nodeName.toLowerCase == tag.toLowerCase){
						return node.childNodes[i];
					}
					if (! tag) return node.childNodes[i];
				}
			}
			return false;
		},
		_getTabContainerElementsTitleShells: function(contentElms){
			var tList = [];
			var prevNode;
			for (var i = 1; i < contentElms.length -1; ++i){
				var node = contentElms[i];
				while (this._getFirstMatchChildNode(node, 'div', 1)){
					prevNode = node;
					node = this._getFirstMatchChildNode(node, 'div', 1);
				}
				tList.push(prevNode);
			}
			return tList;
		},
		_getTab: function(title, grpId, tabId){
			var id = 'tab_' + grpId + '_' + tabId;
			var tab = $(
				'<div id="' + id + '" class="tab_passive">' +
					'<div class="inner1">' +
						'<div class="inner2">' +
							'<span>' + title + '</span>' +
						'</div>' +
					'</div>' +
				'</div>'
			).get(0);
			var self = this;
			$(tab.childNodes[0].childNodes[0].childNodes[0]).bind('click', function(e){self.show(grpId, tabId, e)});
			return tab;
		},
		_fillTabsElement: function(grpId){
			var tabs = this.tabGroups[grpId].tabs;
			var outer = $('<div class="outer1"></div>');
			for (var i = 0; i < tabs.length; ++i){
				outer.append($(tabs[i]));
			}
			
			outer.append($('<div></div>').css({'clear': 'both', 'min-height': '1px', 'margin-bottom': '-1px'}));
			$(this.tabsCont).css({'display': 'block'});
			$(this.tabsCont).append(outer);
		},
		_prepareParagraphShells: function(grpId){
			var paras = this.tabGroups[grpId].elements;
			for (var i = 0; i < paras.length; ++i){
				var id = 'tabContent_' + grpId + '_' + i;
				$(paras[i]).css({'display': 'none'});
			}
			
		},
		show: function(grpId, tabId, e){
			var grpId = this._getTabGroupId(grpId);
			var tabId = isNaN(parseInt(tabId)) ? 0 : tabId;
			if (tabId > this.tabGroups[grpId].tabs.length -1 || tabId < 0) tabId = 0;
			var tabs = this.tabGroups[grpId].tabs;
			var elements = this.tabGroups[grpId].elements;
			var hereId = this.tabGroups[grpId].hereId;
			if (hereId > -1){
				$(tabs[hereId]).attr('class', 'tab_passive');
				$(elements[hereId]).css({'display': 'none'});
			}
			$(tabs[tabId]).attr('class', 'tab_active');
			$(elements[tabId]).css({'display': 'block'});
			this.tabGroups[grpId].hereId = tabId;
		}
	}
/* << */


/* >> Calendar control (requires jQuery 1.2.6+ and scrollTo plugin). Version: rel-1-0-0 */
	// The script supports horizontal and vertical scrolling in the future!
	function CalendarControl(mode){
		this.months = [];
		this.scrollToDef = null;
		this.mode = this.getMode(mode); // horizontal or vertical
		this.currScrollPos = 0;
		this.scrollPane = $('#calendarHorizontalScrollPane');
		this.mBoxName = 'calendarMonthContainer_'; // month container id snippet
		this.ctrlBoxName = '#horizontalScrollControls' // holds the calendar controlls (left and right arrow)
		// @controls:
		// 'key': [element, event, binding, attributes, connection id]
		this.controlsHorz = {
			'l': [$('#scrollLeft'), 'click', 'scroll', -1],
			'r': [$('#scrollRight'), 'click', 'scroll', 1]
		};
		this.scrollStep = 2; // how many months to scroll with one click
	}
	
	CalendarControl.prototype.init = function(args){
		this.handleLayout();
		this.detectMonths();
		if (args.current > 0){
			if (args.current % this.scrollStep > 0){
				this.currScrollPos = Math.floor(args.current / this.scrollStep) * this.scrollStep;
			}else{
				this.currScrollPos = args.current - this.scrollStep;
			}
			var mode = this.mode > 1 ? 'y': 'x';
			this.scrollPane.scrollTo(this.months[this.currScrollPos].monthElement, 600, {'axis': mode, 'offset': {'left': -35, 'top': 0}});
		}
		this.handleControls();
	}
	
	CalendarControl.prototype.handleControls = function(){
		var c = this.controlsHorz;
		var status = {
			'l': this.currScrollPos > 0 ? 1 : null,
			'r': this.currScrollPos + this.scrollStep < this.months.length ? 1 : null
		};
		for (var i in c){
			var ctrl = c[i];
			ctrl[0].unbind().removeClass('act').addClass('pass');
			if (status[i]){
				var self = this;
				(function(m){
					ctrl[0].bind(ctrl[1], function(e){
						e.preventDefault();
						self[ctrl[2]](m);
					});
				})(ctrl[3]);
				ctrl[0].removeClass('pass').addClass('act');
			}
		}
	}
	
	CalendarControl.prototype.handleLayout = function(){
		$(this.ctrlBoxName).show();
		this.scrollPane.css({'overflow': 'hidden'});
	}
	
	CalendarControl.prototype.detectMonths = function(){
		for (var count = 0;;){
			var month = $('#' + this.mBoxName + count++);
			if (month.size() == 0) break;
			this.months.push(new CalendarMonth(month));
		}
	}
	
	CalendarControl.prototype.scroll = function(direction){
		var nextPos = this.currScrollPos + direction * this.scrollStep;
		if (nextPos >= 0 && nextPos <= this.months.length){
			var mode = this.mode > 1 ? 'y': 'x';
			this.scrollPane.scrollTo(this.months[nextPos].monthElement, 600, {'axis': mode, 'offset': {'left': -35, 'top': 0}});
			this.currScrollPos = nextPos;
		}
		this.handleControls();
	}

	CalendarControl.prototype.getMonthDims = function(){
		return {'w': this.months[0].monthElement.width(), 'h': this.months[0].monthElement.height()};
	}
	
	CalendarControl.prototype.getMode = function(mode){
		mode = (String(mode)).toLowerCase;
		if (mode == 'h'){
			return 1;
		}else if (mode == 'v'){
			return 2
		}
		return 1;
	}


	function CalendarMonth(monthElement){
		this.monthElement = monthElement;
		this.name = this.getName();
		this.here = null;
	}
	
	CalendarMonth.prototype.getName = function(){
		return null;
	}
/* << */




/* >> Slot Machine */
	/* >> slot machine */
		SlotMachine = $.extend(
			$.clone(LLObject),
			{
				toJsonAttrs: ['data'],
				data: null,
				url: null,
				onAfterSlotCatch: null,
				onDataRequest: null,
				onDataRequestSuccess: null,
				slots: [],
				opts: null,
				bgAnimation: null,
				actionKeeper: null,
				actionKeeperTimeout: null,
				urlParams: null,
				init: function(opts){
					window.slotMachinePresent = 1;
					BgAnimate.registerAnimation('slotMachineBusyRotor', null, {'bgPosition': '912px 190px', 'prefix': 'rotorMedAni_', 'duration': 130});
					if (opts){
						this.opts = opts;
						this.makeShell(opts.target);
						//{'auf_id': 917440} product test
						var urlParams = this.urlParams = this.getURLParams();
						if (!urlParams.ovn) urlParams.ovn = 'false';
						this.url = AjaxURLManager.getUrlWithKey('configarticle', urlParams);
						if (this.urlParams.loadPos) this.urlParams.loadPos = null;
						var cb = opts.onAfterSlotCatch;
						if (cb && typeof cb == 'function') this.onAfterSlotCatch = cb;
						var cbdr = opts.onDataRequest;
						if (cbdr && typeof cbdr == 'function') this.onDataRequest = cbdr;
						var cbdrs = opts.onDataRequestSuccess;
						if (cbdrs && typeof cbdrs == 'function') this.onDataRequestSuccess = cbdrs;
						if (this.url){
							var self = this;
							this.setActionKeeper({'opacity': 1, 'background': 'transparent'});
							$.getJSON(this.url, function(data, textStatus){
								var d = self.data = data;
								if (d.overnight) self.urlParams.ovn = true;
								if (d.type == 'SlotMachineData'){
									$(d.slots).each(function(i){
										if (this.type == 'SlotMachineSlot'){
											var slot = SlotMachineSlot.create(this.title, this.currentItem);
											slot.id = 'slot_' + i;
											slot.itemId = i;
											slot.data = this;
											slot.width = this.width;
											$(this.items).each(function(i){
												if (this.type == 'SlotMachineSlotItem'){
													var slotItem = SlotMachineSlotItem.create(this.title, this.value);
													slotItem.id = slot.id + '_slotItem_' + i;
													slotItem.itemCnt = i;
													slotItem.data = this;
													slotItem.slot = slot;
													slotItem.width = slot.width;
													slot.appendItem(slotItem);
												}
											});
											self.appendSlot(slot);
											var realWidth = slot.width;
											var itemsHasImage = false;
											$(slot.items).each(function(i){
												if (this.data.img) itemsHasImage = true;
												var item = $('#' + this.id);
												var scrollWidth = item.get(0).scrollWidth;
												if (scrollWidth > slot.width && scrollWidth > realWidth){
													realWidth = scrollWidth;
												}
												item.css({'width': 'auto'});
											});
											var addSpace = itemsHasImage ? 53 : 10;
											if (realWidth > slot.width) slot.setWidth(realWidth + addSpace);
										}
									});
								}
								self.clearActionKeeper();
								// call init callback if exists
								var initCb = opts.onAfterInit;
								if (initCb && typeof initCb == 'function'){
									initCb.call(self, self.data);
								}
								if (self.onDataRequestSuccess) self.onDataRequestSuccess.call(self, null, d);
							});
						}
					}
				},
				getURLParams: function(specParams){
					var url = window.location.href;
					var params =  Utils.getUrlParamsAsJson(url);
					if (params && params.id) params = $.reduce(params, 'id');
					var reg = /_dId_/;
					var id = null;
					if (reg.test(url)){
						id = url.substring(url.search(reg) + 5, url.search(/_\.htm/));
					}
					if (params && params.auf_id != null){
						id = params.auf_id;
					}
					if (params && params.pos_id != null && !params.auf_id){
						id = params.pos_id;
					}
					if (id){
						if (params.pos_id){
							params = $.extend(params, {'pos_id': id});
						}else{
							params = $.extend(params, {'auf_id': id});
						}
					}else{
						var cfd = window.CONFIGURATOR_FALLBACK_DATA;
						if (cfd && cfd.auf_id){
							params = $.extend(params, {'auf_id': cfd.auf_id, 'freeConfig': 'true'});
						}
					}
					params = $.extend(params, specParams);
					return params;
				},
				makeShell: function(target){
					var shell = $(
						'<div id="slotMachineOuter">' +
							'<div id="slotMachineMainBg">' +
								'<table cellpaddig="0" cellspacing="0" border="0">' +
									'<tr class="titles">' +
									'</tr>' +
									'<tr class="slots">' +
									'</tr>' +
								'</table>' +
							'</div>' +
						'</div>'
					);
					target.append(shell);
				},
				appendSlot: function(slot){
					if (slot.instanceOf(SlotMachineSlot)){
						this.slots.push(slot);
						slot.make(this.opts.target);
					}
				},
				setActionKeeper: function(options){
					if ($('#slotMachineActionKeeper').size() == 0){
						var defaults = {
							'opacity': 0.3,
							'background': '#000'
						}
						var opts = $.extend(defaults, options);
						var akShell = $('<div id="slotMachineActionKeeper"></div>');
						var target = $('div.contColDes5');
						target.addClass('viewport').css({'overflow': 'hidden'});
						var w = target.width();
						var h = target.height();
						akShell.width(w).height(h);
						akShell.css(opts);
						target.append(akShell);
						this.actionKeeper = akShell;
						this.bgAnimation = BgAnimate.createAnimation('slotMachineBusyRotor', akShell);
						this.bgAnimation.start();
					}
				},
				slotUpdateCheck: function(){
					var data = this.data;
					var self = this;
					$(data.slots).each(function(i){
						var realSlot = self.slots[i];
						var slotData = this;
						if (slotData.update){
							realSlot.update(slotData);
						}
						self.data.slots[i].update = false;
					});
				},
				clearActionKeeper: function(){
					//setTimeout(function(){
						$('#slotMachineActionKeeper').remove();
						$('div.contColDes5').css({'overflow': 'auto'});
					//}, 500);
				},
				verifyData: function(slot, woActionKeeper){
					var slot = slot || null;
					var self = this;
					if (!woActionKeeper) this.setActionKeeper({'opacity': 1, 'background': 'transparent'});
					var oldData = SlotMachine.data;
					if (slot) SlotMachine.data.changedSlot = slot.itemId;
					var cbdr = SlotMachine.onDataRequest;
					if (cbdr) cbdr.call(SlotMachine, self, SlotMachine.data);
					var url = AjaxURLManager.getUrlWithKey('configarticle');
					//alter data and send it to cherrypy
					for (var i in this.data.slots){
						this.data.slots[i].currentItem = this.slots[i].currentItem;
					}
					/* LOGGING >> */
					//if (window.console) console.log($.toJson(SlotMachine));
					/* << LOGGING */
					$.ajax({
						type: 'post',
						url: url,
						data: {'content': encodeURIComponent($.toJson(SlotMachine))},
						success: function(data, msg){self.verifyDataRequestSuccess(data, msg, slot);},
						error: function(req, status, error){self.verifyDataRequestError(req, status, error, slot);}
					});
				},
				verifyDataRequestSuccess: function(data, msg, slot){
					//eval('var data = ' + data);
					this.data = data;
					if (this.urlParams && this.urlParams.auf_id) this.urlParams.auf_id = data.auf_id;
					if (this.onDataRequestSuccess) this.onDataRequestSuccess.call(this, slot, data);
					this.slotUpdateCheck();
					this.clearActionKeeper();
				},
				verifyDataRequestError: function(req, status, error, slot){
					this.clearActionKeeper();
					/* todo: .... */
				}
			}
		);
	/* << */

	/* >> slot machine slot */
		SlotMachineSlot = $.extend(
			$.clone(LLObject),
			{
				create: function(title, currentItem){
					var slotMachineSlot = LLObject.create.call(this);
					slotMachineSlot.id = null;
					slotMachineSlot.itemId = null;
					slotMachineSlot.title = title;
					slotMachineSlot.width = null;
					slotMachineSlot.items = [];
					slotMachineSlot.currentItem = currentItem;
					slotMachineSlot.data = null;
					slotMachineSlot.mouseDownInterval = null;
					slotMachineSlot.initMode = true;
					slotMachineSlot.clickTimeout = null;
					return slotMachineSlot;
				},
				makeSlotTitle: function(){
					var title = $(
						'<td class="' + this.id + '_titleColumn"><div class="slotTitle">' + this.title + '</div></td>'
					);
					return title;
				},
				makeSlotLayout: function(){
					var slot = $(
						'<td class="' + this.id + '_column">' +
							'<div id="' + this.id + '_outer" class="slotMachineSlotOuter viewport">' +
								'<div id="' + this.id + '_slotButtonTop" class="slotButton slotButtonTop">' +
									'<div class="top"></div>' +
								'</div>' +
								'<div id="' + this.id + '_slotScrollPane" class="slotScrollPane">' +
									'<div id="' + this.id + '_slotItems" class="slotItems">' +
									'</div>' +
								'</div>' +
								'<div class="slotLens slotLensLeft">' +
									'<div class="slotLens slotLensRight">' +
										'<div class="slotLens slotLensCenter">' +
										'</div>' +
									'</div>' +
								'</div>' +
								'<div class="slotGlass slotGlassLeft">' +
									'<div class="slotGlass slotGlassRight">' +
										'<div class="slotGlass slotGlassCenter">' +
										'</div>' +
									'</div>' +
								'</div>' +
								'<div id="' + this.id + '_slotButtonBottom" class="slotButton slotButtonBottom">' +
									'<div class="bottom"></div>' +
								'</div>' +
							'</div>' +
						'</td>'
					);
					return slot;
				},
				appendItem: function(item){
					if (item && item.instanceOf(SlotMachineSlotItem)){
						this.items.push(item);
					}
				},
				adaptSlotDimensions: function(){
					var outer = $('#' + this.id + '_outer');
					if (this.width) outer.width(this.width);
					var slotGlass = outer.find('.slotGlassLeft');
					var slotLens = outer.find('.slotLensLeft');
					var slotScrollPane = outer.find('.slotScrollPane');
					// slot outer dimensions
					var ohDim = {'w': outer.width(), 'h': outer.height()};
					// adjust slot outer inner slot glass to the target center.
					slotGlass.css({'width': ohDim.w})
						.find('.slotGlassCenter')
						.css({'width': ohDim.w - 8, 'margin-left': 4});
					// slot glass dimenesions
					var glassDim = {'w': slotGlass.width(), 'h': slotGlass.height()};
					// slot glass offset.
					slotGlass.css({'top': (ohDim.h - glassDim.h) / 2, 'left': (ohDim.w - glassDim.w) / 2});
					// adjust slot lens.
					slotLens.css({'width': ohDim.w + 6, 'left': 0})
						.find('.slotLensCenter')
						.css({'width': ohDim.w + 6 - 16, 'margin-left': 8});
					// slot lens dimensions
					var lensDim = {'w': slotLens.width(), 'h': slotLens.height()};
					// adjust lens offset.
					slotLens.css({'top': (ohDim.h - lensDim.h) / 2 + 5, 'left': (ohDim.w - lensDim.w) / 2});
					// adjust slot outer inner slot scroll pane to the target center.
					slotScrollPane.css({'width': ohDim.w})
						.css({'width': glassDim.w, 'height': glassDim.h - 5});
					// slot scroll pane offset.
					slotScrollPane.css({'top': ((ohDim.h - glassDim.h) / 2) + 2, 'left': (ohDim.w - glassDim.w) / 2});
					
				},
				appendItemsToSlot: function(){
					var outer = $('#' + this.id + '_outer');
					var slotGlass = outer.find('.slotGlassLeft');
					var target = $('#' + this.id + '_slotItems');
					var spacerItem = $('<div class="slotItemsSpacerItem"></div>');
					spacerItem.height(slotGlass.height() / 2);
					var bottomSpacerItem = spacerItem.clone();
					var self = this;
					$(this.items).each(function(i){
						if (i == 0) target.append(spacerItem);
						this.make(target);
						if (i + 1 == self.items.length) target.append(bottomSpacerItem);
					});
				},
				adaptAndDisplayButtons: function(){
					var outer = $('#' + this.id + '_outer');
					var slotGlass = outer.find('.slotGlassLeft');
					var button = outer.find('.slotButton');
					var buttonTop = outer.find('.slotButtonTop');
					var buttonBottom = outer.find('.slotButtonBottom');
					button.css({'width': slotGlass.width()});
					buttonTop.css({'top': slotGlass.position().top - button.height()});
					buttonBottom.css({'top': slotGlass.position().top + slotGlass.height()});
				},
				setWidth: function(width){
					if (width && typeof width == 'number'){
						this.width = width;
						this.adaptSlotDimensions();
						this.adaptAndDisplayButtons();
					}
				},
				scrollToItem: function(currentItem, button, duration){
					var curr = null;
					if (button){
						if (button == 'up' || button == 'down'){
							var up = button == 'up' ? true : false;
							var down = button == 'down' ? true : false;
						}else{
							button = $(button);
							var up = button.hasClass('top');
							var down = button.hasClass('bottom');
						}
						if (down){
							if (currentItem < this.items.length - 1){
								$('#' + this.id + '_slotItem_' + currentItem).removeClass('slotMachineItemHere');
								curr = ++this.currentItem;
							}
						}
						if (up){
							if (currentItem > 0){
								$('#' + this.id + '_slotItem_' + currentItem).removeClass('slotMachineItemHere');
								curr = --this.currentItem;
							}else{
								curr = -1;
							}
						}
					}else{
						SlotMachine.setActionKeeper({'opacity': 1, 'background': 'transparent'});
						curr = this.currentItem = currentItem;
					}
					var self = this;
					var items = $('div[id^=' + this.id + '_slotItem_]');
					this.slotDataValidCheck(curr);
					if (curr != null && curr > -1){
						var dur = 300;
						if (duration || duration == 0) dur = duration;
						$('#' + this.id + '_slotScrollPane').scrollTo(
							'#' + this.id + '_slotItem_' + curr,
							{
								'offset': -60,
								'duration': dur,
								'easing': 'elasout',
								'onAfter': function(){
									// after the slot catch trigger a callback
									var cb = SlotMachine.onAfterSlotCatch;
									if (cb) cb.call(SlotMachine, self);
									$('#' + self.id + '_slotItem_' + curr).addClass('slotMachineItemHere');
									items.each(function(i){
										if (curr != i) $(this).removeClass('slotMachineItemHere');
									});
									
									if (!self.initMode){
										if (self.clickTimeout) clearTimeout(self.clickTimeout);
										self.clickTimeout = setTimeout(function(){
											self.clickTimeout = null;
											SlotMachine.data.art_id = null;
											SlotMachine.data[SlotMachine.data.pk] = null;
											SlotMachine.verifyData(self);
										}, 500);
									}
									self.initMode = false;
								}
							}
						);
					}
				},
				make: function(target){
					if (target){
						var slotLay = this.makeSlotLayout();
						var slotTitle = this.makeSlotTitle();
						var titleTarget = target.find('#slotMachineMainBg tr.titles');
						var target = target.find('#slotMachineMainBg tr.slots');
						titleTarget.append(slotTitle);
						target.append(slotLay);
						this.adaptSlotDimensions();
						this.appendItemsToSlot();
						this.adaptAndDisplayButtons();
						var self = this;

						$('#' + this.id +'_slotButtonTop div, #' + this.id +'_slotButtonBottom div')
							.bind('click', function(e){
								self.scrollToItem(self.currentItem, this);
							})
							.bind('mousedown', function(e){
								if (! self.mouseDownInterval){
									var button = this;
									self.mouseDownInterval = setInterval(function(){
										self.scrollToItem(self.currentItem, button, 200);
									}, 300);
								}
							})
							.bind('mouseup', function(e){
								if (self.mouseDownInterval){
									clearInterval(self.mouseDownInterval);
									self.mouseDownInterval = null;
								}
							})
							.hover(
								function(){$(this).addClass('active')},
								function(){$(this).removeClass('active')}
							);
						// initial scroll to the pre configured item.
						this.scrollToItem(this.currentItem);
					}
				},
				update: function(slotData){
					this.items = [];
					this.initMode = true;
					$('#' + this.id + '_outer').find('.slotItems').empty();
					$('#' + this.id + '_titleColumn').find('.slotTitle').text(slotData.title);
					var self = this;
					$(slotData.items).each(function(i){
						if (this.type == 'SlotMachineSlotItem'){
							var slotItem = SlotMachineSlotItem.create(this.title, this.value);
							slotItem.id = self.id + '_slotItem_' + i;
							slotItem.itemCnt = i;
							slotItem.data = this;
							slotItem.slot = self;
							slotItem.width = self.width;
							self.appendItem(slotItem);
						}
					});
					this.appendItemsToSlot();
					var realWidth = this.width;
					var itemsHasImage = false;
					$(this.items).each(function(i){
						if (this.data.img) itemsHasImage = true;
						var item = $('#' + this.id);
						var scrollWidth = item.get(0).scrollWidth;
						if (scrollWidth > self.width && scrollWidth > realWidth){
							realWidth = scrollWidth;
						}
						item.css({'width': 'auto'});
					});
					if (this.items.length > 0){
						var addSpace = itemsHasImage ? 53 : 10;
						if (realWidth > this.width) this.setWidth(realWidth + addSpace);
						this.scrollToItem(slotData.currentItem, null, 0);
					}
				},
				slotDataValidCheck: function(currentItem){
					var outer = $('#' + this.id + '_outer');
					if (currentItem == 0 || currentItem == -1){
						outer.addClass('slotMachineSlotOuter_pass');
						outer.find('.slotLensLeft').addClass('slotLensLeft_pass');
						outer.find('.slotLensRight').addClass('slotLensRight_pass');
						outer.find('.slotLensCenter').addClass('slotLensCenter_pass');
					}else{
						outer.removeClass('slotMachineSlotOuter_pass');
						outer.find('.slotLensLeft').removeClass('slotLensLeft_pass');
						outer.find('.slotLensRight').removeClass('slotLensRight_pass');
						outer.find('.slotLensCenter').removeClass('slotLensCenter_pass');
					}
				}
			}
		);
	/* << */

	/* >> slot machine item */
		SlotMachineSlotItem = $.extend(
			$.clone(LLObject),
			{
				create: function(title, value){
					var slotMachineItem = LLObject.create.call(this);
					slotMachineItem.id = null;
					slotMachineItem.itemCnt = null;
					slotMachineItem.title = title;
					slotMachineItem.value = value;
					slotMachineItem.data = null;
					slotMachineItem.slot = null;
					slotMachineItem.width = 118;
					return slotMachineItem;
				},
				makeItemLayout: function(){
					var item = $(
						'<div id="' + this.id + '" class="slotMachineItem"><div class="inner">' + this.title + '</div></div>'
					);
					item.css({'width': this.width, 'overflow': 'hidden'});
					if (this.data.img){
						var img = this.data.img;
						item.addClass('slotMachineItemWithImage').find('.inner').css({'background-image': 'url(' + img.src + ')'});
					}
					var self = this;
					item.bind('click', function(e){
						var currItem = $('#' + self.slot.items[self.slot.currentItem].id);
						currItem.removeClass('slotMachineItemHere');
						self.slot.scrollToItem(self.itemCnt);
					});
					return item;
				},
				make: function(target){
					if (target){
						target.append(this.makeItemLayout());
					}
				}
			}
		);
	/* << */
	
	/* >> Slot machine initialization */
		// starts the slot machine
		StartSlotmachine = function(){
			QuickChoice = TopProductQuickChoice.create();
			ScartPreparer = ShoppingcartPreparer.create();
			AddOptions = AdditionalOptions.create();
			CustFormats = CustomFormats.create();
			CostTables = CostsTableHandler.create();
			LinkPreparer = PageLinkPreparer.create();
			ResetPreparer = ResetButtonPreparer.create();
			TopImagePrep = TopImagePreparer.create();
			ErrorMsgHandler = ErrorMessagesHandler.create();
			SlotMachine.init(
				{
					'target': $('#slotMachine'),
					'onAfterInit': function(data){
						var opts = {
							'title': data.productTitle,
							'data': data,
							'target': $('#prdConfTopConfig'),
							'slot': this
						}
						QuickChoice.init(opts);
						ScartPreparer.update(data);
						AddOptions.update(data);
						CustFormats.update(data);
						CostTables.init(data, $('#prdConfCostsOuterTable'));
						LinkPreparer.update(data, this.urlParams);
						ResetPreparer.make();
						TopImagePrep.update(data);
						ErrorMsgHandler.handleError(data);
					},
					'onAfterSlotCatch': function(slot){
					},
					'onDataRequest': function(slot, oldData){
					},
					'onDataRequestSuccess': function(slot, data){
						ScartPreparer.update(data);
						AddOptions.update(data);
						CustFormats.update(data);
						CostTables.update(data);
						LinkPreparer.update(data, this.urlParams);
						QuickChoice.opts = {
							'title': data.productTitle,
							'data': data,
							'target': $('#prdConfTopConfig'),
							'slot': slot
						}
						QuickChoice.update(slot);
						ErrorMsgHandler.handleError(data);
					}
				}
			);
		}
	/* << */
/* << */


/* >> Slot Machine add ons there are triggered on slot machine events*/
	/* >> top image preparer */
		TopImagePreparer = $.extend(
			$.clone(LLObject),
			{
				create: function(){
					var o = LLObject.create.call(this);
					return o;
				},
				update: function(data){
					if (data.groupImage){
						var target = $('div.prdConfTopShell').find('img.prdConfTopShellImage');
						if (target.size() > 0){
							target.css({
								'background-image': 'url(' + data.groupImage.src + ')'
							});
						}
					}
				}
			}
		);
	/* << */

	/* >> top product quick choice */
		TopProductQuickChoice = $.extend(
			$.clone(LLObject),
			{
				create: function(){
					var o = LLObject.create.call(this);
					this.subtitle = null;
					return o;
				},
				init: function(opts){
					this.opts = opts || null;
					if (this.opts) this.target = this.opts.target || null;
					if (this.target.size() > 0){
						this.makeTableWithTitle();
						if (this.opts.onlyInfo){
							this.makeRowsForInfo();
						}else{
							this.makeRowsWithBindings();
						}
					}
				},
				makeTableWithTitle: function(){
					var t = this.target;
					var title = this.opts.title || null;
					var subtitle = this.opts.data.subTitle || null;
					this.subtitle = subtitle;
					var table = $(
						'<table cellspacing="0" cellpadding="0" border="0">' +
						'</table>'
					);
					if (title){
						var titleElm = $(
							'<tr>' +
								'<th></th>' +
								'<th>' + title + '</th>' +
							'</tr>'
						);
						if (subtitle){
							titleElm.find('th:nth-child(2)').addClass('withSub');
						}
						table.append(titleElm);
					}
					if (subtitle){
						table.append(
							'<tr>' +
								'<th></th>' +
								'<th class="subtitle">' + subtitle + '</th>' +
							'</tr>'
						);
					}
					
					t.empty().append(table);
				},
				getRowClone: function(){
					var r = $(
						'<tr>' +
							'<td class="title"></td>' +
							'<td class="value"></td>' +
						'</tr>'
					);
					return r.clone();
				},
				getFinalInfoRow: function(infoText){
					if (infoText){
						var row = this.getRowClone();
						row.find('.title').addClass('infoTextTitle').html($.lang('infoTextPmt'));
						row.find('.value').addClass('valueWrapped').append('<div class="infoText">' + infoText + '</div>');
						return row;
					}
					return null;
				},
				makeRowsWithBindings: function(){
					var slots = SlotMachine.slots;
					var infoText = this.opts.data.infoText;
					var table = this.target.find('table');
					var self = this;
					$(slots).each(function(i){
						var slot = this;
						var row = self.getRowClone();
						row.find('.title').html(slot.title);
						var value = row.find('.value');
						var info = slot.items[slot.currentItem].title;
						var addInfoText = slot.items[slot.currentItem].data.addInfoText;
						if (addInfoText){
							info += ' (' + addInfoText + ')';
						}
						value.html(info);
						table.append(row);
					});
					var infoRow = this.getFinalInfoRow(infoText);
					if (infoRow){
						table.append(infoRow);
					}
				},
				makeRowsForInfo: function(){
					var slots = this.opts.data.slots;
					var infoText = this.opts.data.infoText;
					var table = this.target.find('table');
					var self = this;
					if (slots){
						$(slots).each(function(i){
							var slot = this;
							var row = self.getRowClone();
							row.find('.title').html(slot.title);
							var value = row.find('.value');
							for (var j in slot.items){
								if (j == slot.currentItem){
									var info = slot.items[j].title;
									var addInfoText = slot.items[j].addInfoText;
									if (addInfoText){
										info += ' (' + addInfoText + ')';
									}
									value.html(info);
								}
							}
							table.append(row);
						});
					}
					var infoRow = this.getFinalInfoRow(infoText);
					if (infoRow){
						table.append(infoRow);
					}
				},
				update: function(slot, data){
					var subtitle = this.subtitle;
					if (slot){
						var elm = $('#prdConfTopConfig');
						if (elm.size() > 0){
							var index = 2;
							if (subtitle) index += 1;
							var valCol = elm.find('tr:nth-child(' + (slot.itemId + index) + ')').find('.value');
							var info = slot.items[slot.currentItem].title;
							var addInfoText = slot.items[slot.currentItem].data.addInfoText;
							if (addInfoText){
								info += ' (' + addInfoText + ')';
							}
							valCol.html(info);
						}
					}
					var infoText = data.infoText;
					if (infoText){
						if (this.target.find('.value .infoText').size() > 0){
							this.target.find('.value .infoText').addClass('valueWrapped').html(infoText);
						}else{
							var infoRow = this.getFinalInfoRow(infoText);
							if (infoRow){
								this.target.find('table').append(infoRow);
							}
						}
					}else{
						this.target.find('.value .infoText').parent('td').parent('tr').remove();
					}
				}
			}
		);
	/* << */
	
	/* >> shopping cart preparer */
		ShoppingcartPreparer = $.extend(
			$.clone(LLObject),
			{
				create: function(){
					var o = LLObject.create.call(this);
					var sc = $('div.prdConfTopWkShell');
					o.sCartForm = sc.find('form');
					o.price = sc.find('.priceSum');
					o.priceInfoWoTax = sc.find('.dutyFree');
					o.priceTax = sc.find('.duty');
					o.euroTpl = $('<span>&nbsp;&euro;</span>');
					// prepare shoppingcart action url.
					if (typeof FLYPI_CONFIGURATION_TYPE === 'undefined' || (FLYPI_CONFIGURATION_TYPE !== 'sm' && FLYPI_CONFIGURATION_TYPE !== 'xxl')){
						var action = $('.wkTopShell').find('a').attr('href') || '#';
						$('.prdConfTopWkShell').find('form').attr({'action': action});
					}
					return o;
				},
				triggerShoppingcartWithAvatar: function(){
					$('.prdConfTopWkShell').find('form').submit();
				},
				update: function(data){
					if (data.auf_id){
						$('.prdConfTopWkShell, #prdConfCustHeadWkButton').fadeIn('fast');
						//$('#prdConfTopConfig').find('th:first-child').text('Gültig!').css({'color': 'green'});
					}else{
						$('.prdConfTopWkShell, #prdConfCustHeadWkButton').fadeOut('fast');
						//$('#prdConfTopConfig').find('th:first-child').text('Ungültig!').css({'color': 'red'});
					}
					if (data && data.auf_id){
						if (data.meta){
							var m = data.meta;
							this.price.html(this.euroTpl.clone()).prepend(m.price);
							this.priceInfoWoTax.html(this.euroTpl.clone()).prepend(m.priceWoTax);
							this.priceTax.html(this.euroTpl.clone()).prepend(m.priceTax);
						}
						//var data = SlotMachine.data;
						$('#prdConfTopWk_express').val(data.express);
						$('#prdConfTopWk_overnight').val(data.overnight);
						$('#prdConfTopWk_auf_id').val(data.auf_id);
						if (data.pos_id){
							$('#prdConfTopWk_pos_id').val(data.pos_id);
						}else{
							$('#prdConfTopWk_pos_id').val('');
						}
						$('#prdConfTopWk_customerHeight').val(data.customerHeight);
						$('#prdConfTopWk_customerWidth').val(data.customerWidth);
					}
				}
			}
		);
	/* << */
	
	/* >> additional options*/
		AdditionalOptions = $.extend(
			$.clone(LLObject),
			{
				options: null,
				create: function(){
					var o = LLObject.create.call(this);
					o.optsContainer = $('#prdConfAddOptsContainer');
					o.scOptsContainer = $('#shoppingCartConfigOptData');
					return o;
				},
				update: function(data){
					var optsContainer = this.optsContainer;
					optsContainer.empty();
					var self = this;
					if (data.options && data.options.length > 0){
						$(data.options).each(function(i){
							if (this.type == 'radio'){
								var type = this.type;
								$(this.items).each(function(j){
										optsContainer.append(self.makeOption($.extend(this, {'type': type}), j + '_' + i));
								});
							}else{
								optsContainer.append(self.makeOption(this, i));
							}
						});
						self.makeShoppingCartOpts(data);
					}else{
						optsContainer.append(
							'<div class="optionOuter">' +
								'<div class="pmt">Keine verfügbar.</div>' +
							'</div>'
						);
					}
					$(data.options).each(function(i){
							if (this.type == 'radio'){
								var type = this.type;
								$(this.items).each(function(j){
									if (this.here){
										var id = 'opt_' + j + '_' + i;
										$('#' + id).attr('checked', 'checked');
									}
								});
							}else{
								if (this.here){
									var id = 'opt_' + i;
									$('#' + id).attr('checked', 'checked');
								}
							}
					});
				},
				makeShoppingCartOpts: function(data){
					var container = this.scOptsContainer;
					container.empty();
					$(data.options).each(function(i){
						if (this.type == 'text'){
							if (this.value != ''){
								container.append('<input type="hidden" name="' + this.name + '" value="' + this.value + '"/>');
							}
						}else if (this.type == 'select'){
							var select = this;
							$(this.items).each(function(j){
								if ((select.mandatory && this.here) || (this.here && j > 0)){
									container.append('<input type="hidden" name="' + select.name + '" value="opt_' + this.value + '"/>');
								}
							});
						}else if(this.type == 'checkbox'){
							if (this.here){
								container.append('<input type="hidden" name="' + this.name + '" value="opt_' + this.value + '"/>');
							}
						}else if(this.type == 'radio'){
							$(this.items).each(function(j){
								if (this.here){
									container.append('<input type="hidden" name="' + this.name + '" value="opt_' + this.value + '"/>');
								}
							});
						}
					});
				},
				makeOption: function(data, idx){
					var o = $(
						'<div class="optionOuter">' +
							'<table cellpadding="0" cellspacing="0" border="0">' +
								'<tr>' +
									'<td>' +
										'<div class="pmt">' + data.prompt + '</div>' +
									'</td>' +
									'<td>' +
										'<div class="field"></div>' +
									'</td>' +
								'</tr>' +
							'</table>' +
						'</div>'
					);
					o.find('.field').append(this.getField(data, idx));
					return o;
				},
				getField: function(data, idx){
					var optIdPfx = 'opt_';
					switch (data.type){
						case 'select':
							var f = this.select(data);
							f.attr('id', optIdPfx + idx);
							return f;
							break;
						case 'checkbox':
							var f = this.checkbox(data);
							f.attr('id', optIdPfx + idx);
							return f;
							break;
						case 'radio':
							var f = this.radio(data);
							f.attr('id', optIdPfx + idx);
							return f;
							break;
						case 'text':
							var f = this.text(data);
							f.find(':input').attr('id', optIdPfx + idx);
							return f;
							break;
					}
					return false;
				},
				getOptId: function(id){
					return id.substring(id.lastIndexOf('_') + 1, id.length);
				},
				select: function(data){
					var f = $('<select></select>').attr({'name': data.name});
					$(data.items).each(function(i){
						var o = $('<option></option>').val(this.value).text(this.content);
						if (this.here) o.attr('selected', 'selected');
						f.append(o);
					});
					var self = this;
					f.bind('change', function(e){
						var items = SlotMachine.data.options[self.getOptId(this.id)].items;
						var elm = this;
						$(items).each(function(i){
							if (this.value == $(elm).val()){
								this.here = true;
							}else{
								this.here = false;
							}
						});
						SlotMachine.data.options[self.getOptId(this.id)].items = items;
						self.verifyData();
					});
					return f;
				},
				checkbox: function(data){
					var f = $('<input/>').attr({'type': data.type, 'name': data.name, 'value': data.value});
					var self = this;
					f.bind('click', function(e){
						var here = $(this).attr('checked');
						SlotMachine.data.options[self.getOptId(this.id)].here = here;
						self.verifyData();
					});
					return f;
				},
				radio: function(data){
					var f = $('<input/>').attr({'type': 'radio', 'name': data.name, 'value': data.value});
					var self = this;
					f.bind('click', function(e){
						var items = SlotMachine.data.options[self.getOptId(this.id)].items;
						var elm = this;
						$(items).each(function(i){
							if (this.value == $(elm).val()){
								this.here = true;
							}else{
								this.here = false;
							}
						});
						SlotMachine.data.options[self.getOptId(this.id)].items = items;
						self.verifyData();
					});
					return f;
				},
				text: function(data){
					var f =  $(
						'<div class="textFieldAndButtonOuter">' +
							'<div class="fieldOuter"><input type="text" name="' + data.name + '" value="' + data.value + '"/></div>' +
							'<div class="textFieldSaveButton"></div>' +
						'</div>'
					);
					// This is a static text field char limitation and should be solved
					// at the WAF administration.
					f.find(':input').attr({'maxlength': 5});
					var self = this;
					f.find('.textFieldSaveButton').bind('click', function(e){
						var field = $(this).prev('.fieldOuter').find(':input');
						var id = field.attr('id');
						SlotMachine.data.options[self.getOptId(id)].value = field.val();
						self.verifyData();
					});
					return f;
				},
				verifyData: function(){
					SlotMachine.verifyData();
				}
			}
		);
	/* << */
	
	/* >> custom formats */
		CustomFormats = $.extend(
			$.clone(LLObject),
			{
				create: function(){
					var o = LLObject.create.call(this);
					o.format = $('#prdCustFormat');
					o.formatWidth = $('#prdCustFormatWidth');
					o.formatHeight = $('#prdCustFormatHeight');
					o.custWidth = $('#prdCustFormatWidthInput');
					o.custHeight = $('#prdCustFormatHeightInput');
					var saveFormatContentButton = $('#prdConfCustHeadFormatSaveButton');
					if (saveFormatContentButton.size() > 0){
						var self = o;
						saveFormatContentButton.bind('click', function(e){
							e.preventDefault();
							e.stopPropagation();
							SlotMachine.data.meta.formatDims.custHeight = self.custHeight.val();
							SlotMachine.data.meta.formatDims.custWidth = self.custWidth.val();
							SlotMachine.verifyData();
						});
					}
					return o;
				},
				update: function(data){
					if (data.customFormat){
						$('div.prdConfCustHead, div.prdConfCustFields').show();
						var m = data.meta;
						if (m){
							var f = m.format || '';
							if (m.formatDims){
								var fw = m.formatDims.width || 0;
								var fh = m.formatDims.height || 0;
								var cw = m.formatDims.custWidth || '';
								var ch = m.formatDims.custHeight || '';
								var suffix = m.formatDims.suffix || 'mm';
								this.format.text(f);
								this.formatWidth.text(fw);
								this.formatHeight.text(fh + ' ' + suffix);
								this.custWidth.val(cw);
								this.custHeight.val(ch);
								// prepare shopping cart
								$('#prdConfTopWk_customerWidth').val(cw);
								$('#prdConfTopWk_customerHeight').val(ch);
							}
						}
					}else{
						// reset shopping cart
						if (data.meta && data.meta.formatDims){
							data.meta.formatDims.custWidth = null;
							data.meta.formatDims.custHeight = null;
						}
						$('#prdConfTopWk_customerWidth').val('');
						$('#prdConfTopWk_customerHeight').val('');
						$('div.prdConfCustHead, div.prdConfCustFields').hide();
					}
				}
			}
		);
	/* << */

	/* >> costs table handler */
		CostsTableHandler = $.extend(
			$.clone(LLObject),
			{
				create: function(){
					var o = LLObject.create.call(this);
					return o;
				},
				init: function(data, target){
					this.data = data || null;
					this.target = target || null;
					this.update(data);
				},
				update: function(data){
					var tar = this.target;
					var lcol = tar.find('.left');
					var rcol = tar.find('.right');
					if (tar){
						if (data.costs){
							var renderer = JSONRenderer.create(data.costs, lcol);
							renderer.renderCostsExtendedTable('costs', SlotMachine);
						}else{
							lcol.empty();
							rcol.empty();
						}
						if (data.ovCosts){
							var renderer = JSONRenderer.create(data.ovCosts, rcol);
							renderer.renderCostsExtendedTable('ovCosts', SlotMachine);
						}
					}
				}
			}
		);
	/* << */
	
	/* >> page link preparer */
		PageLinkPreparer = $.extend(
			$.clone(LLObject),
			{
				create: function(){
					var o = LLObject.create.call(this);
					return o;
				},
				update: function(data, params){
					if (!params) var params = Utils.getUrlParamsAsJson(window.location.href, true);
					if (!params) params = {'auf_id': window.CONFIGURATOR_FALLBACK_DATA.auf_id};
					if (params.id) params = $.reduce(params, 'id');
					if (params.loadPos) params.loadPos = null;
					if (data.optionsParam) params = $.extend(params, data.optionsParam);
					if (data.freeConfig){
						var freeConfig = 'true';
					}else{
						var freeConfig = 'false';
					}
					params = $.extend(params, {'freeConfig': freeConfig});
					if (!data.auf_id){
						$.extend(params, {'auf_id': data.baseArticle});
					}else{
						$.extend(params, {'auf_id': data.auf_id});
					}
					if (data.overview){
						$.extend(params, {'ovn': data.overview});
					}
					if (data.express){
						$.extend(params, {'ex': data.express});
					}
					var tabItems = $('div.contentNavigationShell a');
					$(tabItems).each(function(i){
						var href = this.href;
						var rex = /\?/;
						if (rex.test(href)){
							href = this.href.substring(0, this.href.search(rex));
						}
						this.href = href + Utils.getUrlParamsFromJson(params);
					});
				}
			}
		);
	/* << */
	
	/* >> reset button preparer */
		ResetButtonPreparer = $.extend(
			$.clone(LLObject),
			{
				create: function(){
					var o = LLObject.create.call(this);
					return o;
				},
				makeButton: function(){
					var b = $(
						'<div id="slotMachineResetButton"></div>'
					);
					b.css({'cursor': 'pointer'});
					b.bind('click', function(e){
						var url = window.location.href;
						var attrs = Utils.getUrlParamsAsJson(url);
						if (url.search(/\?/) > -1) url = url.substring(0, url.search(/\?/));
						attrs = $.extend(attrs, {'freeConfig': 'true'});
						window.location = url + Utils.getUrlParamsFromJson(attrs);
					});
					return b;
				},
				make: function(){
					var b = this.makeButton();
					$(function(){
						$('#prdConfAddOpts').append(b);
					});
				}
			}
		);
	/* << */
	
	/* >> handle error messages */
		ErrorMessagesHandler = $.extend(
			$.clone(LLObject),
			{
				create: function(){
					var o = LLObject.create.call(this);
					return o;
				},
				handleError: function(data){
					if (data.errorMessage){
						alert(data.errorMessage.title + ':\n' + data.errorMessage.text);
						SlotMachine.data.errorMessage = null;
					}
				}
			}
		);
	/* << */
/* << */


/* >> json renderer require jQuery 1.2.6 Version: rel-1-0-0 */
	JSONRenderer = $.extend(
		$.clone(LLObject),
		{
			data: null,
			target: null,
			create: function(data, target){
				var o = LLObject.create.call(this);
				o.data = data || null;
				o.target = target || null;
				return o;
			},
			render: function(data, target){
				this.data = data;
				this.target = target;
				switch (data.type){
					case 'extendedTable':
						this.renderCostsExtendedTable(data);
						break;
					case 'formularRadioTable':
						this.renderFormularRadioTable(data);
						break;
				}
			},
			renderCostsExtendedTable: function(type, parent){
				var t = $('<table cellpadding="0" cellspacing="0" border="0"></table>');
				var data = this.data;
				if (data.stylename) t.attr({'class': data.stylename});
				var tar = this.target;
				tar.empty();
				var self = this;
				if (data.allowSearch){
					this._makeMenuBarAndContentShell();
					this._renderSearchFieldBar('searchWknIsinName');
				}
				if (data.columnOrder){
					var r = $('<tr></tr>');
					$(data.columnOrder).each(function(i){
						var c = $('<th class="thead thead' + i + '">' + this.header + '</th>');
						if (! isNaN(parseInt(data.columnOrder[i].order))){
							var key = data.columnOrder[i].key;
							var order = data.columnOrder[i].order;
							if (order != null) c.addClass('receiveClick');
							if (order == 1) c.addClass('sortedUp');
							if (order == 2) c.addClass('sortedDown');
							c.bind('click', function(e){
								(function(ord, parent, d){
									ord = (ord + 1) % 3;
									if (d.handler){
										var phrase = null
										if (parent.searchPhrase) phrase = parent.searchPhrase;
										var url = AjaxURLManager.getUrlWithKey(d.handler, {'phrase': phrase, 'field': key, 'order': ord});
										$.getJSON(url, function(data, textStatus){
											JSONPanelContentRenderer.render(data, parent);
										});
									}
								})(order, self.parent, data);
							});
						}
						r.append(c);
					});
					t.append(r);
				}
				var rows = data.rows;
				if (data.pager){
					rows = this._getPagerPreparedList(rows, data.pager);
				}
				$(rows).each(function(i){
					r = $('<tr></tr>');
					if (i % 2 != 0) r.addClass('odd');
					if (this.special) r.addClass('special');
					if (this.here) r.addClass('here');
					var rowData = this;
					if (data.columnOrder){
						$(data.columnOrder).each(function(j){
							var k = this.key;
							var c = $('<td class="col col_' + j + ' col_' + j + '_' + i + '"></td>');
							var row = rows[i];
							var cell = rows[i][k]; // data.rows[i][k];
							if (j == 0 && row.bestprice){
								c.addClass('bestprice');
							}
							// binding row for mouseevent click
							if (row[data.pk]){
								self._handleRowClick(c, row, type, parent, data);
								c.css({'cursor': 'pointer'});
							}
							// binding row for hover effects
							r.hover(
								function(){
									$(this).children('td').addClass('mouseOver');
								},
								function(){
									$(this).children('td').removeClass('mouseOver');
								}
							);
							if (cell.title.__datetime__){
								var title = $('<span>' + $.formatDate(cell.title.value, $.lang())._middle  + '&nbsp;' + $.formatTime(cell.title.value).time + '</span>');
							}else{
								if (parseInt(cell.mode) > 0 || parseInt(cell.mode) < 0 || parseInt(cell.mode) == 0){
									var title = $('<div><span>' + cell.title + '</span></div>');
									var sty = 'vNoChanges';
									if (parseInt(cell.mode) > 0) sty = 'vPlus';
									if (parseInt(cell.mode) < 0) sty = 'vMinus';
									title.addClass(sty);
								}else{
									var title = $('<span>' + cell.title + '</span>');
								}
							}
							c.append(title);
							if (cell.href) title.wrap('<a href="' + cell.href + '" target="' + cell.target + '"></a>');
							// add shoppingcart symbol to last column of the selected row
							if (j == data.columnOrder.length - 1 && rowData.here){
								if (c.text().charCodeAt(0) != 160){
									var scartSym = $('<div class="viewport"><div class="smallScartSym"></div></div>');
									self._handleRowShoppingcartClick(scartSym.find('.smallScartSym'), row, type, parent, data);
									c.prepend(scartSym);
								}
							}
							r.append(c);
						});
					}else{
						var cnt = 0;
						for( var k in this){
							var c = $('<td class="col col_' + cnt + ' col_' + cnt + '_' + i + '"></td>');
							var row = rows[i];
							var cell = rows[i][k]; // data.rows[i][k];
							// binding context menu
							if (data.contextType && this.contextActive){
								(function(row){
									c.bind('click', function(e){
										var m = MenuConfig[data.contextType](self.parent, row, e);
										m.init();
										m.show(e);
									});
								})(row);
								c.addClass('receiveClick');
							}
							if (cell.title.__datetime__){
								var title = $('<span>' + $.formatDate(cell.title.value, $.lang())._middle  + '&nbsp;' + $.formatTime(cell.title.value).time + '</span>');
							}else{
								if (parseInt(cell.mode) > 0 || parseInt(cell.mode) < 0 || parseInt(cell.mode) == 0){
									var title = $('<div><span>' + cell.title + '<span></div>');
									var sty = 'vNoChanges';
									if (parseInt(cell.mode) > 0) sty = 'vPlus';
									if (parseInt(cell.mode) < 0) sty = 'vMinus';
									title.addClass(sty);
								}else{
									var title = $('<span>' + cell.title + '</span>');
								}
							}
							c.append(title);
							if (cell.href) title.wrap('<a href="' + cell.href + '" target="' + cell.target + '"></a>');
							r.append(c);
							cnt++;
						}
					}
					t.append(r);
				});
				if (data.allowSearch){
					tar.find('div[id$=_content]').append(t);
				}else{
					tar.append(t);
				}
			},
			renderFormularRadioTable: function(tableIdx, parent, id, item){
				var t = $('<table cellpadding="0" cellspacing="0" border="0"></table>');
				var data = this.data;
				if (data.stylename) t.attr({'class': data.stylename});
				var tar = this.target;
				tar.empty();
				var self = this;
				if (data.allowSearch){
					this._makeMenuBarAndContentShell();
					this._renderSearchFieldBar('searchWknIsinName');
				}
				if (data.columnOrder){
					var r = $('<tr></tr>');
					$(data.columnOrder).each(function(i){
						var c = $('<th class="thead thead' + i + '">' + this.header + '</th>');
						if (! isNaN(parseInt(data.columnOrder[i].order))){
							var key = data.columnOrder[i].key;
							var order = data.columnOrder[i].order;
							if (order != null) c.addClass('receiveClick');
							if (order == 1) c.addClass('sortedUp');
							if (order == 2) c.addClass('sortedDown');
							c.bind('click', function(e){
								(function(ord, parent, d){
									ord = (ord + 1) % 3;
									if (d.handler){
										var phrase = null
										if (parent.searchPhrase) phrase = parent.searchPhrase;
										var url = AjaxURLManager.getUrlWithKey(d.handler, {'phrase': phrase, 'field': key, 'order': ord});
										$.getJSON(url, function(data, textStatus){
											JSONPanelContentRenderer.render(data, parent);
										});
									}
								})(order, self.parent, data);
							});
						}
						r.append(c);
					});
					t.append(r);
				}
				var rows = data.rows;
				if (data.pager){
					rows = this._getPagerPreparedList(rows, data.pager);
				}
				$(rows).each(function(i){
					r = $('<tr></tr>');
					if (i % 2 != 0) r.addClass('odd');
					if (this.special) r.addClass('special');
					var checked = false;
					if (this.here){
						r.addClass('here');
						var checked = true;
					}
					if (data.columnOrder){
						$(data.columnOrder).each(function(j){
							var k = this.key;
							var c = $('<td class="col col_' + j + ' col_' + j + '_' + i + '"></td>');
							var row = rows[i];
							var cell = rows[i][k]; // data.rows[i][k];
							// binding row for mouseevent click
							if (row[data.pk]){
								(function(row, parent, d, item, tableIdx, rowIdx){
									c.bind('click', function(e){
										item.handlePrepareDataModelAndVerify(tableIdx, rowIdx);
									});
								})(row, parent, data, item, tableIdx, i);
								c.css({'cursor': 'pointer'});
								if (j == data.columnOrder.length - 1){
									c.addClass('priceColumn');
								}
							}
							if (cell.title.__datetime__){
								var title = $('<span>' + $.formatDate(cell.title.value, $.lang())._middle  + '&nbsp;' + $.formatTime(cell.title.value).time + '</span>');
							}else{
								var t = cell.title;
								if (parseInt(cell.mode) > 0 || parseInt(cell.mode) < 0 || parseInt(cell.mode) == 0){
									var title = $('<div><span>' + t + '</span></div>');
									var sty = 'vNoChanges';
									if (parseInt(cell.mode) > 0) sty = 'vPlus';
									if (parseInt(cell.mode) < 0) sty = 'vMinus';
									title.addClass(sty);
								}else{
									var title = $('<span>' + t + '</span>');
								}
								if (k == 'option'){
									t = $('<input type="radio" name="' + id + '" value="' + row[data.pk] + '" />');
									t.attr({'checked': checked});
									if (title.find('span').size() > 0){
										title.find('span').append(t);
									}else{
										title.append(t);
									}
								}
							}
							c.append(title);
							if (cell.href) title.wrap('<a href="' + cell.href + '" target="' + cell.target + '"></a>');
							r.append(c);
						});
					}else{
						var cnt = 0;
						for(var k in this){
							var c = $('<td class="col col_' + cnt + ' col_' + cnt + '_' + i + '"></td>');
							var row = rows[i];
							var cell = rows[i][k]; // data.rows[i][k];
							// binding context menu
							if (data.contextType && this.contextActive){
								(function(row){
									c.bind('click', function(e){
										var m = MenuConfig[data.contextType](self.parent, row, e);
										m.init();
										m.show(e);
									});
								})(row);
								c.addClass('receiveClick');
							}
							if (cell.title.__datetime__){
								var title = $('<span>' + $.formatDate(cell.title.value, $.lang())._middle  + '&nbsp;' + $.formatTime(cell.title.value).time + '</span>');
							}else{
								if (parseInt(cell.mode) > 0 || parseInt(cell.mode) < 0 || parseInt(cell.mode) == 0){
									var title = $('<div><span>' + cell.title + '<span></div>');
									var sty = 'vNoChanges';
									if (parseInt(cell.mode) > 0) sty = 'vPlus';
									if (parseInt(cell.mode) < 0) sty = 'vMinus';
									title.addClass(sty);
								}else{
									var title = $('<span>' + cell.title + '</span>');
								}
							}
							c.append(title);
							if (cell.href) title.wrap('<a href="' + cell.href + '" target="' + cell.target + '"></a>');
							r.append(c);
							cnt++;
						}
					}
					t.append(r);
				});
				if (data.allowSearch){
					tar.find('div[id$=_content]').append(t);
				}else{
					tar.append(t);
				}
			},
			_handleRowClick: function(column, row, type, parent, d){
				column.bind('click', function(e){
					e.preventDefault();
					e.stopPropagation();
					var data = parent.data;
					parent.urlParams.ovn = 'false';
					data.overnight = false;
					if (type == 'ovCosts'){
						data.overnight = true;
						parent.urlParams.ovn = 'true';
					}
					data[d.pk] = row[d.pk];
					parent.data = data;
					parent.verifyData();
				});
			},
			_handleRowShoppingcartClick: function(scart, row, type, parent, d){
				scart.bind('click', function(e){
					e.preventDefault();
					e.stopPropagation();
					var data = parent.data;
					parent.urlParams.ovn = 'false';
					data.overnight = false;
					if (type == 'ovCosts'){
						data.overnight = true;
						parent.urlParams.ovn = 'true';
					}
					data[d.pk] = row[d.pk];
					parent.data = data;
					if (typeof parent.verifyDataAndAddToShoppingcart == 'undefined'){
						parent = $.extend(parent, {
							verifyDataAndAddToShoppingcart: function(){
								var slot = slot || null;
								var self = this;
								this.setActionKeeper({'opacity': 1, 'background': 'transparent'});
								var oldData = SlotMachine.data;
								if (slot) SlotMachine.data.changedSlot = slot.itemId;
								var cbdr = SlotMachine.onDataRequest;
								if (cbdr) cbdr.call(SlotMachine, self, SlotMachine.data);
								var url = AjaxURLManager.getUrlWithKey('configarticle');
								//alter data and send it to cherrypy
								for (var i in this.data.slots){
									this.data.slots[i].currentItem = this.slots[i].currentItem;
								}
								$.ajax({
									type: 'post',
									url: url,
									data: {'content': encodeURIComponent($.toJson(SlotMachine))},
									success: function(data, msg){self.verifyDataAndAddToShoppingcartRequestSuccess(data, msg, slot);},
									error: function(req, status, error){self.verifyDataRequestError(req, status, error, slot);}
								});
							},
							verifyDataAndAddToShoppingcartRequestSuccess: function(data, msg, slot){
								//eval('var data = ' + data);
								this.data = data;
								if (this.urlParams && this.urlParams.auf_id) this.urlParams.auf_id = data.auf_id;
								if (this.onDataRequestSuccess) this.onDataRequestSuccess.call(this, slot, data);
								this.slotUpdateCheck();
								this.clearActionKeeper();
								$('div.prdConfTopWkShell').find('form').submit();
							}
						});
						parent.verifyDataAndAddToShoppingcart();
					}
				});
			}
		}
	);
/* << */


/* >> Slot machine tapped pages shopping cart info */
	//show the quick config and shopping cart info on tabbed config pages.
	ShowShoppingCartInfo = $.extend(
		$.clone(LLObject),
		{
			create: function(){
				var o = LLObject.create.call(this);
				return o;
			},
			update: function(data, quickInfo, scart){
				var qi = TopProductQuickChoice.create();
				var opts = {
					'title': data.productTitle,
					'data': data,
					'target': quickInfo,
					'slot': null,
					'onlyInfo': true
				}
				qi.init(opts);
			}
		}
	);
/* << */


/* >> Tapped pages handling */
	handlePageTabs = function(){
		var configType = window.FLYPI_CONFIGURATION_TYPE || null;
		if (configType == 'sm'){
			var configurator = $('#slotMachine');
			if (configurator.size() == 0){
				var urlParams = Utils.getUrlParamsAsJson(window.location.href);
				var url = AjaxURLManager.getUrlWithKey('configarticle', urlParams);
				var quickInfo = $('#prdConfTopConfig');
				var scart = $('div.prdConfTopWkShell');
				if (quickInfo.size() > 0 && scart.size() > 0){
					$.getJSON(url, function(data, textStatus){
						CustFormats = CustomFormats.create();
						CustFormats.update(data);
						LinkPreparer = PageLinkPreparer.create();
						LinkPreparer.update(data);
						ScartInfo = ShowShoppingCartInfo.create();
						ScartInfo.update(data, quickInfo, scart);
						ScartPreparer = ShoppingcartPreparer.create();
						ScartPreparer.update(data);
						AddOption = AdditionalOptions.create();
						AddOption.makeShoppingCartOpts(data);
						TopImagePrep = TopImagePreparer.create();
						TopImagePrep.update(data);
					});
				}
			}
		}else if(configType == 'xxl'){
			var configurator = $('#rowFilteredXxlConfigurator');
			if (configurator.size() == 0){
				var urlParams = Utils.getUrlParamsAsJson(window.location.href);
				var url = AjaxURLManager.getUrlWithKey('xxlproduct', urlParams);
				var quickInfo = $('#prdConfTopConfigXxl');
				var scart = $('div.prdConfTopWkShell');
				if (quickInfo.size() > 0 && scart.size() > 0){
					$.getJSON(url, function(data, textStatus){
						LinkPreparerXxl = PageLinkPreparerXxl.create();
						LinkPreparerXxl.update(data);
						ScartInfo = ShowShoppingCartInfo.create();
						ScartInfo.update(data, quickInfo, scart);
						ScartPreparer = ShoppingcartPreparer.create();
						ScartPreparer.update(data);
						TopImagePrep = TopImagePreparer.create();
						TopImagePrep.update(data);
						AddOptsXxl = AdditionalOptionsXxl.create();
						AddOptsXxl.update(data);
						/* todo: add handlers for tabbed pages */
					});
				}
			}
		}
	}

	$(function(){
		handlePageTabs();
	});
/* << */


/* >> Creative pilot step bar control */
	CreativePilotStepBarControl = $.extend(
		$.clone(LLObject),
		{
			create: function(){
				var o = LLObject.create.call(this);
				return o;
			},
			update: function(step){
				var stepBar = $('#creativePilotTopStateNav');
				if (stepBar.size() > 0){
					var steps = stepBar.find('li');
					$(steps).each(function(i){
						if (step >= i){
							$(this).addClass('stateNavItemActive');
							$(this).find('a').css({'cursor': 'pointer'}).unbind();
						}else{
							$(this).removeClass('stateNavItemActive');
							$(this).find('a').css({'cursor': 'default'}).bind('click', function(e){
								e.preventDefault();
								e.stopPropagation();
							});
						}
					});
				}
			}
		}
	);
/* << */


/* >> Creative pilot configurator (inherit SlotMachine) */
	/* >> Slot machine select variant*/
		SlotMachineSelectVariant = $.extend(
			$.clone(SlotMachine),
			{
				init: function(opts){
					window.slotMachinePresent = 1;
					if (opts){
						this.opts = opts;
						this.makeShell(opts.target);
						//{'auf_id': 917440} product test
						var urlParams = this.urlParams = this.getURLParams();
						urlParams = $.extend(urlParams, {'cp': 'true'});
						if (!urlParams.ovn) urlParams.ovn = 'false';
						this.url = AjaxURLManager.getUrlWithKey('configarticle', urlParams);
						if (this.urlParams.loadPos) this.urlParams.loadPos = null;
						var cb = opts.onAfterSlotCatch;
						if (cb && typeof cb == 'function') this.onAfterSlotCatch = cb;
						var cbdr = opts.onDataRequest;
						if (cbdr && typeof cbdr == 'function') this.onDataRequest = cbdr;
						var cbdrs = opts.onDataRequestSuccess;
						if (cbdrs && typeof cbdrs == 'function') this.onDataRequestSuccess = cbdrs;
						if (this.url){
							var self = this;
							$.getJSON(this.url, function(data, textStatus){
								var d = self.data = data;
								if (d.type == 'SlotMachineData'){
									$(d.slots).each(function(i){
										if (this.type == 'SlotMachineSlot'){
											var slot = SlotMachineSlotSelectVariant.create(this.title, this.currentItem);
											slot.id = 'slot_' + i;
											slot.itemId = i;
											slot.data = this;
											slot.width = this.width;
											$(this.items).each(function(i){
												if (this.type == 'SlotMachineSlotItem'){
													var slotItem = SlotMachineSlotItemSelectVariant.create(this.title, this.value);
													slotItem.id = slot.id + '_slotItem_' + i;
													slotItem.itemCnt = i;
													slotItem.data = this;
													slotItem.slot = slot;
													slotItem.width = slot.width;
													slot.appendItem(slotItem);
												}
											});
											self.appendSlot(slot);
										}
									});
								}
								// call init callback if exists
								var initCb = opts.onAfterInit;
								if (initCb && typeof initCb == 'function'){
									initCb.call(self, self.data);
								}
								if (self.onDataRequestSuccess) self.onDataRequestSuccess.call(self, null, d);
							});
						}
					}
				},
				makeShell: function(target){
					var shell = $(
						'<div id="slotMachineSelectVariantOuter">' +
							'<div id="slotMachineSelectVariantMainBg">' +
								'<table cellpadding="0" cellspacing="0" border="0" class="slotOuterSelectVariantShell">' +
								'</table>' +
							'</div>' +
						'</div>'
					);
					target.append(shell);
				},
				verifyData: function(slot){
					var slot = slot || null;
					var self = this;
					var oldData = this.data;
					if (slot) this.data.changedSlot = slot.itemId;
					var cbdr = this.onDataRequest;
					if (cbdr) cbdr.call(this, self, this.data);
					var url = AjaxURLManager.getUrlWithKey('configarticle');
					//alter data and send it to cherrypy
					for (var i in this.data.slots){
						this.data.slots[i].currentItem = this.slots[i].currentItem;
					}
					$.ajax({
						type: 'post',
						url: url,
						data: {'content': encodeURIComponent($.toJson(SlotMachineSelectVariant))},
						success: function(data, msg){self.verifyDataRequestSuccess(data, msg, slot);},
						error: function(req, status, error){self.verifyDataRequestError(req, status, error, slot);}
					});
				},
				verifyDataRequestSuccess: function(data, msg, slot){
					//eval('var data = ' + data);
					this.data = data;
					if (this.urlParams && this.urlParams.auf_id) this.urlParams.auf_id = data.auf_id;
					if (this.onDataRequestSuccess) this.onDataRequestSuccess.call(this, slot, data);
					this.slotUpdateCheck();
				},
				verifyDataRequestError: function(req, status, error, slot){
					/* todo: .... */
				}
			}
		);
	/* << */

	/* >> slot machine slot select variant (inherit SlotMachineSlot) */
		SlotMachineSlotSelectVariant = $.extend(
			$.clone(SlotMachineSlot),
			{
				create: function(title, currentItem){
					return SlotMachineSlot.create.call(this, title, currentItem);
				},
				makeSlotLayout: function(){
					var slot = $(
						'<tr>' +
							'<td class="' + this.id + '_titleColumn titleColumn"><div class="slotTitle"><span>' + this.title + '</span></div></td>' +
							'<td class="' + this.id + '_column selectColumn">' +
								'<div class="slotSelect">' +
									'<select name="' + this.id + '_select" id="' + this.id + '_select"></select>' +
								'</div>' +
							'</td>' +
						'</tr>'
					);
					var self = this;
					slot.find('select').bind('change', function(e){
						var select = $(this);
						var value = select.val();
						self.data.currentItem = self.currentItem = 0;
						select.find('option').each(function(i){
							if ($(this).attr('value') == value) self.data.currentItem = self.currentItem = i;
						});
						
						SlotMachineSelectVariant.data.art_id = null;
						SlotMachineSelectVariant.data[SlotMachineSelectVariant.data.pk] = null;
						SlotMachineSelectVariant.verifyData(self);
					});
					return slot;
				},
				appendItemsToSlot: function(){
					var target = $('#' + this.id + '_select');
					var self = this;
					$(this.items).each(function(i){
						this.make(target);
					});
				},
				make: function(target){
					if (target){
						var slotLay = this.makeSlotLayout();
						var target = target.find('table.slotOuterSelectVariantShell');
						target.append(slotLay);
						this.appendItemsToSlot();
						this.selectCurrentItem();
						var self = this;
					}
				},
				selectCurrentItem: function(){
					var self = this;
					$(this.items).each(function(i){
						if (self.currentItem == i){
							$('#' + self.id + '_slotItem_' + i).attr('selected', true);
						}else{
							$('#' + self.id + '_slotItem_' + i).attr('selected', false);
						}
					})
				},
				update: function(slotData){
					this.items = [];
					this.initMode = true;
					this.data = slotData;
					this.currentItem = slotData.currentItem;
					$('#' + this.id + '_select').empty();
					$('#' + this.id + '_titleColumn').find('.slotTitle').text(slotData.title);
					var self = this;
					$(slotData.items).each(function(i){
						if (this.type == 'SlotMachineSlotItem'){
							var slotItem = SlotMachineSlotItemSelectVariant.create(this.title, this.value);
							slotItem.id = self.id + '_slotItem_' + i;
							slotItem.itemCnt = i;
							slotItem.data = this;
							slotItem.slot = self;
							slotItem.width = self.width;
							self.appendItem(slotItem);
						}
					});
					this.appendItemsToSlot();
					this.selectCurrentItem();
				},
				slotDataValidCheck: function(currentItem){
					var outer = $('#' + this.id + '_outer');
					if (currentItem == 0 || currentItem == -1){
						outer.addClass('slotMachineSlotOuter_pass');
						outer.find('.slotLensLeft').addClass('slotLensLeft_pass');
						outer.find('.slotLensRight').addClass('slotLensRight_pass');
						outer.find('.slotLensCenter').addClass('slotLensCenter_pass');
					}else{
						outer.removeClass('slotMachineSlotOuter_pass');
						outer.find('.slotLensLeft').removeClass('slotLensLeft_pass');
						outer.find('.slotLensRight').removeClass('slotLensRight_pass');
						outer.find('.slotLensCenter').removeClass('slotLensCenter_pass');
					}
				}
			}
		);
	/* << */

	/* >> slot machine item select variant (inherit SlotMachineItem) */
		SlotMachineSlotItemSelectVariant = $.extend(
			$.clone(SlotMachineSlotItem),
			{
				create: function(title, value){
					return SlotMachineSlotItem.create.call(this, title, value);
				},
				makeItemLayout: function(){
					var item = $(
						'<option id="' + this.id + '" class="slotMachineItem" value="' + this.title + '">' + this.title + '</div>'
					);
					return item;
				}
			}
		);
	/* << */
	
	/* >> Slot machine select variant initialization */
		// starts the slot machine
		StartSlotmachineSelectVariant = function(){
			ScartPreparer = ShoppingcartPreparer.create();
			AddButtonsPrep = SlotmachineSelectVariantAddButtonsPreparer.create();
			StepBarLinkPrep = StepBarLinkPreparer.create();
			DetailImagePrep = DetailImagePreparer.create();
			ProductDescriptionPrep = ProductDescriptionPreparer.create();
			CpResetButtonPrep = CreativePilotResetButtonPreparer.create();
			SlotMachineSelectVariant.init(
				{
					'target': $('#creativePilotProductConfigurator'),
					'onAfterInit': function(data){
						ScartPreparer.update(data);
						//AddButtonsPrep.update(data);
						StepBarLinkPrep.update(data);
						DetailImagePrep.update(data);
						ProductDescriptionPrep.update(data);
						CpResetButtonPrep.make();
					},
					'onAfterSlotCatch': function(slot){
					},
					'onDataRequest': function(slot, oldData){
					},
					'onDataRequestSuccess': function(slot, data){
						ScartPreparer.update(data);
						AddButtonsPrep.update(data);
						StepBarLinkPrep.update(data);
						ProductDescriptionPrep.update(data);
					}
				}
			);
		}
	/* << */
	
	/* >> Configurator product category list (placed at the left teaser) */
		ConfiguratorProductCategoryList = $.extend(
			$.clone(LLObject),
			{
				create: function(){
					var o = LLObject.create.call(this);
					return o;
				},
				getURLParams: function(specParams){
					var url = window.location.href;
					var params =  Utils.getUrlParamsAsJson(url);
					var reg = /_dId_/;
					var id = null;
					if (reg.test(url)){
						id = url.substring(url.search(reg) + 5, url.search(/_\.htm/));
					}
					if (params.auf_id != null){
						id = params.auf_id;
					}
					if (id){
						params = $.extend(params, {'auf_id': id});
					}
					params = $.extend(params, specParams);
					return params;
				},
				makeItemLayout: function(){
					var lay = $(
						'<div class="categoryListItem">' +
							'<div class="inner">' +
								'<a href="#"><span></span></a>' +
							'</div>' +
						'</div>'
					)
					return lay;
				},
				make: function(){
					var self = this;
					$.ajax({
						type: 'get',
						url: AjaxURLManager.getUrlWithKey('creativepilot_panel', self.getURLParams()),
						success: function(data, msg){
							self.success(data, msg);
						},
						error: function(req, status, error){
							self.error(req, status, error);
						}
					});
				},
				success: function(data, msg){
					//eval('var data = ' + data);
					var target = $('#creativePilotProductsList');
					var url = window.location.href;
					var params = Utils.getUrlParamsAsJson(url);
					var rex = /\?/;
					if (rex.test(url)){
						url = url.substring(0, url.search(rex));
					}
					var self = this;
					var loc = window.location;
					$(data).each(function(i){
						var item = self.makeItemLayout();
						if (this.here) item.addClass('categoryListItem_here');
						if (i % 2 != 0) item.addClass('categoryListItem_odd');
						params = $.extend(params, {'auf_id': this.auf_id, 'freeConfig': 'true'});
						item.find('a').attr({
							'href': [loc.protocol, '//', loc.host, loc.pathname, Utils.getUrlSession(';jsessionid='), Utils.getUrlParamsFromJson(params)].join('')
						});
						item.find('span').text(this.prompt);
						target.append(item);
					});
				},
				error: function(data, status, error){
					var target = $('#creativePilotProductsList');
					target.append(error);
				}
			}
		);
	/* << */
/* << */


/* >> Creative pilot choose pattern */
	/* >> branche navigation */
		CreativePilotBrancheNavigator = $.extend(
			$.clone(LLObject),
			{
				create: function(opts){
					var o = LLObject.create.call(this);
					o.target = opts.target || null;
					o.nodes = null;
					o.fo_id_mapper = window.CREATIVEPILOT_FORMAT_MAPPER
					window.branchePath = [];
					return o;
				},
				makeXml2JsonTreeRequest: function(){
					var self = this;
					var auf_id = Utils.getUrlParamsAsJson(window.location.href).auf_id;
					var url = AjaxURLManager.getUrlWithKey('creativepilotgetparams', {'auf_id': auf_id});
					$.getJSON(url, function(data, textStatus){
						var groupId = window.VC_MEDIA_GROUP_ID = data.format.normal;
						var prdGroup = window.VC_MEDIA_PRODUCT_GROUP_ID = data.prdgrp;
						var url = window.location.protocol + '//' + window.location.host + '/cgi-bin/r31msvc_fremdsystem_aufruf.pl?var_hauptpfad=../creativpilot/r31/vc_media/&var_fa1_select=var_fa1_select||1|&var_aufruf_art=17&var_rueckgabe_encoding=utf8&var_vs58=' + groupId  + '&var_vs57=' + prdGroup;
						$.ajax({
							type: 'get',
							dataType: 'xml',
							url: url,
							success: function(data, msg){
								var data = $(data).children().children('gruppe');
								self.nodes = self.makeXml2JsonTree(data, 0);
								self.makeDomFromJson(self.nodes, self.target, 0, 0);
								self.target.find('.nodeChildrenShell_0').children('.nodeOuter_0').each(function(i){
									if (i % 2 != 0) $(this).addClass('nodeOuterOdd');
								});
								//activate first node with content
								self.activateFirstNodeWithContent();
							},
							error: function(req, status, error){}
						});
					});
				},
				makeXml2JsonTree: function(data){
					var newArr = [];
					for (var i = 0; i < data.length; i++){
						var dat = data.eq(i);
						var level = dat.parents('gruppe').length;
						var id = dat.children('gruppe_id').text();
						var patternCount = dat.children('gruppe_anz_vorlagen').text();
						var title = dat.children('gruppe_name').text();
						var parent = dat.children('gruppe_id_zuordnung').text();
						if (id != ''){
							var newNode = CreativePilotBrancheNavigatorNode.create();
							newNode.title = title;
							newNode.id = id;
							newNode.level = level;
							newNode.pId = parent;
							newNode.patternCount = patternCount;
							newArr.push(newNode);
							var children = dat.children('gruppe');
							if (children.length > 0){
								newNode.children = this.makeXml2JsonTree(children);
							}
						}
					}
					return newArr;
				},
				makeDomFromJson: function(nodes, target, level){
					var outer = this.makeChildrenShellLayout(level);
					var self = this;
					$(nodes).each(function(i){
						this.make(outer);
						if (this.children){
							self.makeDomFromJson(this.children, outer, level + 1);
						}
					});
					target.append(outer);
				},
				makeChildrenShellLayout: function(level){
					var lay = $(
						'<div class="nodeChildrenShell nodeChildrenShell_' + level + '"></div>'
					);
					return lay;
				},
				activateFirstNode: function(){
					var node = this.nodes[0];
					node.handleNodeClick();
				},
				activateFirstNodeWithContent: function(){
					var i, node;
					for (i = 0; i < this.nodes.length; i+=1){
						node = this.nodes[i];
						if (node.patternCount !== '0'){
							node.handleNodeClick();
							return;
						}
					}
				},
				make: function(){
					this.makeXml2JsonTreeRequest();
				}
			}
		);

		CreativePilotBrancheNavigatorNode = $.extend(
			$.clone(LLObject),
			{
				create: function(){
					var o = LLObject.create.call(this);
					o.level = null;
					o.type = 'normal';
					o.title = null;
					o.id = null;
					o.jqDomel = null;
					o.children = null;
					o.pId = null;
					o.patternCount = 0;
					return o;
				},
				makeNodeLayout: function(){
					var lay = $(
						'<div class="nodeOuter nodeOuter_' + this.level + '">' +
							'<div class="inner">' +
							'</div>' +
						'</div>'
					);
					lay.data('pId', this.pId);
					lay.data('id', this.id);
					lay.data('level', this.level);
					var self = this;
					lay.bind('click', function(e){
						e.preventDefault();
						e.stopPropagation();
						var node = $(this);
						self.handleNodeClick(node);
					});
					var patternCount = '&nbsp;(' + this.patternCount + ')';
					var title = this.title.replace(/\//g, ' / ');
					if (this.type == 'here'){
						lay.find('.inner').append(
							'<div class="noLink navItem">' + title + patternCount + '</div>'
						);
					}else{
						lay.find('.inner').append(
							'<a href="#" class="navItem navItem_' +  this.type + '">' + title + patternCount + '</a>'
						);
					}
					return lay;
				},
				handleNodeClick: function(){
					var node = this.jqDomel;
					PatternPreview.buildPagedPreviewList(node.data('id'), window.VC_MEDIA_GROUP_ID, window.VC_MEDIA_PRODUCT_GROUP_ID, node.data('level'));
					$('.navItem').removeClass('navItemHere');
					node.find('.navItem').addClass('navItemHere');
					node.parents('.nodeChildrenShell').prev('.nodeOuter').find('.navItem').addClass('navItemHere');
					if (node.data('level') == 0){
						$('.nodeChildrenShell_0 .nodeChildrenShell').hide();
					}else{
						$('.nodeChildrenShell_0 .nodeChildrenShell_' + (node.data('level') + 1)).hide();
					}
					node.next('.nodeChildrenShell').show();
				},
				make: function(target){
					this.jqDomel = this.makeNodeLayout();
					target.append(this.jqDomel);
				}
			}
		);
	/* << */


	/* >> pattern overview */
		CreativePilotPatternPreview = $.extend(
			$.clone(LLObject),
			{
				create: function(){
					var o = LLObject.create.call(this);
					o.data = null;
					o.currentPage = 1;
					o.offset = 6;
					o.overall = 0;
					o.pages = 0;
					o.data = null;
					return o;
				},
				makePatternLayout: function(){
					var lay = $(
						'<div class="patternPreviewItem">' +
							'<div class="image"><img src="" alt="" title="" height="" width=""/></div>' +
							'<div class="data">' +
								'<table cellpadding="0" cellspacing="0" border="0">' +
									'<tr>' +
										'<td class="title"></td>' +
										'<td class="id"></td>' +
									'</tr>' +
								'</table>' +
							'</div>' +
							'<div class="choose">' +
								'<a href="#">' + $.lang('choosePattern') + '</a>' +
							'</div>' +
						'</div>'
					);
					return lay;
				},
				makePatternPagerLayout: function(){
					var lay = $(
						'<div id="patterPreviewPager">' +
							'<table cellpadding="0" cellspacing="0" border="0" class="outerShell">' +
								'<tr>' +
									'<td class="info"></td>' +
									'<td class="buttons">' +
										'<a href="#" class="next button"></a>' +
										'<a href="#" class="previous button"></a>' +
										'<div class="floatTerm"></div>' +
									'</td>' +
								'</tr>' +
							'</table>' +
						'</div>'
					);
					return lay;
				},
				makeRow: function(){
					return $('<tr></tr>');
				},
				makeColumn: function(){
					return $('<td class="patternCol"></td>');
				},
				appendAndGetRow: function(target){
					var row = this.makeRow();
					target.append(row);
					return row;
				},
				appendAndGetColumn: function(target){
					var c = this.makeColumn();
					target.append(c);
					return c;
				},
				makePatternGrid: function(data){
					var table = $('<table cellpadding="0" cellspacing="0" border="0" class="patternOuter"></table>');
					var self = this;
					var row = null;
					var items = data.children('vorlage');
					this.overall = items.length;
					var pages = Math.floor(this.overall / this.offset);
					this.pages = this.overall % this.offset != 0 ? pages + 1 : pages;
					if (items.length > 0){
						for (var i = 0; i < this.offset; ++i){
							var item = items.eq(i);
							if (i % 3 == 0) row = self.appendAndGetRow(table);
							var id = item.find('vorlage_id').text();
							if (id != ''){
								var text = item.find('vorlage_langbeschreibung').text();
								var realText = text;
								text = text.length > 20 ? text.substring(0, 20) + '...': text;
								var imgTitle = realText + ': ' + item.find('vorlage_klartext').text();
								var prevSrc = item.find('vorlage_preview_absolut').text();
								var imgWidth = item.find('vorlage_preview_breite').text();
								var imgHeight = item.find('vorlage_preview_hoehe').text();
								var patternLay = self.makePatternLayout();
								patternLay.find('img').attr({
									src: prevSrc,
									alt: imgTitle,
									title: imgTitle,
									width: imgWidth || '',
									height: imgHeight || ''
								}).end().find('.title').text(text).end().find('.id').text('#' + id);
								var href = window.location.protocol + '//' + window.location.host + '/xist4c/web/Produkt-gestalten_id_827_.htm';
								var params = Utils.getUrlParamsAsJson(window.location.href);
								params = $.extend(params, {'patId': id, 'id': 3645});
								href = href + Utils.getUrlSession(';jsessionid=') + Utils.getUrlParamsFromJson(params);
								patternLay.find('.choose a').attr({'href': href});
								var col = self.appendAndGetColumn(row);
								col.append(patternLay);
							}
						}
					}
					return table;
				},
				updatePagedPreviewList: function(){
					var table = $('#patternPreviewPane').find('table.patternOuter').empty();
					var items = this.data.children('vorlage');
					var curr = this.currentPage;
					var self = this;
					var row = null;
					for (var i = 0; i < this.offset; ++i){
						var item = items.eq(i + (curr - 1) * this.offset);
						if (i % 3 == 0) row = self.appendAndGetRow(table);
						var id = item.find('vorlage_id').text();
						if (id != ''){
							var text = item.find('vorlage_langbeschreibung').text();
							var realText = text;
							text = text.length > 20 ? text.substring(0, 20) + '...': text;
							var imgTitle = realText + ': ' + item.find('vorlage_klartext').text();
							var prevSrc = item.find('vorlage_preview_absolut').text();
							var imgWidth = item.find('vorlage_preview_breite').text();
							var imgHeight = item.find('vorlage_preview_hoehe').text();
							var patternLay = self.makePatternLayout();
							patternLay.find('img').attr({
								src: prevSrc,
								alt: imgTitle,
								title: imgTitle,
								width: imgWidth || '',
								height: imgHeight || ''
							}).end().find('.title').text(text).end().find('.id').text('#' + id);
							var href = window.location.protocol + '//' + window.location.host + '/xist4c/web/Produkt-gestalten_id_827_.htm';
							var params = Utils.getUrlParamsAsJson(window.location.href);
							params = $.extend(params, {'patId': id, 'id': 3645});
							href = href + Utils.getUrlParamsFromJson(params);
							patternLay.find('.choose a').attr({'href': href});
							var col = self.appendAndGetColumn(row);
							col.append(patternLay);
						}
					}
				},
				handlePager: function(){
					var pager = $('#patterPreviewPager');
					var self = this;
					if (this.currentPage == 1){
						pager.find('.previous').addClass('passive');
					}else{
						pager.find('.previous').removeClass('passive');
					}
					pager.find('.previous').unbind().bind('click', function(e){
						e.preventDefault();
						e.stopPropagation();
						if (self.currentPage > 1){
							self.currentPage--;
							self.updatePagedPreviewList();
							self.handlePager();
						}
					});
					if (this.currentPage == this.pages || this.pages == 0){
						pager.find('.next').addClass('passive');
					}else{
						pager.find('.next').removeClass('passive');
					}
					pager.find('.next').unbind().bind('click', function(e){
						e.preventDefault();
						e.stopPropagation();
						if (self.currentPage < self.pages){
							self.currentPage++;
							self.updatePagedPreviewList();
							self.handlePager();
						}
					});
					if (this.pages > 0){
						var info = ['<strong>'+$.lang('page'),this.currentPage,$.lang('from'),this.pages+'</strong>','-',this.overall,$.lang('previewOverall')].join(' ');
					}else{
						var info = $.lang('pagerInfoNoItems');
					}
					pager.find('.info').html(info);
				},
				buildPagedPreviewList: function(id, grpId, prdGrpId, level){
					var target = $('#patternPreviewPane').empty();
					// url to get pattern xml.
					var url = window.location.protocol + '//' + window.location.host + '/cgi-bin/r31msvc_fremdsystem_aufruf.pl?var_hauptpfad=../creativpilot/r31/vc_media/';
					url += '&var_fa1_select=var_fa1_select||1|&var_aufruf_art=7&var_vs2' + level +'=' + id + '&var_rueckgabe_encoding=utf8&var_vs58=' + grpId + '&var_vs57=' + prdGrpId;
					var self = this;
					$.ajax({
						type: 'get',
						url: url,
						dataType: 'xml',
						success: function(data, msg){
							self.currentPage = 1;
							self.pages = 0;
							self.overall = 0;
							var data = self.data = $(data).children();
							$('#patternPreviewPane').empty();
							target.append(self.makePatternGrid(data));
							target.append(self.makePatternPagerLayout(data));
							self.handlePager();
							self.prepareEmptyPatternButton();
						},
						error: function(req, status, error){
							target.append('<p>Fehler: Kein Daten-XML vorhanden!</p>');
						}
					});
				},
				prepareEmptyPatternButton: function(){
					var params = Utils.getUrlParamsAsJson(window.location.href);
					var auf_id = params.auf_id;
					var url = AjaxURLManager.getUrlWithKey('creativepilotgetparams', {'auf_id': auf_id});
					$.getJSON(url, function(data, textStatus){
						var prdgrp = data.prdgrp;
						if (data.format){
							var grp_id = data.format.normal;
							var landscape_grp_id = null;
							if (data.specialOrientation && data.format.lscape){
								var landscape_grp_id = data.format.lscape;
							}
							var b = $('#emptyDocumentButton');
							b.addClass('emptyDocumentButton_active');
							b.unbind().bind('click', function(e){
								e.preventDefault();
								e.stopPropagation();
								if (landscape_grp_id){
									if(confirm($.lang('withLandscapeMsg'))){
										grp_id = landscape_grp_id;
									}
								}
								var url = [
									window.location.protocol,'//',window.location.host,'/cgi-bin/r31msvc_fremdsystem_aufruf.pl?',
									'var_hauptpfad=../creativpilot/r31/vc_media/&var_fa1_select=var_fa1_select||1|&',
									'var_aufruf_art=7&var_vs20=27&var_rueckgabe_encoding=utf8&var_vs58=',grp_id,'&',
									'var_vs57=',prdgrp
								];
								if (data.subFormat){
									url.push('&var_vs59=', data.subFormat);
								}
								url = url.join('');
								$.ajax({
									type: 'get',
									url: url,
									dataType: 'xml',
									success: function(data, msg){
										var pattern = $(data).children().children(':first-child');
										var id = pattern.find('vorlage_id').text();
										var params = Utils.getUrlParamsAsJson(window.location.href);
										params = $.reduce(params, 'freeConfig');
										params = $.extend(params, {'patId': id, 'id': 3645, 'auf_id': auf_id});
										var href = window.location.protocol + '//' + window.location.host + '/xist4c/web/Produkt-gestalten_id_827_.htm';
										href += Utils.getUrlParamsFromJson(params);
										window.location = href;
									},
									error: function(req, status, error){}
								});
							});
						}
					});
				}
			}
		);
	/* << */
/* << */


/* >> Creative pilot alter pattern */
	CreativePilotLayoutTool = $.extend(
		$.clone(LLObject),
		{
			create: function(){
				var o = LLObject.create.call(this);
				return o;
			},
			getAnonymousUserId: function(){
				var id = new Date().getTime();
				return ['-',id,Math.ceil(id * Math.random(id) / 10000000)].join('');
			},
			getUserInfoAttributes: function(){
				var loginData = (XIST4C_GLOBALS && XIST4C_GLOBALS.login) || null,
						cookieName = 'creative_pilot_anonymus_userId',
						cookie = $.cookie(cookieName),
						attrs = null;
				if (loginData && typeof loginData.userID !== 'undefined'){
					if (cookie){
						attrs = $.extend(attrs, {'var_vs5_uebergabe': cookie});
						attrs = $.extend(attrs, {'var_vs5_neu': loginData.userID});
						$.cookie(cookieName, null);
						alert($.lang('creativePilotMergedUserDocuments'));
					}else{
						attrs = $.extend(attrs, {'var_vs5_uebergabe': loginData.userID});
					}
				}else{
					$.cookie(cookieName, this.getAnonymousUserId(), {path: '/', expires: 3});
					attrs = $.extend(attrs, {'var_vs5_uebergabe': this.getAnonymousUserId()});
				}
				return attrs;
			},
			makeUrlAndPostData: function(){
				var params = Utils.getUrlParamsAsJson(window.location.href),
						responseUrl = encodeURIComponent(window.location.protocol + '//' + window.location.host + '/xist4c/web/Fertig_id_3646_.htm' + Utils.getUrlSession(';jsessionid=')),
						postData, url, crmkd110 = 'J';
				if (typeof params.JOBNUMMER === 'undefined'){
					postData = {
						'var_hauptpfad': '../creativpilot/r31/vc_media/',
						'var_fa1_select': 'var_fa1_select||1|',
						'var_aufruf_art': '1',
						'var_html_folgemaske': 'r31msvcmedia_daten_anzeigen_vorlagen_api.html',
						'var_vs3': '1',
						'var_vs4': params.patId,
						'var_rueckgabe_parameter_select': ['var_rueckgabe_parameter_select||auf_id,',params.auf_id,',patId,',params.patId,'|'].join(''),
						'var_rueckgabe_aufruf_select': ['var_rueckgabe_aufruf_select||',responseUrl].join('')
					};
				}else{
					if (typeof params.assigned !== 'undefined' && params.assigned === 'true'){
						crmkd110 = 'N';
					}
					postData = {
						'var_hauptpfad': '../creativpilot/r31/vc_media/',
						'var_fa1_select': 'var_fa1_select||1|',
						'var_aufruf_art': '2',
						'var_crmkd110_uebergabe': crmkd110,
						'var_vb4_uebergabe': params.JOBNUMMER,
						'var_html_folgemaske': 'r31msvcmedia_daten_anzeigen_job_api.html',
						'var_vs3': '1',
						'var_rueckgabe_parameter_select': ['var_rueckgabe_parameter_select||auf_id,',params.auf_id,',patId,',params.patId,'|'].join(''),
						'var_rueckgabe_aufruf_select': ['var_rueckgabe_aufruf_select||',responseUrl].join('')
					};
				}
				url = [ window.location.protocol, '//', window.location.host, '/cgi-bin/r31msvc_fremdsystem_aufruf.pl'].join('');
				return {'url': url, 'data': postData};
			},
			make: function(){
				var self = this;
				var iframe = $('#vcMediaFlashTool').find('iframe');
				var postData = this.makeUrlAndPostData();
				$.post(postData.url, postData.data, function(data){
					data = data.replace(/http:/g, window.location.protocol);
					data = data.replace(/flyerpilot\.xist4c\.de/, 'www.flyerpilot.de');
					iframe.attr({'src': data});
				});
			},
			saveDocument: function(jobId){
				/* LOGGING >> */
				if (window.console) console.log('save');
				/* << LOGGING */
			},
			openDocument: function(){
				/* LOGGING >> */
				if (window.console) console.log('open');
				/* << LOGGING */
			}
		}
	);
/* << */


/* >> Creative pilot finish product info (inherits TopProductQuickChoice)*/
	CreativePilotProductInfo = $.extend(
		$.clone(TopProductQuickChoice),
		{
			create: function(){
				var o = TopProductQuickChoice.create.call(this);
				o.data = null;
				return o;
			},
			makeTableWithTitle: function(){
				var t = this.target;
				var title = this.opts.title || null;
				var subtitle = this.opts.data.subTitle || null;
				this.subtitle = subtitle;
				var table = $(
					'<table cellspacing="0" cellpadding="0" border="0">' +
					'</table>'
				);
				if (title){
					var titleElm = $(
						'<tr>' +
							'<th>' + title + '</th>' +
							'<th></th>' +
						'</tr>'
					);
					if (subtitle){
						titleElm.find('th:nth-child(2)').addClass('withSub');
					}
					table.append(titleElm);
				}
				if (subtitle){
					table.append(
						'<tr>' +
							'<th class="subtitle">' + subtitle + '</th>' +
							'<th></th>' +
						'</tr>'
					);
				}
				t.empty().append(table);
			},
			makeRowsWithBindings: function(){},
			update: function(slot, data){},
			patternPreviewAndDownloadBinding: function(){
				var params = Utils.getUrlParamsAsJson(window.location.href);
				var url = [
					window.location.protocol,'//',window.location.host,'/cgi-bin/r31msvc_fremdsystem_aufruf.pl?',
					'var_hauptpfad=../creativpilot/r31/vc_media/&var_fa1_select=var_fa1_select||1|&var_aufruf_art=8&',
					'var_vb4_uebergabe=',params.JOBNUMMER,'&var_crmkd110_uebergabe=J'
				].join('');
				var self = this;
				$.ajax({
					type: 'get',
					url: url,
					dataType: 'text',
					success: function(data, msg){
						var d = self.data = $(data), prevPaths = [], path;
						d.find('preview').each(function(i){
							var img = null;
							path = $(this).text();
							prevPaths.push(path);
							if (path !== ''){
								var img = $('<img/>').attr({'src': path});
							}
							$('#creativePilotProductPatternImage').append(img);
						});
						self.patternPDFBinding();
						self.prepareBufferDocument(params, prevPaths);
					},
					error: function(req, status, error){
					}
				});
			},
			patternPDFBinding: function(){
				if (this.data){
					var links = $('a.pdfDownloadLink');
					links.show();
					var href = this.data.find('lq_path').text();
					if (href != ''){
						links.attr({'href': href});
					}
				}else{
					$('a.pdfDownloadLink').hide();
				}
			},
			prepareUrlWithSession: function(url){
				var sid = Utils.getUrlSession();
				if (sid !== ''){
					sid = 'xist4c_eagw_sid=' + sid + '&';
					url = url.split('?');
					return [url[0], '?', sid, url[1]].join('');
				}
				return url;
			},
			prepareBufferDocument: function(params, prevPaths){ // zwischenspeichern
				var login = XIST4C_GLOBALS.login, button = $('#creativePilotBufferButton'), 
						userId, userName, jobId, aufId, patId, url, self = this;
				if (login){
					button.addClass('creativePilotBufferButton_active');
					button.bind('click', function(e){
						params.user_id = login.userID;
						params.userName = login.userName;
						params.prevPath = prevPaths;
						url = AjaxURLManager.getUrlWithKey('creativepilotbuffer');
						delete params[''];
						$.ajax({
							type: 'post',
							url: url,
							data: {'content': encodeURIComponent($.toJson(params))},
							success: function(data, msg){
								data = self.prepareUrlWithSession(data);
								window.location.href = data;
							},
							error: function(req, status, error){
								alert($.lang('creativePilotBufferError'));
							}
						});
					});
				}
			}
		}
	);
/* << */


/* >> Slot machine select variant add ons there are triggered on configurator events*/
	/* >> Add Buttons preparer */
		SlotmachineSelectVariantAddButtonsPreparer = $.extend(
			$.clone(LLObject),
			{
				create: function(){
					var o = LLObject.create.call(this);
					return o;
				},
				update: function(data){
					var auf_id = data.auf_id;
					var buttons = $('#creativePilotNextSteps').find('.button');
					buttons.removeClass('buttonActive');
					buttons.bind('click', function(e){
						e.preventDefault();
						e.stopPropagation();
					});
					if (data.auf_id){
						var buttons = $('#creativePilotNextSteps').find('.button');
						var emptyPatternGroupId = 27;
						var url = AjaxURLManager.getUrlWithKey('creativepilotgetparams', {'auf_id': auf_id});
						var smData = data;
						$.getJSON(url, function(data, textStatus){
							var prdgrp = data.prdgrp;
							if (data.format){
								var grp_id = data.format.normal;
								var landscape_grp_id = null;
								if (data.specialOrientation && data.format.lscape){
									var landscape_grp_id = data.format.lscape;
								}
								buttons.each(function(i){
									if (i == 0){ // with pattern button
										var b = $(this);
										var link = b.attr('href');
										var attrs = Utils.getUrlParamsAsJson(link);
										if (attrs){
											attrs.auf_id = smData.auf_id;
										}else{
											var attrs = {'auf_id': smData.auf_id};
										}
										var rex = /\?/;
										if (rex.test(link)){
											link = link.substring(0, link.search(rex));
										}
										b.attr('href', link + Utils.getUrlParamsFromJson(attrs));
										b.unbind();
										buttons.eq(i).addClass('buttonActive');
									}else if (i == 1){ // empty document button
										var b = buttons.eq(i);
										b.addClass('buttonActive');
										b.unbind().bind('click', function(e){
											e.preventDefault();
											e.stopPropagation();
											if (landscape_grp_id){
												if(confirm($.lang('withLandscapeMsg'))){
													grp_id = landscape_grp_id;
												}
											}
											var url = [
											window.location.protocol,'//',window.location.host,'/cgi-bin/r31msvc_fremdsystem_aufruf.pl?',
												'var_hauptpfad=../creativpilot/r31/vc_media/&var_fa1_select=var_fa1_select||1|&',
												'var_aufruf_art=7&var_vs20=27&var_rueckgabe_encoding=utf8&var_vs58=',grp_id,'&',
												'var_vs57=',prdgrp
											];
											if (data.subFormat){
												url.push('&var_vs59=', data.subFormat);
											}
											url = url.join('');
											$.ajax({
												type: 'get',
												url: url,
												dataType: 'xml',
												success: function(data, msg){
													var pattern = $(data).children().children(':first-child');
													var id = pattern.find('vorlage_id').text();
													var params = Utils.getUrlParamsAsJson(window.location.href);
													params = $.reduce(params, 'freeConfig');
													params = $.extend(params, {'patId': id, 'id': 3645, 'auf_id': auf_id});
													var href = window.location.protocol + '//' + window.location.host + '/xist4c/web/Produkt-gestalten_id_827_.htm';
													href += Utils.getUrlParamsFromJson(params);
													window.location = href;
												},
												error: function(req, status, error){}
											});
										});
									}
								});
							}
						});
					}
				}
			}
		);
	/* << */
	
	/* >> Step bar links preparer */
		StepBarLinkPreparer = $.extend(
			$.clone(LLObject),
			{
				create: function(){
					var o = LLObject.create.call(this);
					o.coIds = [
						null,
						3642, // configurator
						3644, // choose pattern
						3645, // alter pattern
						3646 // finish
					];
					o.params = Utils.getUrlParamsAsJson(window.location.href);
					o.barItems = $('#creativePilotTopStateNav').children().children('li');
					return o;
				},
				update: function(data){
					this.params = $.reduce(this.params, 'JOBNUMMER');
					if (data && data.auf_id != null){
						this.params = $.extend(this.params, {'auf_id': data.auf_id});
						this.params = $.reduce(this.params, 'freeConfig');
					}
					for (var i = 1; i < this.barItems.length - 1; ++i){
						var item = this.barItems.eq(i);
						if (item.hasClass('stateNavItemActive')){
							var ref = item.find('a');
							var page = ref.attr('href');
							var lastPos = page.search(/\?/) != -1 ? page.search(/\?/) : page.length;
							page = page.substring(page.lastIndexOf('/') + 1, lastPos);
							var href = [page,Utils.getUrlParamsFromJson($.extend(this.params, {'id':this.coIds[i]}))].join('');
							ref.attr({'href': href});
						}
					}
				}
			}
		);
	/* << */
	
	/* >> detail image*/
		DetailImagePreparer = $.extend(
			$.clone(LLObject),
			{
				create: function(){
					var o = LLObject.create.call(this);
					return o;
				},
				update: function(data){
					var img = null;
					if (data.creativePilotImage){
						$('#creativePilotProductImage').append($('<img/>').attr(data.creativePilotImage));
					}
				}
			}
		);
	/* << */
	
	/* >> product description */
		ProductDescriptionPreparer = $.extend(
			$.clone(LLObject),
			{
				create: function(){
					var o = LLObject.create.call(this);
					return o;
				},
				update: function(data){
					if (data.infoText){
						$('#creativePilotProductPrdInfo').find('.pmt').text($.lang('productInfoPrompt'))
							.end().find('.text').text(data.infoText);
					}else{
						$('#creativePilotProductPrdInfo').find('span').empty();
					}
					if (data.productTitle) $('#creativePilotProductInfoHeadline').text(data.productTitle);
					if (data.description) $('#creativePilotProductInfoText').text(data.description);
				}
			}
		);
	/* << */

	/* >> reset button preparer (inherits ResetButtonPreparer)*/
		CreativePilotResetButtonPreparer = $.extend(
			$.clone(ResetButtonPreparer),
			{
				create: function(){
					return ResetButtonPreparer.create.call(this);
				},
				make: function(){
					var b = this.makeButton();
					$(function(){
						$('#creativePilotResetButton').append(b);
					});
				}
			}
		);
	/* << */
/* << */


/* >> Step filtered configurator */
	/* >>  Step filtered configurator */
		StepFilteredConfigurator = $.extend(
			$.clone(LLObject),
			{
				toJsonAttrs: ['data'],
				opts: null,
				data: null,
				steps: [],
				onDataRequestSuccess: null,
				onAfterInit: null,
				urlParams: null,
				init: function(opts){
					var urlParams = this.urlParams = this.getURLParams();
					var url = AjaxURLManager.getUrlWithKey(opts.cpKey, urlParams);
					this.opts = opts;
					if (opts.onAfterInit && typeof opts.onAfterInit == 'function'){
						this.onAfterInit = opts.onAfterInit;
					}
					if (opts.onDataRequestSuccess && typeof opts.onDataRequestSuccess == 'function'){
						this.onDataRequestSuccess = opts.onDataRequestSuccess;
					}
					var self = this;
					$.getJSON(url, function(data, textStatus){
						var d = self.data = data;
						if (d.type == 'StepFilteredConfiguratorData'){
							var target = self.opts.target;
							target.append(self.makeBaseTable());
							$(d.steps).each(function(i){
								var step = window[this.type].create();
								step.id = 'step_' + i;
								step.itemId = i;
								step.title = this.title || null;
								step.data = this;
								if (i == 0) step.first = true;
								if (i == d.steps.length - 1) step.last = true;
								$(this.items).each(function(j){
									var item = window[this.type].create();
									if (j % 2 == 0) item.odd = true;
									item.id = j;
									item.parent = step;
									item.title = this.title;
									if (this.here) item.here = true;
									if (this.img) item.image = this.img;
									item.data = this;
									step.appendItem(item);
								});
								self.appendStep(step);
							});
						}
						var cb = self.onAfterInit;
						if (cb && typeof cb == 'function'){
							cb.call(self, data);
						}
						target.append(self.makeShoppingcartButton());
					});
				},
				getURLParams: function(specParams){
					var url = window.location.href;
					var params =  Utils.getUrlParamsAsJson(url);
					var reg = /_dId_/;
					var id = null;
					if (reg.test(url)){
						id = url.substring(url.search(reg) + 5, url.search(/_\.htm/));
					}
					if (params && typeof params.auf_id != 'undefined' && params.auf_id != null){
						id = params.auf_id;
					}
					if (id){
						params = $.extend(params, {'auf_id': id});
					}else{
						var cfd = window.CONFIGURATOR_FALLBACK_DATA;
						if (cfd && cfd.auf_id){
							params = $.extend(params, {'auf_id': cfd.auf_id});
						}
					}
					params = $.extend(params, specParams);
					return params;
				},
				appendStep: function(step){
					this.steps.push(step);
					step.make();
				},
				makeBaseTable: function(){
					return $('<table cellpadding="0" cellspacing="0" border="0" class="stepOuter"></table>');
				},
				makeShoppingcartButton: function(){
					var b = $(
						'<div class="shoppingcartButtonOuter"><div class="button xxlShoppingcartButton"></div></div>'
					);
					b.find('.xxlShoppingcartButton').css({'display': 'none'}).bind('click', function(e){
						var sc = $('.prdConfTopWkShell').find('form').submit();
					});
					return b;
				},
				stepUpdateCheck: function(){
					var d = this.data;
					var self = this;
					$(d.steps).each(function(i){
						if (self.steps.length -1 < i){
							var step = window[this.type].create();
							step.id = 'step_' + i;
							step.itemId = i;
							step.title = this.title || null;
							step.data = this;
							if (i == 0) step.first = true;
							if (i == d.steps.length - 1) step.last = true;
							$(this.items).each(function(j){
								var item = window[this.type].create();
								if (j % 2 == 0) item.odd = true;
								item.id = j;
								item.parent = step;
								item.title = this.title;
								if (this.here) item.here = true;
								if (this.img) item.image = this.img;
								item.data = this;
								step.appendItem(item);
							});
							self.appendStep(step);
						}else{
							if (this.update){
								self.steps[i].update(d.steps[i]);
							}
						}
					});
				},
				verifyData: function(step, item){
					var item = item || null;
					var url = AjaxURLManager.getUrlWithKey(this.opts.cpKey);
					/* LOGGING >> */
					//if (window.console) console.log($.toJson(StepFilteredConfigurator));
					/* << LOGGING */
					var self = this;
					$.ajax({
						type: 'post',
						url: url,
						data: {'content': encodeURIComponent($.toJson(StepFilteredConfigurator))},
						success: function(data, msg){self.verifyDataRequestSuccess(data, msg, step, item);},
						error: function(req, status, error){self.verifyDataRequestError(req, status, error);}
					});
				},
				verifyDataRequestSuccess: function(data, msg, step, item){
					//eval('var data = ' + data + ';');
					this.data = data;
					if (this.urlParams && this.urlParams.auf_id) this.urlParams.auf_id = data.auf_id;
					this.stepUpdateCheck();
					if (this.opts.deleteUnnecessarySteps){
						var viewSteps = $('td[id^=step_]').size();
						for (var i = 0; i < viewSteps; i++){
							if (i > this.data.steps.length - 1){
								$('#step_' + i + '_items').empty();
							}
						}
					}
					var cb = this.onDataRequestSuccess;
					if (cb && typeof cb == 'function'){
						cb.call(this, data, step, item);
					}
				},
				verifyDataRequestError: function(req, status, error){
					/* todo: .... */
				}
			}
		);
	/* << */


	/* >>  Step filtered configurator column */
		StepFilteredConfiguratorColumn = $.extend(
			$.clone(LLObject),
			{
				create: function(){
					var o = LLObject.create.call(this);
					o.id = null;
					o.itemId = null;
					o.title = null;
					o.data = null;
					o.items = [];
					o.last = false;
					o.first = false;
					return o;
				},
				appendItem: function(item){
					if (item && item.instanceOf(StepFilteredConfiguratorColumnItem)){
						this.items.push(item);
					}
				},
				makeTitle: function(){
					return $('<div class="columnTitle"><span>' + this.title + '</span></div>');
				},
				makeLayout: function(){
					var lay = $('<td id="' + this.id + '_items" class="items"></td>');
					lay.width(this.data.width);
					if (this.first) lay.addClass('first');
					if (this.last) lay.addClass('last');
					return lay;
				},
				makeSpacerLayout: function(){
					var lay = $('<td class="spc">&nbsp;</td>');
					return lay;
				},
				makeStepItems: function(){
					var target = $('#' + this.id + '_items');
					$(this.items).each(function(i){
						this.make(target);
					});
				},
				make: function(){
					var target = StepFilteredConfigurator.opts.target.children('table');
					if (this.itemId == 0){
						target.append('<tr></tr>');
					}
					target = target.find('tr');
					var col = this.makeLayout();
					target.append(col);
					if (this.title) col.append(this.makeTitle());
					if (!this.last) target.append(this.makeSpacerLayout());
					this.makeStepItems();
				},
				update: function(colData){
					var target = $('#' + this.id + '_items');
					target.find('div[id^=' + this.id +'_item_]').remove();
					this.items = [];
					var self = this;
					$(colData.items).each(function(j){
						var item = window[this.type].create();
						if (j % 2 == 0) item.odd = true;
						item.id = j;
						item.parent = self;
						item.title = this.title;
						if (this.here) item.here = true;
						if (this.img) item.image = this.img;
						item.data = this;
						self.appendItem(item);
					});
					this.makeStepItems();
				}
			}
		);
	/* << */


	/* >>  Step filtered configurator column item */
		StepFilteredConfiguratorColumnItem = $.extend(
			$.clone(LLObject),
			{
				create: function(){
					var o = LLObject.create.call(this);
					o.id = null;
					o.parent = null;
					o.title = null;
					o.image = null;
					o.here = false;
					o.data = null;
					o.odd = false;
					return o;
				},
				makeItem: function(){
					var item = $(
						'<div id="' + this.parent.id + '_item_' + this.id + '" class="item viewport">' +
							'<div class="title">' + this.title + '</div>' +
						'</div>'
					)
					if (this.data.meta && this.data.meta.price){
						item.append('<div class="price">' + this.data.meta.price + '</div>');
					}
					if (this.here){
						item.addClass('itemHere');
						if (!this.parent.last){
							item.append('<div class="redArrow"></div>');
						}
					}else{
						var self = this;
						item.bind('click', function(e){
							var step = self.parent;
							var stepId = self.parent.itemId;
							StepFilteredConfigurator.data.changedStep = stepId;
							StepFilteredConfigurator.data.steps[stepId].currentItem = self.id;
							StepFilteredConfigurator.verifyData(step, item);
						});
						item.css({'cursor': 'pointer'});
					}
					if (this.odd && !this.here) item.addClass('odd');
					if (this.image){
						var img = $(
							'<div class="image">' +
								'<img src="' + this.image.src + '" height="' + this.image.height + '" width="' + this.image.width + '" alt=""/>' +
							'</div>'
						);
						item.append(img);
					}
					return item;
				},
				justifyHereArrow: function(item){
					if (item.hasClass('itemHere')){
						var h = item.outerHeight();
						var arrow = item.find('.redArrow');
						arrow.css({'top': h / 2 - 16});
					}
				},
				make: function(target){
					var item = this.makeItem();
					target.append(item);
					this.justifyHereArrow(item);
					StepFilteredConfigurator.data.steps[this.parent.itemId].items[this.id].here = false;
				}
			}
		);
	/* << */


	/* >>  Step filtered configurator row */
		StepFilteredConfiguratorRow = $.extend(
			$.clone(StepFilteredConfiguratorColumn),
			{
				create: function(){
					var o = StepFilteredConfiguratorColumn.create.call(this);
					return o;
				},
				makeLayout: function(){
					var lay = $('<tr><td id="' + this.id + '_items" class="items"></td></tr>');
					lay.children('td').height(this.data.height);
					if (this.first) lay.addClass('first');
					if (this.last) lay.addClass('last');
					return lay;
				},
				makeSpacerLayout: function(){
					var lay = $('<tr><td class="spc"></td></tr>');
					return lay;
				},
				make: function(){
					var target = StepFilteredConfigurator.opts.target.children('table');
					var lay = this.makeLayout();
					target.append(lay);
					if (this.title) lay.find('td').append(this.makeTitle());
					if (!this.last) target.append(this.makeSpacerLayout());
					this.makeStepItems();
				},
				update: function(colData){
					var target = $('#' + this.id + '_items');
					target.find('.itemsOuter').remove();
					this.items = [];
					var self = this;
					$(colData.items).each(function(j){
						var item = window[this.type].create();
						if (j % 2 == 0) item.odd = true;
						item.id = j;
						item.parent = self;
						item.title = this.title;
						if (this.here) item.here = true;
						if (this.img) item.image = this.img;
						item.data = this;
						self.appendItem(item);
					});
					this.makeStepItems();
				}
			}
		);
	/* << */


	/* >>  Step filtered configurator row item */
		StepFilteredConfiguratorRowItem = $.extend(
			$.clone(StepFilteredConfiguratorColumnItem),
			{
				create: function(){
					var o = StepFilteredConfiguratorColumnItem.create.call(this);
					o.free = false;
					return o;
				},
				makeItem: function(){
					var item = $(
						'<div id="' + this.parent.id + '_item_' + this.id + '" class="item viewport">' +
							'<div class="title">' + this.title + '</div>' +
						'</div>'
					)
					if (this.data.meta && this.data.meta.price){
						item.append('<div class="price">' + this.data.meta.price + '</div>');
					}
					if (this.here){
						item.addClass('itemHere');
						if (!this.parent.last){
							item.append('<div class="redArrow"></div>');
						}
					}else{
						var self = this;
						item.bind('click', function(e){
							var step = self.parent;
							var stepId = self.parent.itemId;
							StepFilteredConfigurator.data.changedStep = stepId;
							StepFilteredConfigurator.data.steps[stepId].currentItem = self.id;
							StepFilteredConfigurator.verifyData(step, self);
						});
						item.css({'cursor': 'pointer'});
					}
					if (this.odd && !this.here) item.addClass('odd');
					if (this.image){
						var img = $(
							'<div class="image">' +
								'<img src="' + this.image.src + '" height="' + this.image.height + '" width="' + this.image.width + '" alt=""/>' +
							'</div>'
						);
						item.append(img);
					}
					return item;
				}
			}
		);
	/* << */


	/* >>  Step filtered configurator row variant 1 */
		StepFilteredConfiguratorRowVariant1 = $.extend(
			$.clone(StepFilteredConfiguratorRow),
			{
				create: function(){
					var o = StepFilteredConfiguratorRow.create.call(this);
					return o;
				},
				makeLayout: function(){
					var lay = $('<tr><td id="' + this.id + '_items" class="items"></td></tr>');
					lay.children('td').height(this.data.height);
					if (this.first) lay.addClass('first');
					if (this.last) lay.addClass('last');
					return lay;
				},
				makeSpacerLayout: function(){
					var lay = $('<tr><td class="spc"></td></tr>');
					return lay;
				},
				makeStepItems: function(){
					var target = $('#' + this.id + '_items');
					var row = $('<tr></tr>');
					if (target.find('table.itemsOuter').size() == 0){
						target.append('<table class="itemsOuter" cellpadding="0" cellspacing="0" border="0"></table>');
					}
					target = target.find('table.itemsOuter');
					var colCnt = this.data.colCount;
					var self = this;
					$(this.items).each(function(i){
						if (i % colCnt == 0){
							realTarget = row.clone();
							target.append(realTarget);
						}
						this.make(realTarget);
					});
				},
				make: function(){
					var target = StepFilteredConfigurator.opts.target.children('table');
					var lay = this.makeLayout();
					target.append(lay);
					if (this.title) lay.find('td').append(this.makeTitle());
					if (!this.last) target.append(this.makeSpacerLayout());
					this.makeStepItems();
				},
				update: function(colData){
					var target = $('#' + this.id + '_items');
					target.find('.itemsOuter, .shoppingcartButtonOuter').remove();
					this.items = [];
					var self = this;
					$(colData.items).each(function(j){
						var item = window[this.type].create();
						if (j % 2 == 0) item.odd = true;
						item.id = j;
						item.parent = self;
						item.title = this.title;
						if (this.here) item.here = true;
						if (this.img) item.image = this.img;
						item.data = this;
						self.appendItem(item);
					});
					this.makeStepItems();
				}
			}
		);
	/* << */


	/* >>  Step filtered configurator row item variant1*/
		StepFilteredConfiguratorRowItemVariant1 = $.extend(
			$.clone(StepFilteredConfiguratorRowItem),
			{
				create: function(){
					return StepFilteredConfiguratorRowItem.create.call(this);
				},
				makeItem: function(){
					var image = '';
					if (this.image){
						var i = this.image;
						image = '<img src="' + i.src + '" height="' + i.height + '" width="' + i.width + '" alt="" />';
					}
					var item = $(
						'<td class="itemOuter">' +
							'<table id="' + this.parent.id + '_item_' + this.id + '" class="item" cellpadding="0" cellspacing="0" border="0">' +
								'<tr>' +
									'<td class="image">' +
										image +
									'</td>' +
									'<td class="info">' +
										'<div class="title">' + this.title + '</div>' +
										'<div class="text">' + this.data.text + '</div>' +
										'<div class="formElmOuter roundedBox">' +
											'<table cellpadding="0" cellspacing="0" border="0" class="formElmOuter">' +
												'<tr>' +
													'<td class="formElm"></td>' +
													'<td class="formElmTitle">' + this.title + ' ' + $.lang('choose') + '</td>' +
											'</table>' +
										'</div>' +
									'</td>' +
								'</tr>' +
							'</table>' +
						'</td>'
					);
					if (this.data.lowestPrice){
						item.find('.info').prepend('<div class="lowestPrice">' + this.data.lowestPrice + '</div>');
					}
					var colWidth = 100 / this.parent.data.colCount;
					item.css({'width': colWidth + '%'});
					var f = $(
						'<input type="radio" name="' + this.parent.id + '_item" value="' + this.data.value + '"/>'
					);
					if (this.here) f.attr('checked', true);
					var self = this;
					f.bind('click', function(e){
						var step = self.parent;
						var stepId = self.parent.itemId;
						StepFilteredConfigurator.data.free = self.free;
						StepFilteredConfigurator.data.changedStep = stepId;
						StepFilteredConfigurator.data.steps[stepId].currentItem = self.id;
						StepFilteredConfigurator.verifyData(step, self);
					});
					item.find('.formElm').append(f);
					return item;
				}
			}
		);
	/* << */


	/* >>  Step filtered configurator row item variant1_2*/
		StepFilteredConfiguratorRowItemVariant1_2 = $.extend(
			$.clone(StepFilteredConfiguratorRowItemVariant1),
			{
				create: function(){
					return StepFilteredConfiguratorRowItemVariant1.create.call(this);
				},
				makeItem: function(){
					var item = $(
						'<td class="itemOuter">' +
							'<div class="formElmOuter formElmOuterVar2 roundedBox">' +
								'<table cellpadding="0" cellspacing="0" border="0" class="formElmOuter">' +
									'<tr>' +
										'<td class="formElm"></td>' +
										'<td class="formElmTitle">' + this.title + '</td>' +
										'<td class="addPrice">' + this.data.price + '</td>' +
								'</table>' +
							'</div>' +
							'<div class="text textVar2">' + this.data.text + '</div>' +
						'</td>'
					);
					var colWidth = 100 / this.parent.data.colCount;
					item.css({'width': colWidth + '%'});
					var formType = this.data.formType || 'checkbox';
					if (formType == 'checkbox'){
						var name = this.parent.id + '_item_' + this.id;
					}else{
						var name = this.parent.id + '_item_' + this.data.formGroupId;
					}
					var f = $(
						'<input type="' + formType + '" name="' + name + '" value="' + this.data.value + '"/>'
					);
					if (this.here) f.attr('checked', true);
					var self = this;
					f.bind('click', function(e){
						var step = self.parent;
						var stepId = self.parent.itemId;
						if (self.data.formType == 'radio'){
							var value = $(this).val();
							var formGrp = self.data.formGroupId;
							$(StepFilteredConfigurator.data.steps[stepId].items).each(function(i){
								if (this.formGroupId == formGrp && value != this.value){
									this.here = false;
									$(this).attr('checked', false);
								}
							});
						}
						StepFilteredConfigurator.data.free = self.free;
						StepFilteredConfigurator.data.changedStep = stepId;
						StepFilteredConfigurator.data.steps[stepId].items[self.id].here = $(this).attr('checked');
						StepFilteredConfigurator.data.steps[stepId].currentItem = self.id;
						StepFilteredConfigurator.verifyData(step, self);
					});
					item.find('.formElm').append(f);
					return item;
				},
				make: function(target){
					var item = this.makeItem();
					target.append(item);
					//this.justifyHereArrow(item);
					//StepFilteredConfigurator.data.steps[this.parent.itemId].items[this.id].here = false;
				}
			}
		);
	/* << */


	/* >>  Step filtered configurator row item variant1_3*/
		StepFilteredConfiguratorRowItemVariant1_3 = $.extend(
			$.clone(StepFilteredConfiguratorRowItemVariant1),
			{
				create: function(){
					return StepFilteredConfiguratorRowItemVariant1.create.call(this);
				},
				makeItem: function(){
					var image = '';
					if (this.image){
						var i = this.image;
						image = '<img src="' + i.src + '" height="' + i.height + '" width="' + i.width + '" alt="" />';
					}
					var item = $(
						'<td class="itemOuter">' +
							'<div class="image imageVar3">' + image + '</div>' +
							'<div class="formElmOuter formElmOuterVar3 roundedBox">' +
								'<table cellpadding="0" cellspacing="0" border="0" class="formElmOuter">' +
									'<tr>' +
										'<td class="formElm"></td>' +
										'<td class="formElmTitle">' + this.title + '</td>' +
										'<td class="addPrice">' + this.data.price + '</td>' +
								'</table>' +
							'</div>' +
						'</td>'
					);
					var colWidth = 100 / this.parent.data.colCount;
					item.css({'width': colWidth + '%'});
					var formType = this.data.formType || 'checkbox';
					if (formType == 'checkbox'){
						var name = this.parent.id + '_item_' + this.id;
					}else{
						var name = this.parent.id + '_item';
					}
					var f = $(
						'<input type="' + formType + '" name="' + name + '" value="' + this.data.value + '"/>'
					);
					if (this.here) f.attr('checked', true);
					var self = this;
					f.bind('click', function(e){
						var step = self.parent;
						var stepId = self.parent.itemId;
						StepFilteredConfigurator.data.free = self.free;
						StepFilteredConfigurator.data.changedStep = stepId;
						StepFilteredConfigurator.data.steps[stepId].currentItem = self.id;
						StepFilteredConfigurator.verifyData(step, self);
					});
					item.find('.formElm').append(f);
					return item;
				}
			}
		);
	/* << */


	/* >>  Step filtered configurator row item format*/
		StepFilteredConfiguratorRowItemFormat = $.extend(
			$.clone(StepFilteredConfiguratorRowItemVariant1),
			{
				create: function(){
					return StepFilteredConfiguratorRowItemVariant1.create.call(this);
				},
				makeItem: function(){
					var item = $(
						'<td class="itemOuter">' +
						'</td>'
					);
					var colWidth = 100 / this.parent.data.colCount;
					item.css({'width': colWidth + '%'});
					var tableItems = this.data.items;
					var id = this.parent.id + '_' + this.id;
					if (tableItems.length > 1){
						var tabAera = $(
							'<div id="' + id + '_tabbar">' +
								'<ul></ul>' +
							'</div>'
						);
						var li = $('<li><a></a></li>');
						item.append(tabAera);
						$(tableItems).each(function(i){
							var title = this.title;
							var tabId = id + '_' + i;
							var tab = li.clone();
							tab.find('a').attr({'href': '#' + tabId}).text(title);
							tabAera.find('ul').append(tab);
							tabAera.append('<div id="' + tabId + '"></div>');
						});
					}
					item.append('<div id="' + id + '_0"></div>');
					return item;
				},
				make: function(target){
					var item = this.makeItem();
					target.append(item);
					var tableItems = this.data.items;
					var id = this.parent.id + '_' + this.id;
					var self = this;
					if (tableItems.length > 1){
						$(tableItems).each(function(i){
							var contId = id + '_' + i;
							var renderer = JSONRenderer.create(this.table, $('#' + contId));
							renderer.renderFormularRadioTable(i, StepFilteredConfigurator, id, self);
						});
						var stepId = self.parent.itemId;
						var tabIdx = StepFilteredConfigurator.data.steps[stepId].items[this.id].tableIndex
						$('#' + id + '_tabbar').tabs({'selected': tabIdx});
					}else{
						var contId = id + '_0';
						var renderer = JSONRenderer.create(tableItems[0].table, $('#' + contId));
						renderer.renderFormularRadioTable(0, StepFilteredConfigurator, id, self);
					}
					if (StepFilteredConfigurator.data.steps.length > 2){
						target.find('.items').append(StepFilteredConfigurator.makeShoppingcartButton());
					}
					target.find('tr.here').find(':input').attr('checked', 'checked');
				},
				handlePrepareDataModelAndVerify: function(tableIdx, rowIdx){
					var step = this.parent;
					var stepId = this.parent.itemId;
					var data = StepFilteredConfigurator.data;
					var oldTableIndex = data.steps[stepId].items[this.id].tableIndex;
					var oldCurrentItem = data.steps[stepId].items[this.id].items[oldTableIndex].table.currentItem;
					data.free = this.free;
					data.steps[stepId].items[this.id].items[oldTableIndex].table.rows[oldCurrentItem].here = false;
					data.changedStep = stepId;
					data.steps[stepId].tableIndex = 0;
					data.steps[stepId].items[this.id].tableIndex = tableIdx;
					data.steps[stepId].items[this.id].items[tableIdx].table.currentItem = rowIdx;
					data.customerWidth = null;
					data.customerHeight = null;
					if (data.steps[stepId].items.length > 1){
						data.steps[stepId].items[1].here = false;
					}
					StepFilteredConfigurator.data = data;
					StepFilteredConfigurator.verifyData(step, self);
				}
			}
		);
	/* << */


	/* >>  Step filtered configurator row item custom format*/
		StepFilteredConfiguratorRowItemCustomFormat = $.extend(
			$.clone(StepFilteredConfiguratorRowItemVariant1),
			{
				create: function(){
					var o = StepFilteredConfiguratorRowItemVariant1.create.call(this);
					o.free = true;
					return o;
				},
				makeVariantLayout: function(pmt){
					var name = 'variant';
					var select = $('<select name="' + name + '" id="customerSizeVariant"/>');
					var wl = $(
						'<table cellpadding="0" cellspacing="0" border="0" class="customerVariant">' +
							'<tr>' +
								'<td class="pmt">' +
									pmt + ':' +
								'</td>' +
								'<td class="field">' +
								'</td>' +
							'</tr>' +
						'</table>'
					);
					var self = this;
					select.bind('change', function(e){
						var data = StepFilteredConfigurator.data;
						var stepId = self.parent.itemId;
						var opts = self.data.options.items;
						var elm = this;
						$(opts).each(function(i){
							var value = this.value;
							if (value == $(elm).val()){
								data.steps[stepId].items[1].options.items[i].here = true;
							}else{
								data.steps[stepId].items[1].options.items[i].here = false;
							}
						})
						StepFilteredConfigurator.data = data;
						self.handlePrepareDataModelAndVerify();
					});
					wl.find('.field').append(select);
					return wl;
				},
				makeOptionLayout: function(opt){
					var o = $(
						'<option value="' + opt.value + '">' + opt.title + '</option>'
					);
					return o;
				},
				makeButtonLayout: function(){
					var b = $(
						'<input type="image" src="/xist4c/px/spc.gif" class="button formatSaveButton" id="formatSaveButton" />'
					);
					return b;
				},
				makeSizeLayout: function(pmt, hint, mode){
					var name = 'customerWidth';
					if (mode == 'height') name = 'customerHeight';
					var input = $('<input type="text" name="' + name + '" value="" id="' + name + '"/>');
					var self = this;
					input.bind('click', function(e){
						if (!self.data.here){
							self.handlePrepareDataModelAndVerify();
						}
					});
					if (hint){
						hint = '(max. ' + hint + ')';
					}else{
						hint = '';
					}
					var sl = $(
						'<table cellpadding="0" cellspacing="0" border="0" class="customerSize">' +
							'<tr>' +
								'<td class="pmt">' +
									pmt + ':' +
								'</td>' +
								'<td class="field">' +
									'<div class="hint">' + hint + '</div>' +
								'</td>' +
							'</tr>' +
						'</table>'
					);
					sl.find('.field').prepend(input);
					return sl;
				},
				makeContentLayout: function(){
					var id = this.parent.id + '_' + this.id;
					var self = this;
					var cont = $(
						'<form method="post" action="#">' +
							'<table cellpadding="0" cellspacing="0" border="0" class="customerFormat">' +
								'<tr>' +
									'<td class="variant cfCol0_0">' +
									'</td>' +
									'<td colspan="2" class="cfCol0_1">' +
									'</td>' +
									'<td class="cfCol0_3">' +
									'</td>' +
								'</tr>' +
								'<tr>' +
									'<td class="option cfCol1_0">' +
									'</td>' +
									'<td class="cfCol1_1">' +
									'</td>' +
									'<td class="cfCol1_2">' +
									'</td>' +
									'<td class="price cfCol1_3">' +
									'</td>' +
								'</tr>' +
								'<tr>' +
									'<td class="cfCol2_0">' +
									'</td>' +
									'<td class="cfCol2_1">' +
									'</td>' +
									'<td class="cfCol2_2">' +
									'</td>' +
									'<td class="cfCol2_3">' +
									'</td>' +
								'</tr>' +
							'</table>' +
						'</form>'
					);
					cont.find('.option')
						.append('<input type="radio" name="step_1_0" value="customFormat"/>')
						.end()
						.find(':input')
						.bind('click', function(e){
							$(this).parents('table.itemsOuter').find('table.formularRadioTable tr').removeClass('here');
							self.handlePrepareDataModelAndVerify();
						});
					cont.find('.cfCol1_1').append(this.makeSizeLayout($.lang('width'), this.data.maxWidth, 'width'));
					cont.find('.cfCol1_2').append(this.makeSizeLayout($.lang('heigth'), this.data.maxHeight, 'height'));
					if (this.data.options.items.length > 0){
						cont.find('.cfCol0_1').append(this.makeVariantLayout(this.data.options.title));
					}
					cont.find('.cfCol2_2').append(this.makeButtonLayout());
					cont.bind('submit', function(e){
						e.preventDefault();
						e.stopPropagation();
						self.handlePrepareDataModelAndVerify();
					});
					return cont;
				},
				makeItem: function(){
					var item = $(
						'<td class="itemOuter">' +
							'<div class="customFormatPanel">' +
								'<div class="title">' +
									$.lang('setCustomFormat') +
								'</div>' +
								'<div class="content">' +
								'</div>' +
							'</div>' +
						'</td>'
					);
					item.find('.content').append(this.makeContentLayout());
					var colWidth = 100 / this.parent.data.colCount;
					item.css({'width': colWidth + '%'});
					return item;
				},
				handlePrepareDataModelAndVerify: function(){
					var step = this.parent, stepId = this.parent.itemId, data = StepFilteredConfigurator.data, i,
					formData = $('table.customerSize').find(':input').serializeArray(), tableIdx = 0, item;
					data.steps[stepId].currentItem = 1;
					$(data.steps[stepId].items[0].items).each(function(i){
						$(this.table.rows).each(function(j){
							this.here = false;
						});
					});
					data.free = this.free;
					data.changedStep = stepId;
					for (i = 0; i < data.steps[stepId].items.length; i+=1){
						item = data.steps[stepId].items[i];
						if (item.type && item.type === 'StepFilteredConfiguratorRowItemCustomFormat'){
							tableIdx = i;
							break;
						}
					}
					data.steps[stepId].tableIndex = tableIdx;
					data.customerWidth = formData[0].value;
					data.customerHeight = formData[1].value;
					StepFilteredConfigurator.data = data;
					StepFilteredConfigurator.verifyData(step, this);
				},
				make: function(target){
					var item = this.makeItem();
					target.append(item);
					if (this.data.here){
						$('table.customerFormat').find('input[name=step_1_0]').attr('checked', true);
						$('#customerWidth').val(StepFilteredConfigurator.data.customerWidth).focus();
						$('#customerHeight').val(StepFilteredConfigurator.data.customerHeight);
					}
					var self = this;
					var opts = this.data.options.items;
					if (opts && opts.length > 0){
						var select = $('#customerSizeVariant');
						$(opts).each(function(i){
							var o = self.makeOptionLayout(this);
							select.append(o);
							if (this.here) o.attr('selected', 'selected');
						});
					}
				}
			}
		);
	/* << */


	/* >> Step filtered configurator initialization */
		startColumnFilteredConfiguration = function(){
			PrdPriceBarUpdater = ProductAndPriceBarUpdater.create();
			ScartHandler = ShoppingcartHandler.create();
			PosterPrdTabHandler = PosterProductTabHandler.create();
			PosterPrdErrorMsgHandler = StepFilteredConfiguratorErrorMessagesHandler.create();
			StepFilteredConfigurator.init(
				{
					'target': $('#columnFilteredConfigurator'),
					'cpKey': 'posterproduct', // cherrypy handler key
					'onAfterInit': function(data){
						PrdPriceBarUpdater.update(data);
						ScartHandler.update(data, {'index': 0});
						PosterPrdTabHandler.update(data, {'index': 0});
						PosterPrdErrorMsgHandler.handleError(data);
					},
					'onDataRequestSuccess': function(data, column, item){
						PrdPriceBarUpdater.update(data);
						ScartHandler.update(data, {'index': 0});
						PosterPrdTabHandler.update(data, {'index': 0});
						PosterPrdErrorMsgHandler.handleError(data);
					}
				}
			);
			$('body').bind('tabsshow', function(e, ui){
				ScartHandler.update(StepFilteredConfigurator.data, ui);
				PosterPrdTabHandler.update(StepFilteredConfigurator.data, ui);
			});
		}
		
		startRowFilteredXxlConfiguration = function(){
			TopImagePrep = TopImagePreparer.create();
			QuickChoiceXxl = TopProductQuickChoiceXxl.create();
			ShoppingcartPrep = ShoppingcartPreparerXxl.create();
			LinkPreparerXxl = PageLinkPreparerXxl.create();
			AddOptsXxl = AdditionalOptionsXxl.create();
			ErrorMsgHandlerXxl = StepFilteredConfiguratorErrorMessagesHandler.create();
			StepFilteredConfigurator.init(
				{
					'target': $('#rowFilteredXxlConfigurator'),
					'cpKey': 'xxlproduct', // cherrypy handler key
					'deleteUnnecessarySteps': true,
					'onAfterInit': function(data){
						TopImagePrep.update(data);
						var opts = {
							'title': data.productTitle,
							'data': data,
							'target': $('#prdConfTopConfigXxl'),
							'configurator': this,
							'onlyInfo': true
						}
						QuickChoiceXxl.init(opts);
						ShoppingcartPrep.updateShoppingcartAndWkButtons(data);
						LinkPreparerXxl.update(data, this.urlParams);
						AddOptsXxl.update(data);
						ErrorMsgHandlerXxl.handleError(data);
					},
					'onDataRequestSuccess': function(data, column, item){
						if (item.parent.itemId == 0){
							$('body').scrollTo('#step_1_items', 1000, {
									'axis': 'y'
							});
						}
						QuickChoiceXxl.update(data);
						ShoppingcartPrep.updateShoppingcartAndWkButtons(data);
						LinkPreparerXxl.update(data, this.urlParams);
						AddOptsXxl.update(data);
						ErrorMsgHandlerXxl.handleError(data);
					}
				}
			);
			$('body').bind('tabsshow', function(e, ui){
			});
		}
	/* << */
/* << */


/* >> Step filtered configurator add ons there are triggered on configurator events*/
	/* >> XXL top product quick choice */
		TopProductQuickChoiceXxl = $.extend(
			$.clone(TopProductQuickChoice),
			{
				create: function(){
					var o = TopProductQuickChoice.create.call(this);
					return o;
				},
				init: function(opts){
					this.opts = opts || null;
					if (this.opts) this.target = this.opts.target || null;
					if (this.target.size() > 0){
						this.makeTableWithTitle();
						if (this.opts.onlyInfo){
							this.makeRowsForInfo();
						}else{
							this.makeRowsWithBindings();
						}
					}
				},
				makeTableWithTitle: function(){
					var t = this.target;
					t.html(
						'<table cellspacing="0" cellpadding="0" border="0">' +
							'<tr>' +
								'<th>' + this.opts.title + '</th>' +
							'</tr>' +
						'</table>'
					);
				},
				makeRowsWithBindings: function(){
					var r = $(
						'<tr>' +
							'<td class="value"></td>' +
						'</tr>'
					);
					var table = this.target.find('table');
					var self = this;
					var data = this.opts.data;
					r.text(data.infoText);
				},
				makeRowsForInfo: function(){
					var r = $(
						'<tr>' +
							'<td class="value"></td>' +
						'</tr>'
					);
					var table = this.target.find('table');
					var self = this;
					var data = this.opts.data;
					r.find('.value').text(data.infoText);
					table.append(r);
				},
				update: function(data){
					this.target.find('.value').text(data.infoText);
				}
			}
		);
	/* << */

	/* >> posters & more product and price updater */
		ProductAndPriceBarUpdater = $.extend(
			$.clone(LLObject),
			{
				create: function(){
					var o = LLObject.create.call(this);
					return o;
				},
				update: function(data){
					var cols = data.steps;
					var bar = $('div.cfcFunctionBar');
					var prd = bar.find('.name');
					var size = bar.find('.size');
					var price = bar.find('.value');
					var sizeVal = '-- x -- cm';
					var priceVal = '--,--&euro;';
					if (cols[2].currentItem != null){
						sizeVal = cols[2].items[cols[2].currentItem].title;
						if (data.meta) priceVal = data.meta.price || priceVal;
					}
					size.html(' ' + sizeVal);
					price.html(' ' + priceVal);
					if (cols[0].currentItem != null){
						prd.html(' ' + cols[0].items[cols[0].currentItem].title);
					}
				}
			}
		);
	/* << */
	
	/* >> posters & more shoppingcart handler */
		ShoppingcartHandler = $.extend(
			$.clone(LLObject),
			{
				create: function(){
					var o = LLObject.create.call(this);
					o.auf_id = null;
					o.hasInterval = null;
					return o;
				},
				makeHiddenField: function(name, value){
					var form = $('div.cfcFunctionBar form');
					if (form.size() > 0){
						var input = form.find('input[name=' + name + ']');
						if (input.size() == 0){
							var inp = $('<input type="hidden" name="' + name + '" value="' + value + '"/>');
							form.append(inp);
						}else{
							input.val(value);
						}
					}
				},
				update: function(data, ui){
					this.auf_id = data.auf_id;
					var auf_id = this.auf_id || '';
					this.makeHiddenField('auf_id', auf_id);
					this.makeHiddenField('opt_job_id', '');
					this.makeHiddenField('handleArticle', '1');
					var motiveButton = $('div.cfcFunctionBar .cfc_functionButton');
					var scartButton = $('div.cfcFunctionBar .cfc_shoppingCartButton');
					var form = $('div.cfcFunctionBar form');
					var tabs = $('#uiTab0');
					// prepare shoppingcart action url.
					var action = $('.wkTopShell').find('a').attr('href') || '#';
					form.attr({'action': action});
					if (ui.index < 1){
						if (!data.auf_id){
							motiveButton.addClass('cfc_functionButton_pass');
							var tabLockStatus = 'disable';
							motiveButton.show().unbind();
						}else{
							motiveButton.removeClass('cfc_functionButton_pass');
							var tabLockStatus = 'enable';
							var self = this;
							motiveButton.show().bind('click', function(e){
								tabs.tabs('select', 1);
							});
						}
						form.hide();
						scartButton.unbind();
					}else{
						motiveButton.hide().unbind();
						var self = this;
						scartButton.bind('click', function(e){
							var job_id = '';
							if (typeof window.POSTER_PRODUCT_VC_MEDIA_TOOL_JOB_ID != 'undefined' && window.POSTER_PRODUCT_VC_MEDIA_TOOL_JOB_ID){
								job_id = window.POSTER_PRODUCT_VC_MEDIA_TOOL_JOB_ID;
							}
							self.makeHiddenField('opt_job_id', job_id);
							if (self.auf_id != '' && job_id != ''){
								if ($('#uiTab0').tabs('option', 'selected') == 1){
									// save vc-media gfx data and submit form
									PosterPrdTabHandler.saveVcMediaFlashData('ScartHandler', 'submitShoppingcartForm');
								}else if ($('#uiTab0').tabs('option', 'selected') > 1){
									self.submitShoppingcartForm();
								}
							}
						});
						self.wait4FrameScriptReadyThenShowWKButton();
					}
				},
				wait4FrameScriptReadyThenShowWKButton: function(){
					var self = this;
					var vcMediaToolNamespace = window.frames[0];
					if (!this.hasInterval){
						this.hasInterval = setInterval(function(){
							if (typeof vcMediaToolNamespace.saveTemplate != 'undefined'){
								$('div.cfcFunctionBar form').show();
								clearInterval(self.hasInterval);
								self.hasInterval = null;
							}else{
								self.wait4FrameScriptReadyThenShowWKButton();
							}
						}, 1000);
					}
				},
				submitShoppingcartForm: function(){
					$('.cfc_shoppingCartButton').eq(0).parent('form').submit();
				}
			}
		);
	/* << */
	
	/* >> posters & more tab handler */
		PosterProductTabHandler = $.extend(
			$.clone(LLObject),
			{
				create: function(){
					var o = LLObject.create.call(this);
					o.productChanged = false;
					o.old_auf_id = null;
					o.tabIndex = null;
					o.updatePreview = false;
					return o;
				},
				setFlashToolUrlAndPublicJobId: function(data){
					$('#vcMediaToolFrame').attr({'src': ''});
					this.loadingLayouttoolImage('create');
					var lturl = window.location.protocol + '//' + window.location.host + '/cgi-bin/r31msvc_fremdsystem_aufruf.pl';
					lturl += '?var_hauptpfad=../creativpilot/r31/vc_media/&var_fa1_select=var_fa1_select||1|&var_aufruf_art=14';
					lturl += '&var_xml_formatvorgaben_breite=' + data.meta.prdWidth + '&var_xml_formatvorgaben_hoehe=' + data.meta.prdHeight;
					var realData = data;
					var self = this;
					$.ajax({
						type: 'get',
						url: lturl,
						data: null, //{'lturl': encodeURIComponent(lturl)},
						success: function(data, msg){
							self.loadingLayouttoolImage('delete');
							data = data.replace(/http:/g, window.location.protocol);
							data = data.replace(/flyerpilot\.xist4c\.de/, 'www.flyerpilot.de');
							$('#vcMediaToolFrame').attr({'src': data + '&var_html_folgemaske=r31msvcmedia_daten_anzeigen_job_api.html'});
							var jobId = Utils.getUrlParamsAsJson(data);
							if (jobId) jobId = jobId.var_vb4;
							window.POSTER_PRODUCT_VC_MEDIA_TOOL_JOB_ID = jobId;
							self.update(realData, {'index': 1});
						},
						error: function(req, status, error){
							self.loadingLayouttoolImage('delete');
							$('#vcMediaToolFrame').attr({'src': ''});
							window.POSTER_PRODUCT_VC_MEDIA_TOOL_JOB_ID = null;
						}
					});
				},
				update: function(data, ui){
					var tabs = $('#uiTab0');
					if (ui.index == 0){
						this.tabIndex = ui.index;
						this.updatePreview = true;
						var tidx = [1,2,3];
						for (var i in tidx) tabs.tabs('disable', tidx[i]);
						if (data.auf_id){
							tabs.tabs('enable', 1);
							if (this.old_auf_id != data.auf_id){
								this.productChanged = true;
								this.old_auf_id = data.auf_id;
							}
						}else{
							$('#vcMediaToolFrame').attr({'src': ''});
							window.POSTER_PRODUCT_VC_MEDIA_TOOL_JOB_ID = null;
						}
					}else if (ui.index == 1){
						this.tabIndex = ui.index;
						this.updatePreview = true;
						var tabs = $('#uiTab0');
						if (!window.POSTER_PRODUCT_VC_MEDIA_TOOL_JOB_ID || this.productChanged){
							this.productChanged = false;
							this.setFlashToolUrlAndPublicJobId(data);
						}else{
							tabs.tabs('enable', 2);
						}
					}else if (ui.index == 2){
						this.tabIndex = ui.index;
						this.saveVcMediaFlashData('PosterPrdTabHandler', 'switchTabToPreviewAndReceiveVcMediaXml');
					}
				},
				saveVcMediaFlashData: function(obj, method){
					this.showLoadingPreviewPanel();
					var vcMediaToolNamespace = window.frames[0];
					vcMediaToolNamespace.saveTemplate(obj, method);
				},
				switchTabToPreviewAndReceiveVcMediaXml: function(){
					var jobId = window.POSTER_PRODUCT_VC_MEDIA_TOOL_JOB_ID;
					var url = window.location.protocol + '//' + window.location.host + '/cgi-bin/r31msvc_fremdsystem_aufruf.pl?';
					url += 'var_hauptpfad=../creativpilot/r31/vc_media/&var_fa1_select=var_fa1_select||1|';
					url += '&var_aufruf_art=8&var_vb4_uebergabe=' + jobId + '&var_crmkd110_uebergabe=J';
					var self = this;
					$.ajax({
						type: 'get',
						url: url,
						success: function(data, msg){
							self.receiveVcMediaXmlSuccess(data, msg);
						},
						error: function(req, status, error){
							self.receiveVcMediaXmlError(req, status, error);
						}
					});
				},
				loadingLayouttoolImage: function(mode){
					// mode: create | delete
					var panel = $('#uiTab01'), target = panel.find('.fsMediaShell .free');
					if (mode === 'create'){
						target.addClass('viewport');
						target.prepend('<div id="loadingLayouttool"></div>');
					}else if (mode === 'delete'){
						Utils.busyWait(
							function(intervalObj){
								if ($('#vcMediaToolFrame').attr('src') != ''){
									return true;
								}
								return false;
							},
							500,
							1000,
							function(intervalObj){
								$('#loadingLayouttool').remove();
								target.removeClass('viewport');
							}
						);
					}
				},
				showLoadingPreviewPanel: function(){
					var panel = $('#uiTab02');
					var target = panel.find('.fsMediaShell .free').empty();
					target.append('<div id="loadingPreview"></div>');
				},
				receiveVcMediaXmlSuccess: function(data, msg){
					var data = $(data);
					var tabs = $('#uiTab0');
					var panel = $('#uiTab02');
					var flashUrl = "/flash/flashtool/1832_flyerpilot_flashtool.swf";
					flashUrl += '?loadimage=' + encodeURIComponent(data.find('preview').text());
					var flashContainer = $('#flashToolContainer');
					if (this.updatePreview = true){
						var target = panel.find('.fsMediaShell .free').empty();
						target.append('<div id="flashToolContainer"></div>');
						flashContainer = $('#flashToolContainer');
						this.updatePreview = false;
					}
					if (flashContainer.size() > 0){
						var flashvars = {};
						var params = {
							'codebase': 'http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=10,0,0,0',
							'width': '958',
							'height': '585',
							'src': '/flash/flashtool/1832_flyerpilot_flashtool',
							'quality': 'high',
							'pluginspage': 'http://www.adobe.com/go/getflashplayer_de',
							'align': 'middle',
							'play': 'true',
							'loop': 'true',
							'scale': 'showall',
							'wmode': 'transparent',
							'devicefont': 'false',
							'id': '1832_flyerpilot_flashtool',
							'bgcolor': '#ffffff',
							'name': '1832_flyerpilot_flashtool',
							'menu': 'true',
							'allowFullScreen': 'false',
							'allowScriptAccess': 'sameDomain',
							'movie': '/flash/flashtool/1832_flyerpilot_flashtool',
							'salign': ''
						};
						var attributes = {};
						swfobject.embedSWF(flashUrl, "flashToolContainer", "958", "585", "9.0.0",null, flashvars, params, attributes);
					}
				},
				receiveVcMediaXmlError: function(req, status, error){
					/* LOGGING >> */
					if (window.console) console.log(req, status, error);
					/* << LOGGING */
				}
			}
		);
	/* << */

	/* >> XXL shopping cart preparer */
		ShoppingcartPreparerXxl = $.extend(
			$.clone(ShoppingcartPreparer),
			{
				create: function(){
					var o = ShoppingcartPreparer.create.call(this);
					return o;
				},
				updateShoppingcartAndWkButtons: function(data){
					this.update(data);
					if (data.auf_id){
						$('.xxlShoppingcartButton').fadeIn('slow');
					}else{
						$('.xxlShoppingcartButton').fadeOut('slow');
					}
				}
			}
		);
	/* << */

	/* >> XXL page link preparer */
		PageLinkPreparerXxl = $.extend(
			$.clone(PageLinkPreparer),
			{
				create: function(){
					var o = PageLinkPreparer.create.call(this);
					return o;
				},
				update: function(data, params){
					if (!params) var params = Utils.getUrlParamsAsJson(window.location.href, true);
					if (data.optionsParam) params = $.extend(params, data.optionsParam);
					if (!data.auf_id){
						$.extend(params, {'auf_id': data.baseArticle});
					}else{
						$.extend(params, {'config': 'true'});
					}
					var tabItems = $('div.contentNavigationShell a');
					$(tabItems).each(function(i){
						var href = this.href;
						var rex = /\?/;
						if (rex.test(href)){
							href = this.href.substring(0, this.href.search(rex));
						}
						this.href = href + Utils.getUrlParamsFromJson(params);
					});
				}
			}
		);
	/* << */

	/* >> XXL additional options*/
		AdditionalOptionsXxl = $.extend(
			$.clone(LLObject),
			{
				options: null,
				create: function(){
					var o = LLObject.create.call(this);
					o.step = null;
					o.scOptsContainer = $('#shoppingCartConfigOptData');
					return o;
				},
				update: function(data){
					if (data.steps.length > 2){
						this.step = data.steps[2];
						this.makeShoppingCartOpts();
					}else{
						this.scOptsContainer.empty();
					}
				},
				makeShoppingCartOpts: function(){
					var container = this.scOptsContainer;
					container.empty();
					$(this.step.items).each(function(i){
						if (this.here){
							container.append('<input type="hidden" name="opt_' + this.value + '" value="' + this.value + '"/>');
						}
					});
				}
			}
		);
	/* << */

	/* >> step filtered configurator handle error messages (inherits ErrorMessagesHandler)*/
		StepFilteredConfiguratorErrorMessagesHandler = $.extend(
			$.clone(ErrorMessagesHandler),
			{
				create: function(){
					return ErrorMessagesHandler.create.call(this);
				},
				handleError: function(data){
					if (data.errorMessage){
						alert(data.errorMessage.title + ':\n' + data.errorMessage.text);
						StepFilteredConfigurator.data.errorMessage = null;
					}
				}
			}
		);
	/* << */
/* << */


/* >> Poster Product Overview Loader */
	PosterProductOverviewLoader = $.extend(
		$.clone(LLObject),
		{
			opts: null,
			data: null,
			onAfterInit: null,
			onItemClick: null,
			create: function(){
				var o = LLObject.create.call(this);
				o.target = null;
				o.items = [];
				return o;
			},
			init: function(opts){
				var url = AjaxURLManager.getUrlWithKey('posterproductoverview');
				this.opts = opts;
				if (opts.onAfterInit && typeof opts.onAfterInit == 'function'){
					this.onAfterInit = opts.onAfterInit;
				}
				if (opts.onItemClick && typeof opts.onItemClick == 'function'){
					this.onItemClick = opts.onItemClick;
				}
				this.target = opts.target || null;
				var self = this;
				var xs_id = null;
				if (Utils.getUrlParamsAsJson() && Utils.getUrlParamsAsJson().xs_id){
					xs_id = Utils.getUrlParamsAsJson().xs_id;
				}
				$.getJSON(url, function(data, textStatus){
					self.data = data;
					$(data.items).each(function(i){
						var here = xs_id == this.xs_id ? true: false;
						var item = PosterProductOverviewItem.create();
						item.id = i;
						item.domId = 'posteroverviewItem_' + i;
						item.data = self.data;
						item.title = this.title;
						item.co_id = this.co_id || null;
						item.linkname = this.linkname || null;
						item.here = here;
						item.xs_id = this.xs_id || null;
						item.price = this.price;
						item.image = this.image;
						item.width = this.width;
						item.onClick = self.onItemClick;
						self.appendItem(item);
					});
					self.setContentShellWidth();
					Scroller = ScrollBar.create({
						'target': $('#prdScrollPane'),
						'orientation': 'x',
						'scrollerHeight': 21,
						'scrollerWidth': 21,
						'arrowHeight': 34,
						'arrowWidth': 40,
						'arrowMoveIn': 0,
						'sliderCapsPadding': 6,
						'stepSize': 35
					});
					var cb = self.onAfterInit;
					if (cb && typeof cb == 'function'){
						cb.call(self, data);
					}
				});
			},
			appendItem: function(item){
				if (item.instanceOf(PosterProductOverviewItem)){
					this.items.push(item);
					item.make(this.target);
				}
			},
			setContentShellWidth: function(){
				var w = 0;
				$(this.items).each(function(i){
					w += this.width;
				});
				this.target.width(w);
			}
		}
	);
	
	PosterProductOverviewItem = $.extend(
		$.clone(LLObject),
		{
			create: function(){
				var o = LLObject.create.call(this);
				o.id = null;
				o.domId = null;
				o.data = null;
				o.image = null;
				o.title = null;
				o.price = null;
				o.width = null;
				o.co_id = null;
				o.linkname = null;
				o.here = false;
				o.xs_id = null;
				o.onClick = null;
				return o;
			},
			makeItemLayout: function(){
				var lay = $(
					'<div class="item item_' + this.id + '" id="' + this.domId + '">' +
						'<div class="title">' + this.title + '</div>' +
						'<div class="price">' + this.price + '</div>' +
					'</div>'
				);
				if (this.here) lay.addClass('itemHere');
				var css = {'width': this.width};
				if (this.image){
					css = $.extend(css, {'background-image': 'url(' + this.image.src + ')'});
				}
				lay.css(css);
				if (this.co_id){
					var self = this, page, params = {};
					lay.bind('click', function(e){
						params.id = self.co_id;
						if (self.xs_id){
							params.xs_id = self.xs_id;
						}
						if (typeof Scroller != 'undefined' && typeof Scroller.currentScrollPos == 'number'){
							params.spos = Scroller.currentScrollPos;
						}
						if (self.linkname){
							page = self.linkname;
						}else{
							page = 'Produkt_Detail_id_' + self.co_id + '_.htm';
						}
						page += Utils.getUrlParamsFromJson(params);
						var cb = self.onClick;
						if (cb && typeof cb == 'function'){
							cb.call(self, self.data);
						}
						window.location = page;
					}).css({'cursor': 'pointer'});
				}
				return lay;
			},
			make: function(target){
				var item = this.makeItemLayout();
				target.append(item);
			}
		}
	);

	/* >> Poster product overview loader initialization */
		startPosterOverviewLoader = function(){
			PosterOverviewLoader = PosterProductOverviewLoader.create();
			HandleDetailImage = HandleProductDetailImage.create();
			PosterOverviewLoader.init({
					'target': $('div.content', '#prdScrollPane'),
					'onAfterInit': function(data){
						HandleDetailImage.update(data);
						var params = Utils.getUrlParamsAsJson(window.location.href);
						var spos = 0;
						if (params && params.spos) spos = params.spos;
						Scroller.scrollTo(spos, 0);
					},
					'onItemClick': function(data){
					}
			});
		}
	/* << */
/* << */


/* >> Poster product overview loader add ons there are triggered on loader events*/
	HandleProductDetailImage = $.extend(
		$.clone(LLObject),
		{
			create: function(){
				var o = LLObject.create.call(this);
				return o;
			},
			update: function(data){
				var dimg = $('#prodImgDetail');
				var params = Utils.getUrlParamsAsJson(location.href);
				var xs_id = null;
				if (params && params.xs_id) xs_id = params.xs_id;
				if (dimg.size() > 0){
					$(data.items).each(function(i){
						if (this.xs_id == xs_id){
							if (this.detailImage){
								dimg.css({
									'width': this.detailImage.width,
									'height': this.detailImage.height,
									'background': 'url(' + this.detailImage.src + ') center no-repeat'
								});
							}
						}
					});
				}
			}
		}
	);
/* << */


/* >> Poster product image handler (standalone) */
	HandleProductDetailImageStandalone = $.extend(
		$.clone(PosterProductOverviewLoader),
		{
			create: function () {
				var o = PosterProductOverviewLoader.create.call(this);
				return o;
			},
			init: function (opts) {
				var dimg = $('#prodImgDetail');
				if (dimg.size() > 0){
					var url = AjaxURLManager.getUrlWithKey('posterproductoverview');
					var self = this;
					var xs_id = null;
					xs_id = parseInt(dimg.attr('class').split('prdImgDetail_xsid_')[1]);
					$.getJSON(url, function (data, textStatus) {
						self.data = data;
						$(data.items).each(function (i) {
							if (this.xs_id === xs_id) {
								if (this.detailImage) {
									dimg.css({
										'width': this.detailImage.width,
										'height': this.detailImage.height,
										'background': 'url(' + this.detailImage.src + ') center no-repeat'
									});
								}
							}
						});
					});
				}
			}
		}
	);
/* << */


/* >> Classic mode configurator (inherit SlotMachineSelectVariant)*/
	/* >> Slot machine classic mode*/
		SlotMachineClassicMode = $.extend(
			$.clone(SlotMachineSelectVariant),
			{
				init: function(opts){
					window.slotMachinePresent = 1;
					if (opts){
						this.opts = opts;
						this.makeShell(opts.target);
						var urlParams = this.urlParams = this.getURLParams();
						if (!urlParams.ovn) urlParams.ovn = 'false';
						this.url = AjaxURLManager.getUrlWithKey('configarticle', urlParams);
						if (this.urlParams.loadPos) this.urlParams.loadPos = null;
						var cb = opts.onAfterSlotCatch;
						if (cb && typeof cb == 'function') this.onAfterSlotCatch = cb;
						var cbdr = opts.onDataRequest;
						if (cbdr && typeof cbdr == 'function') this.onDataRequest = cbdr;
						var cbdrs = opts.onDataRequestSuccess;
						if (cbdrs && typeof cbdrs == 'function') this.onDataRequestSuccess = cbdrs;
						if (this.url){
							var self = this;
							$.getJSON(this.url, function(data, textStatus){
								var d = self.data = data;
								if (d.type == 'SlotMachineData'){
									$(d.slots).each(function(i){
										if (this.type == 'SlotMachineSlot'){
											var slot = SlotMachineClassicModeSlot.create(this.title, this.currentItem);
											slot.id = 'slot_' + i;
											slot.itemId = i;
											slot.data = this;
											slot.width = this.width;
											$(this.items).each(function(i){
												if (this.type == 'SlotMachineSlotItem'){
													var slotItem = SlotMachineSlotItemSelectVariant.create(this.title, this.value);
													slotItem.id = slot.id + '_slotItem_' + i;
													slotItem.itemCnt = i;
													slotItem.data = this;
													slotItem.slot = slot;
													slotItem.width = slot.width;
													slot.appendItem(slotItem);
												}
											});
											self.appendSlot(slot);
										}
									});
								}
								// call init callback if exists
								var initCb = opts.onAfterInit;
								if (initCb && typeof initCb == 'function'){
									initCb.call(self, self.data);
								}
								if (self.onDataRequestSuccess) self.onDataRequestSuccess.call(self, null, d);
							});
						}
					}
				},
				verifyData: function(slot){
					var slot = slot || null;
					var self = this;
					var oldData = this.data;
					if (slot) this.data.changedSlot = slot.itemId;
					var cbdr = this.onDataRequest;
					if (cbdr) cbdr.call(this, self, this.data);
					var url = AjaxURLManager.getUrlWithKey('configarticle');
					//alter data and send it to cherrypy
					for (var i in this.data.slots){
						this.data.slots[i].currentItem = this.slots[i].currentItem;
					}
					$.ajax({
						type: 'post',
						url: url,
						data: {'content': encodeURIComponent($.toJson(SlotMachineClassicMode))},
						success: function(data, msg){self.verifyDataRequestSuccess(data, msg, slot);},
						error: function(req, status, error){self.verifyDataRequestError(req, status, error, slot);}
					});
				}
			}
		);
	/* << */

	/* >> slot machine slot classic mode (inherit SlotMachineSlotSelectVariant) */
		SlotMachineClassicModeSlot = $.extend(
			$.clone(SlotMachineSlotSelectVariant),
			{
				create: function(title, currentItem){
					return SlotMachineSlotSelectVariant.create.call(this, title, currentItem);
				},
				makeSlotLayout: function(){
					var slot = $(
						'<tr>' +
							'<td class="' + this.id + '_titleColumn titleColumn"><div class="slotTitle"><span>' + this.title + '</span></div></td>' +
							'<td class="' + this.id + '_column selectColumn">' +
								'<div class="slotSelect">' +
									'<select name="' + this.id + '_select" id="' + this.id + '_select"></select>' +
								'</div>' +
							'</td>' +
						'</tr>'
					);
					var self = this;
					slot.find('select').bind('change', function(e){
						var select = $(this);
						var value = select.val();
						self.data.currentItem = self.currentItem = 0;
						select.find('option').each(function(i){
							if ($(this).attr('value') == value) self.data.currentItem = self.currentItem = i;
						});
						
						SlotMachineClassicMode.data.art_id = null;
						SlotMachineClassicMode.data[SlotMachineClassicMode.data.pk] = null;
						SlotMachineClassicMode.verifyData(self);
					});
					return slot;
				}
			}
		);
	/* << */

	/* >> Slot machine classic mode initialization */
		// starts the slot machine
		StartSlotmachineClassicMode = function(){
			ScartPreparer = ShoppingcartPreparer.create();
			DetailImagePrep = DetailImagePreparer.create();
			ProductDescriptionPrep = ProductDescriptionPreparer.create();
			SlotMachineClassicMode.init(
				{
					'target': $('#slotMachineClassicModeConfigurator'),
					'onAfterInit': function(data){
						ScartPreparer.update(data);
						DetailImagePrep.update(data);
						ProductDescriptionPrep.update(data);
					},
					'onAfterSlotCatch': function(slot){
					},
					'onDataRequest': function(slot, oldData){
					},
					'onDataRequestSuccess': function(slot, data){
						ScartPreparer.update(data);
						ProductDescriptionPrep.update(data);
					}
				}
			);
		}
	/* << */
/* << */


/* >> Pattern download preparer */
	PatternDownloadLinkPreparer = $.extend(
		$.clone(LLObject),
		{
			create: function(){
				var o = LLObject.create.call(this);
				return o;
			},
			update: function(){
				if ($('#patternDownload').size() > 0){
					var params = Utils.getUrlParamsAsJson();
					if (params.auf_id){
						var url = AjaxURLManager.getUrlWithKey('formattemplate4article', {'auf_id': params.auf_id});
						var self = this;
						$.ajax({
							type: 'get',
							url: url,
							dataType: 'text',
							success: function(data, msg){
								if (data != '') $('#patternDownload').attr({'href': data});
							},
							error: function(req, status, error){}
						});
					}
				}
			}
		}
	);
/* << */


/* >> Order Process handle submits */
	SpecSubmitAction = $.extend(
		$.clone(LLObject),
		{
			create: function(){
				var o = LLObject.create.call(this);
				return o;
			},
			bindFields: function(outerEl, innerEl, event, form){
				var self = this;
				
				if (!form){
					var form = outerEl
				}
				
				$(outerEl).find(innerEl).bind(event, function(e){
					if (innerEl == 'a'){
						e.preventDefault();
						e.stopPropagation();
					}
					self.sendRequest($(form));
				});
			},
			sendRequest: function(form){
				form.submit();
			}
		}
	);
	SpecialSubmitAction = SpecSubmitAction.create();
/* << */


/* >> Input Button Hover Effect */
	InputButtonHoverEffect = {
		hover: function(){
			var inputs = $('form input[type=image]');
			var submits = $('form input[type=submit]');
			inputs.hover(
				function(){$(this).addClass('buttonHover');},
				function(){$(this).removeClass('buttonHover')}
			);
			submits.hover(
				function(){$(this).addClass('subButtonHover');},
				function(){$(this).removeClass('subButtonHover')}
			);
		}
	}
/* << */


/* >> Show/Hide Elements */
	ShowHideElements = {
		elements: [],
		callback: null,
		register: function(el, inner, callback){
			this.elements.push([el, inner]);
			if (callback && typeof callback == 'function') this.callback = callback;
			this.action(el, inner)
		},
		action: function(el, inner){
			var self = this;
			$(el).hover(
				function(){
					$(this).find(inner).css('display', 'block');
					if (self.callback){
						self.callback.call(self, $(this), $(inner));
					}
				},
				function(){$(this).find(inner).hide()}
			)
		}
	}
	
	/* >> special ShowHideElements callbacks */
		FormElementInfoPanelCorrection = $.extend(
			$.clone(LLObject),
			{
				create: function(){
					return LLObject.create.call(this);
				},
				correct: function(panel){
					var panel = panel.parent('.addInfoShell');
					var outer = panel.parents('.contColDes5');
					if (outer.size() > 0){
						var realHeight = outer.innerHeight();
						var scrollHeight = outer.get(0).scrollHeight;
						var currTopPos = panel.position().top;
						if (realHeight < scrollHeight){
							panel.css({'top': ((scrollHeight - realHeight) + 20) * -1});
						}else{
							panel.css({'top': null});
						}
					}
				}
			}
		);
	/* << */
/* << */


/* >> LivingLogic jsPager (requires jQuery 1.2.6 +) */
	JsPager = $.extend(
		$.clone(LLObject),
		{
			create: function(options){
				var o = LLObject.create.call(this);
				o.items = [];
				o.groupCnt = -1;
				o.pos = 0;
				o.data = null;
				o.countPerLine = 1;
				o.slideInterval = 0;
				o.interval = null;
				o.defaults = {
					target: null
				};
				if (options) $.extend(o.defaults, options);
				for (var k in o.defaults) o[k] = o.defaults[k];
				o.prepareContentArea();
				return o;
			},
			slide: function(pos){
				this.pos += pos;
				if (this.pos < 0){
					this.pos = 0;
				}else if (this.pos > this.groupCnt){
					if (this.interval){
						this.pos = 0;
					}else{
						this.pos = this.groupCnt;
					}
				}
				$(this.target).find('div.jsArea').scrollTo(this.props.width * this.pos, this.props.duration, {'axis': 'x'});
			},
			slideToPos: function(pos){
				var grpItems = this.target.find('.ms_scrollPane >div');
				if (pos > -1 && pos < grpItems.length){
					$(this.target).find('div.jsArea').scrollTo(grpItems.eq(pos), this.props.duration, {'axis': 'x'});
					this.pos = pos;
				}
			},
			prepareContentArea: function(){
				var t = this.target;
				t.data('jsPager', this);
				t.css({'overflow': 'auto'});
				var w = this.props.width;
				var h = this.props.height;
				var content = t.find('div.jsArea');
				content.css({
					'width': w,
					'height': h,
					'overflow': 'hidden'
				});
			},
			makeContentAreaItems: function(){
				var self = this;
				var t = self.target;
				var prefix = t.attr('id');
				var d = this.target.find('div.jsPagerItem');
				var grpShell = null;
				
				if (d && typeof d.length == 'number'){
					var groups = 1;
					if (d.length / self.countPerLine >= 1){
						groups = d.length / self.countPerLine;
						if (groups % 1 > 0) groups++;
					}
					var scrollPaneWidth = self.props.width * groups;
					var scrollPane = $('<div class="ms_scrollPane ms_scrollPane_' + prefix + '"></div>');
					scrollPane.css({'width': scrollPaneWidth, 'height': self.props.height});
					if (groups > 1){
						if (this.props.slideInterval && this.props.slideInterval > 0){
							var slideInterval = this.props.slideInterval;
						}else{
							var slideInterval = 0;
						}
						if (slideInterval == 0){
							t.find('.prev').bind('click', function(e){self.slide(-1)}).css({'cursor': 'pointer'}).end()
								.find('.next').css({'cursor': 'pointer'}).bind('click', function(e){self.slide(1)});
							t.find('div.jsPagerButtons').hover(
								function(){$(this).addClass('jspb_hover');},
								function(){$(this).removeClass('jspb_hover')}
							);
						}else{
							var iterval = slideInterval;
							t.find('table.jsPagerOuterTable td.button').hide();
							this.interval = setInterval(function(){self.slide(1)}, slideInterval);
						}
					}
					$(d).each(function(i){
						if (i % self.countPerLine == 0){
							self.groupCnt++;
							var hwAttrs = {'width': self.props.width, 'height': self.props.height};
							grpShell = $('<div id="ms_grpShell_' + prefix + '_' + self.groupCnt + '" class="ms_grpShell"></div>');
							grpShell.css(hwAttrs);
							var table = $('<table class="jsPagerContentTable" cellpadding="0" cellspacing="0" border="0"><tr></tr></table>');
							table.css(hwAttrs);
							grpShell.append(table);
						}
						var item = JsPagerItem.create(i, this, self);
						self.items.push(item);
						item = item.make();
						grpShell.find('table tr').append(item);
						scrollPane.append(grpShell);
					});
					t.find('.jsArea').append(scrollPane);
				}
				t.find('div.jsPagerItem').empty();
			}
		}
	);

	JsPagerItem = $.extend(
		$.clone(LLObject),
		{
			create: function(id, data, JsPager){
				var o = LLObject.create.call(this);
				o.slider = JsPager || null;
				o.id = id;
				o.data = data || null;
				o.itemWidth = JsPager.defaults.props.itemWidth || null;
				return o;
			},
			make: function(){
				var sliderId = this.slider.target.attr('id');
				var item = $(
					'<td>' + $(this.data).html() + '</td>'
				);
				item.css({'vertical-align': 'top', 'text-align': 'center'});
				return item;
			}
		}
	);
/* << */


/* >> Info tab img handler */
	ProdInfoImgHandler = $.extend(
		$.clone(LLObject),
		{
			create: function(options){
				var o = LLObject.create.call(this);
				o.defaults = {
					target: null
				};
				if (options) $.extend(o.defaults, options);
				for (var k in o.defaults) o[k] = o.defaults[k];
				return o;
			},
			handleAjax: function(){
				var url = window.location.href;
				var urlParamText = url.substring(url.search(/\?/) + 1).split('&');
				var params = {};
				for (var i = 0; i < urlParamText.length; ++i) {
					var item = urlParamText[i].split('=');
					params[item[0]] = item[1];
				}
				var self = this;
				if (this.target && params.auf_id){
					$.ajax({
						type: "get",
						url: window.location.protocol + "//" + window.location.host + "/backend/image4article",
						data: {'auf_id': params.auf_id},
						success: function(data, msg){
							self.target.append('<div class="prodInfoImgDes1"><div class="prodInfoImgDes2"></div></div>');
							self.target.find('div.prodInfoImgDes2').html(data);
						},
						error: function(req, status, error){
						}
					});
				}
			}
		}
	);
/* << */


/* >> Shipping addressbook */
	ShippingAddressbook = $.extend(
		$.clone(LLObject),
		{
			create: function(outerelm){
				var o = LLObject.create.call(this);
				this.bindSearchButton(outerelm);
				this.clearFields();
				return o;
			},
			bindSearchButton: function(outerelm){
				var self = this;
				$('#shipAdrSearch a').bind('click', function(e){
					e.preventDefault();
					e.stopPropagation();
					var pos = $(this).parent().position();
					self.showBook(Math.round(pos.left), Math.round(pos.top), outerelm);
				});
			},
			clearFields: function(){
				if ($('div.addressStandardModeInner').find('div.formError').length == 0 && $('div.addressStandardModeInner').find('div.formGlobalError ul').length == 0){
					$('div.shippingAddessItemsShell form :input').each(function(i){
						var type = $(this).attr('type');
						var name = $(this).attr('name');
						if (type != "submit" && type != "hidden" && type != "checkbox"){
							$(this).val('');
						}
					});
				}
				if ($('div.stickerAdrForm').length > 0){
					this.removeStickerCountryEntries();
				}
			},
			removeStickerCountryEntries: function(){
				var opt = $('div.stickerAdrForm').find('select[name="shipLand"]').find('option');
				var de = "1410";
				opt.each(function(i){
					var val = $(this).attr('value');
					if (!(val == de) && val.length > 0){
						$(this).remove();
					}
				});
			},
			rowHoverEffect: function(){
				$('#shipAddressBook div.shipLayerShell table tr.adrItem').hover(
					function(){$(this).addClass('rowHover');},
					function(){$(this).removeClass('rowHover');}
				);
			},
			selectRow: function(row){
				$('#shipAddressBook div.shipLayerShell table tr.adrItem').removeClass('rowSelect');
				if (row){
					$(row).addClass('rowSelect');
				}
			},
			showBook: function(posx, posy, outerelm){
				var self = this;
				var adrBook = $('#shipAddressBook');
				if ($('div.deliveryAdrForm').size() > 0){
					adrBook.addClass('deliveryAddressBook');
				}
				this.rowHoverEffect();
				var posx = (posx - 9);
				adrBook.css({'position': 'absolute', 'left': posx + 'px', 'top': posy + 'px', 'z-index': '31'});
				adrBook.show();
				self.selectRow(null);
				$('#shipAddressBook div.shipLayerShell table tr.adrItem').bind('click', function(e){
					self.selectRow($(this));
				});
				$('#adrBookSubButton a').bind('click', function(e){
					e.preventDefault();
					e.stopPropagation();
					self.formHandler(outerelm);
				});
				$('#adrBookResetButton a').bind('click', function(e){
					e.preventDefault();
					e.stopPropagation();
					$('#shipAddressBook').hide();
				});
			},
			formHandler: function(outerelm){
				var outerFormShell = 'div.shippingAddessItemsShell form';
				if (outerelm){
					outerFormShell = outerelm;
				}
				var selectedRow = $('#shipAddressBook div.shipLayerShell table tr.rowSelect');
				if (selectedRow.length > 0){
					var spans = selectedRow.find('span');
					var fields = {};
					$(spans).each(function(i){
						var name = $(this).attr('class').split('shipLayerForm_')[1];
						var value = $(this).text();
						fields[name] = value;
					});
					$(outerFormShell + ' :input').each(function(i){
						var type = $(this).attr('type');
						if (type != "submit" && type != "hidden" && type != "checkbox"){
							var name = $(this).attr('name');
							$(this).val('');
							$(this).val(fields[name]);
						}
					});
				}
				$('#shipAddressBook').hide();
				
			}
		}
	);
/* << */


/* >> LivingLogic jsScroller (requires jQuery 1.2.6 +) */
	ScrollBar = $.extend(
		$.clone(LLObject),
		{
			currentScrollPos: 0,
			oldScrollPos: 0,
			scrollBarDim: null,
			mousePosX: 0,
			mousePosY: 0,
			realStepSize: 1,
			afterInitCallback: null,
			defaults: {
				orientation: 'y',
				scrollerWidth: 10,
				scrollerHeight: 10,
				arrowWidth: 10,
				arrowHeight: 10,
				arrowMoveIn: 0,
				sliderCapsPadding: 0,
				stepSize: 1
			},
			create: function(opts){
				var o = LLObject.create.call(this);
				o.target = opts.target || null;
				if (opts.afterInitCallback && typeof opts.afterInitCallback == 'function'){
					o.afterInitCallback = opts.afterInitCallback;
				}
				o.defaults = $.extend(o.defaults, opts);
				o.init();
				return o;
			},
			init: function(){
				var target = this.target;
				if (this.defaults.orientation == 'y'){
					var hasOverflow = target.get(0).scrollHeight > target.height();
				}else{
					var hasOverflow = target.get(0).scrollWidth > target.width();
				}
				var defs = this.defaults;
				if (hasOverflow){
					this.prepareTargets();
					var scrollBarOuter = this.getScrollBarOuter();
					var slider = scrollBarOuter.find('.sliderOuter');
					if (defs.orientation == 'y'){
						var arrowDim = defs.arrowHeight;
						var scrollBarDim = this.scrollBarDim = scrollBarOuter.height() - defs.arrowHeight * 2 + defs.arrowMoveIn;
						var scrollHeight = target.get(0).scrollHeight;
						var sliderDim = scrollBarOuter.height() * scrollBarDim / scrollHeight;
						var css = {'top': arrowDim - defs.arrowMoveIn}
						var innerCss = {'height': sliderDim - defs.sliderCapsPadding};
					}else{
						var arrowDim = defs.arrowWidth;
						var scrollBarDim = this.scrollBarDim = scrollBarOuter.width() - defs.arrowWidth * 2 + defs.arrowMoveIn;
						var scrollWidth = target.get(0).scrollWidth;
						var sliderDim = scrollBarOuter.width() * scrollBarDim / scrollWidth;
						var css = {'left': arrowDim - defs.arrowMoveIn};
						var innerCss = {'width': sliderDim - defs.sliderCapsPadding};
					}
					slider.css(css);
					slider.find('.sliderInner2').css(innerCss);
					this.bindElements();
				}
				var cb = defs.afterInitCallback;
				if (cb) cb.call(this);
			},
			getScrollBarOuter: function(){
				return this.target.parent('.scrollBarScrollPane');
			},
			getSlider: function(){
				var outer = this.getScrollBarOuter();
				return outer.find('.sliderOuter');
			},
			prepareTargets: function(){
				if (this.target && this.target.size() > 0){
					var target = this.target;
					var defs = this.defaults;
					var outer = $(
						'<div class="scrollBarScrollPane"></div>'
					);
					var w = target.width();
					var h = target.height();
					outer.css({'width': w, 'height': h});
					if (defs.orientation == 'y'){
						target.width(w - defs.scrollerWidth);
					}else if (defs.orientation == 'x'){
						target.height(h - defs.scrollerHeight);
					}
					target.wrap(outer);
					target.parent('.scrollBarScrollPane').append(this.makeBar(w, h));
				}
			},
			bindElements: function(){
				var defs = this.defaults;
				var scrollPane = this.getScrollBarOuter();
				var self = this;
				scrollPane.find('.arrow').each(function(i){
					var arrow = $(this);
					if (arrow.hasClass('arrow_top')){
						arrow.bind('click', function(e){
							self.adaptSliderByArrowClick('top');
						});
					}else if(arrow.hasClass('arrow_bottom')){
						arrow.bind('click', function(e){
							self.adaptSliderByArrowClick('bottom');
						});
					}else if(arrow.hasClass('arrow_left')){
						arrow.bind('click', function(e){
							self.adaptSliderByArrowClick('left');
						});
					}else if(arrow.hasClass('arrow_right')){
						arrow.bind('click', function(e){
							self.adaptSliderByArrowClick('right');
						});
					}
				});
				scrollPane.find('.sliderOuter').bind('mousedown', function(e){
					self.mousePosX = e.pageX;
					self.mousePosY = e.pageY;
					self.realStepSize = defs.stepSize;
					self.oldScrollPos = self.currentScrollPos;
					$('body').bind('mousemove', function(e){
						self.adaptSliderByMouseMove(self.getSlider(), e);
					}).bind('mouseup', function(e){
						self.mousePosX = 0;
						self.mousePosY = 0;
						self.oldScrollPos = self.currentScrollPos;
						defs.stepSize = self.realStepSize;
						$('body').unbind('mousemove');
					});
				});
			},
			adaptSliderByMouseMove: function(slider, e){
				var x = e.pageX - this.mousePosX;
				var y = e.pageY - this.mousePosY;
				this.scrollTo(x, y, slider);
			},
			scrollTo: function(x, y, slider){
				var x = isNaN(parseInt(x)) ? 0 : parseInt(x);
				var y = isNaN(parseInt(y)) ? 0 : parseInt(y);
				var defs = this.defaults;
				var scrollPane = this.target;
				var direct = false;
				if (!slider){
					var slider = this.getSlider();
					direct = true;
					this.currentScrollPos = this.oldScrollPos = 0;
				}
				if (defs.orientation == 'y'){
					var value = scrollPane.scrollTop();
					var viewLen = this.getScrollBarOuter().height();
					var ovLen = scrollPane.get(0).scrollHeight;
					var maxScrollLen = ovLen - viewLen;
					if (this.oldScrollPos + y >= Math.floor((ovLen - viewLen) / (ovLen / this.scrollBarDim))){
						slider.css({'top': this.scrollBarDim - (slider.height() + defs.sliderCapsPadding) + defs.arrowHeight});
						scrollPane.scrollTop(ovLen - viewLen);
						if (direct) this.currentScrollPos = this.oldScrollPos = this.scrollBarDim - (slider.height() + defs.sliderCapsPadding) + defs.arrowWidth;
					}else if (this.oldScrollPos + y <= 0){
						slider.css({'top': defs.arrowHeight - defs.arrowMoveIn});
						scrollPane.scrollTop(0);
						if (direct) this.currentScrollPos = this.oldScrollPos = 0;
					}else{
						this.currentScrollPos = this.oldScrollPos + y;
						var nextPos = this.currentScrollPos + defs.arrowHeight - defs.arrowMoveIn;
						slider.css({'top': nextPos});
						scrollPane.scrollTop(this.currentScrollPos * ovLen / this.scrollBarDim);
					}
				}else{
					var value = scrollPane.scrollLeft();
					var viewLen = this.getScrollBarOuter().width();
					var ovLen = scrollPane.get(0).scrollWidth;
					var maxScrollLen = ovLen - viewLen;
					if (this.oldScrollPos + x >= Math.floor((ovLen - viewLen) / (ovLen / this.scrollBarDim))){
						slider.css({'left': this.scrollBarDim - (slider.width() + defs.sliderCapsPadding) + defs.arrowWidth});
						scrollPane.scrollLeft(ovLen - viewLen);
						if (direct) this.currentScrollPos = this.oldScrollPos = this.scrollBarDim - (slider.width() + defs.sliderCapsPadding) + defs.arrowWidth;
					}else if (this.oldScrollPos + x <= 0){
						slider.css({'left': defs.arrowWidth - defs.arrowMoveIn});
						scrollPane.scrollLeft(0);
						if (direct) this.currentScrollPos = this.oldScrollPos = 0;
					}else{
						this.currentScrollPos = this.oldScrollPos + x;
						var nextPos = this.currentScrollPos + defs.arrowWidth - defs.arrowMoveIn;
						slider.css({'left': nextPos});
						scrollPane.scrollLeft(this.currentScrollPos * ovLen / this.scrollBarDim);
					}
				}
			},
			adaptSliderByArrowClick: function(mode){
				var defs = this.defaults;
				var scrollPane = this.target;
				var slider = this.getSlider();
				if (mode == 'top' || mode == 'bottom'){
					var value = scrollPane.scrollTop();
					var viewLen = this.getScrollBarOuter().height();
					var ovLen = scrollPane.get(0).scrollHeight;
				}else{
					var value = scrollPane.scrollLeft();
					var viewLen = this.getScrollBarOuter().width();
					var ovLen = scrollPane.get(0).scrollWidth;
				}
				var maxScrollLen = ovLen - viewLen;
				if (mode == 'top'){
					if (value > 0){
						this.currentScrollPos = Math.max(0, this.currentScrollPos - defs.stepSize);
						var nextPos = this.currentScrollPos + defs.arrowHeight - defs.arrowMoveIn;
						slider.css({'top': nextPos});
						scrollPane.scrollTop(this.currentScrollPos * ovLen / this.scrollBarDim);
					}
				}else if(mode == 'bottom'){
					if(value < maxScrollLen){
						if (value + ovLen * defs.stepSize / this.scrollBarDim < maxScrollLen){
							this.currentScrollPos += defs.stepSize;
							var nextPos = this.currentScrollPos + defs.arrowHeight - defs.arrowMoveIn;
							slider.css({'top': nextPos});
							scrollPane.scrollTop(this.currentScrollPos * ovLen / this.scrollBarDim);
						}else{
							this.currentScrollPos = Math.floor((ovLen - viewLen) / (ovLen / this.scrollBarDim));
							slider.css({'top': this.scrollBarDim - (slider.height() + defs.sliderCapsPadding) + defs.arrowHeight});
							scrollPane.scrollTop(ovLen - viewLen);
						}
					}
				}else if(mode == 'left'){
					if (value > 0){
						this.currentScrollPos = Math.max(0, this.currentScrollPos - defs.stepSize);
						var nextPos = this.currentScrollPos + defs.arrowWidth - defs.arrowMoveIn;
						slider.css({'left': nextPos});
						scrollPane.scrollLeft(this.currentScrollPos * ovLen / this.scrollBarDim);
					}
				}else if(mode == 'right'){
					if(value < maxScrollLen){
						if (value + ovLen * defs.stepSize / this.scrollBarDim < maxScrollLen){
							this.currentScrollPos += defs.stepSize;
							var nextPos = this.currentScrollPos + defs.arrowWidth - defs.arrowMoveIn;
							slider.css({'left': nextPos});
							scrollPane.scrollLeft(this.currentScrollPos * ovLen / this.scrollBarDim);
						}else{
							this.currentScrollPos = Math.floor((ovLen - viewLen) / (ovLen / this.scrollBarDim));
							slider.css({'left': this.scrollBarDim - (slider.width() + defs.sliderCapsPadding) + defs.arrowWidth});
							scrollPane.scrollLeft(ovLen - viewLen);
						}
					}
				}
			},
			makeBar: function(sw, sh){
				var defs = this.defaults;
				var trail = $(
					'<div class="trail trail_' + defs.orientation + '">' +
					'</div>'
				);
				var w = defs.scrollerWidth;
				var h = defs.scrollerHeight;
				var aw = defs.arrowWidth;
				var ah = defs.arrowHeight;
				if (defs.orientation == 'y'){
					trail.css({'position': 'absolute', 'right': 0, 'top': 0, 'height': sh, 'width': w});
					var arrow1 = $(
						'<div class="arrow arrow_' + defs.orientation + ' arrow_top" unselectable="on"></div>'
					);
					var arrow2 = $(
						'<div class="arrow arrow_' + defs.orientation + ' arrow_bottom" unselectable="on"></div>'
					);
					arrow1.css({'width': w, 'height': ah});
					arrow2.css({'width': w, 'height': ah, 'position': 'absolute', 'bottom': 0});
				}else{
					trail.css({'position': 'absolute', 'left': 0, 'bottom': 0, 'width': sw, 'height': h});
					var arrow1 = $(
						'<div class="arrow arrow_' + defs.orientation + ' arrow_left" unselectable="on"></div>'
					);
					var arrow2 = $(
						'<div class="arrow arrow_' + defs.orientation + ' arrow_right" unselectable="on"></div>'
					);
					arrow1.css({'height': h, 'width': aw});
					arrow2.css({'height': h, 'width': aw, 'position': 'absolute', 'right': 0, 'top': 0});
				}
				trail.append(arrow1);
				trail.append(arrow2);
				trail.append(this.makeSlider());
				return trail;
			},
			makeSlider: function(){
				var defs = this.defaults;
				var slider = $(
					'<div class="sliderOuter" unselectable="on">' +
						'<div class="sliderInner1" unselectable="on">' +
							'<div class="sliderInner2" unselectable="on">' +
							'</div>' +
						'</div>' +
					'</div>'
				);
				if (defs.orientation == 'y'){
					slider.css({'position': 'absolute', 'left': 0});
					slider.addClass('slider_top');
					slider.find('.sliderInner1').addClass('slider_bottom');
					slider.find('.sliderInner2').addClass('slider_' + defs.orientation + '_inner2')
						.css({'width': defs.scrollerWidth});
				}else{
					slider.css({'position': 'absolute', 'top': 0});
					slider.addClass('slider_left');
					slider.find('.sliderInner1').addClass('slider_right');
					slider.find('.sliderInner2').addClass('slider_' + defs.orientation + '_inner2')
						.css({'height': defs.scrollerHeight});
				}
				return slider;
			}
		}
	);
/* << */



/* >> classic mode print product configurator */
	/* >>  classic mode configurator*/
		ClassisModeConfigurator = $.extend(
			$.clone(SlotMachine),
			{
				init: function(opts){
					if (opts){
						this.opts = opts;
						this.makeShell(opts.target);
						var urlParams = this.urlParams = this.getURLParams();
						if (!urlParams.ovn) urlParams.ovn = 'false';
						this.url = AjaxURLManager.getUrlWithKey('classicconfigarticle', urlParams);
						if (this.urlParams.loadPos) this.urlParams.loadPos = null;
						var cb = opts.onAfterSlotCatch;
						if (cb && typeof cb == 'function') this.onAfterSlotCatch = cb;
						var cbdr = opts.onDataRequest;
						if (cbdr && typeof cbdr == 'function') this.onDataRequest = cbdr;
						var cbdrs = opts.onDataRequestSuccess;
						if (cbdrs && typeof cbdrs == 'function') this.onDataRequestSuccess = cbdrs;
						if (this.url){
							var self = this;
							$.getJSON(this.url, function(data, textStatus){
								var d = self.data = data;
								if (d.type == 'SlotMachineData'){
									$(d.slots).each(function(i){
										if (this.type == 'SlotMachineSlot'){
											var slot = ClassicModeSlot.create(this.title, this.currentItem);
											slot.id = 'slot_' + i;
											slot.itemId = i;
											slot.data = this;
											slot.width = this.width;
											$(this.items).each(function(i){
												if (this.type == 'SlotMachineSlotItem'){
													var slotItem = ClassicModeSlotItem.create(this.title, this.value);
													slotItem.id = slot.id + '_slotItem_' + i;
													slotItem.itemCnt = i;
													slotItem.data = this;
													slotItem.slot = slot;
													slotItem.width = slot.width;
													slot.appendItem(slotItem);
												}
											});
											self.appendSlot(slot);
										}
									});
								}
								// call init callback if exists
								var initCb = opts.onAfterInit;
								if (initCb && typeof initCb == 'function'){
									initCb.call(self, self.data);
								}
								if (self.onDataRequestSuccess) self.onDataRequestSuccess.call(self, null, d);
							});
						}
					}
				},
				makeShell: function(target){
					var shell = $(
						'<div id="classicModeOuter">' +
						'</div>'
					);
					target.append(shell);
				},
				setActionKeeper: function(options){
				},
				clearActionKeeper: function(){
				},
				verifyData: function(slot){
					var slot = slot || null;
					var self = this;
					var oldData = this.data;
					if (slot) this.data.changedSlot = slot.itemId;
					var cbdr = this.onDataRequest;
					if (cbdr) cbdr.call(this, self, this.data);
					var url = AjaxURLManager.getUrlWithKey('configarticle');
					//alter data and send it to cherrypy
					for (var i in this.data.slots){
						this.data.slots[i].currentItem = this.slots[i].currentItem;
					}
					$.ajax({
						type: 'post',
						url: url,
						data: {'content': encodeURIComponent($.toJson(ClassisModeConfigurator))},
						success: function(data, msg){self.verifyDataRequestSuccess(data, msg, slot);},
						error: function(req, status, error){self.verifyDataRequestError(req, status, error, slot);}
					});
				},
				verifyDataRequestSuccess: function(data, msg, slot){
					//eval('var data = ' + data);
					this.data = data;
					if (this.urlParams && this.urlParams.auf_id) this.urlParams.auf_id = data.auf_id;
					if (this.onDataRequestSuccess) this.onDataRequestSuccess.call(this, slot, data);
					this.slotUpdateCheck();
				},
				verifyDataRequestError: function(req, status, error, slot){
					/* todo: .... */
				}
			}
		);
	/* << */

	/* >> classic mode slot (inherit SlotMachineSlot)*/
		ClassicModeSlot = $.extend(
			$.clone(SlotMachineSlot),
			{
				create: function(title, currentItem){
					var o = SlotMachineSlot.create.call(this);
					return o;
				},
				makeSlotTitle: function(){
					/* todo: .... */
				},
				makeSlotLayout: function(){
					/* todo: .... */
				},
				make: function(target){
					if (target){
						/* todo: ... */
					}
				}
			}
		);
	/* << */


	/* >> classic mode item (inherit SlotMachineSlotItem)*/
		ClassicModeSlotItem = $.extend(
			$.clone(SlotMachineSlotItem),
			{
				create: function(title, value){
					var o = SlotMachineSlotItem.create.call(this);
					return o;
				},
				makeItemLayout: function(){
					/* todo: ... */
				},
				make: function(target){
					if (target){
						/* todo: ... */
					}
				}
			}
		);
	/* << */
/* << */


/* >> product search proposals */
	ProductSearchProposals = $.extend(
		$.clone(LLObject),
		{
			create: function(opts){
				var o = LLObject.create.call(this), sppShell;
				o.keyCnt = 0;
				o.proposalItems = {
					'current': 0,
					'items': null
				};
				o.defaults = {
					searchOuterId: $('#productSearch'),
					searchFormId:  $('#quickSearch'),
					searchPhraseProposals: $('#searchPhraseProposals'),
					proposalsTarget: $('#productSearchFieldImage'),
					pagerTopTarget: $('#productPager1'),
					pagerBottomTarget: $('#productPager2'),
					searchResultTarget: $('#productSearchProposalsTarget'),
					facetPanelsTarget: $('#facetPanelsTarget'),
					positionAbsolute: false,
					relativeTargetPosition: null
				};
				if (opts && Utils.isObject(opts)){
					$.extend(o.defaults, opts)
				}
				o.currentFacets = null;
				o.data = null;
				o.startPhrase = '';
				o.originalTarget = null;
				if (o.defaults.searchPhraseProposals.length === 0){
					sppShell = o.makeSearchPhraseProposalPaneLayout().hide();
					if (o.defaults.positionAbsolute){
						$('body').append(sppShell);
					}else{
						o.defaults.proposalsTarget.append(sppShell);
					}
					o.defaults.searchPhraseProposals = sppShell;
				}
				return o;
			},
			makeSearchPhraseProposalPaneLayout: function(){
				var opts = this.defaults, lay = $(
					'<div id="searchPhraseProposals">' +
						'<div id="searchPhraseProposalsPane">' +
							'<div class="title"></div>' +
							'<div id="searchPhraseProposalsScrollPane"></div>' +
						'</div>' +
					'</div>'
				);
				return lay;
			},
			makeProductProposalPaneLayout: function(){
				var lay = $(
					'<div id="productSearchProposals">' +
						'<div id="productSearchProposalsPane">' +
							'<div class="title">' +
								'<div class="viewport">' +
									'<div class="searchInfo"></div>' +
								'</div>' +
								'<div class="titleInner"></div>' +
							'</div>' +
							'<div id="productSearchProposalsScrollPane"></div>' +
						'</div>' +
					'</div>'
				);
				return lay;
			},
			makeSearchSummaryLayout: function(){
				var d = this.data, numFound, start, rows, overall, current;
				numFound = d.response.numFound;
				start = d.responseHeader.params.start;
				rows = d.responseHeader.params.rows;
				current = start / rows + 1;
				overall = numFound % rows > 0 ? Math.floor(numFound / rows) + 1 : numFound / rows;
				return $(
					'<div class="outer">' +
						'<span class="prompt">' + $.lang('searchInfoPrompt1') + '</span>' +
						'<span class="current">' + current + '</span>' +
						'<span class="prompt">' + $.lang('searchInfoPrompt2') + '</span>' +
						'<span class="overall">' + overall + '</span>' +
					'</div>'
				);
			},
			getQueryParams: function(type, phrase, addParams){
				var stdParams = {
					'q': '',
					'start': 0,
					'rows': 0,
					'indent': 'on',
					'qt': 'dismax',
					'spellcheck': false,
					'wt': 'json',
					'spellcheck.extendedResults': true,
					'spellcheck.collate': true,
					'facet': true,
					'facet.mincount': 1,
					'keyCnt': this.keyCnt
				},
				searchPhraseParamExt = {
					'facet.limit': 10,
					'facet.prefix': ''
				},
				searchPhraseFacets = ['textpropose'],
				productSearchParamExt = {
					'hl': 'false',
					'hl.fl': 'textpropose'
				},
				productSearchFacets = [
					'fo_bezeichnung',
					'wgl_bezeichnung',
					'gr_bezeichnung',
					'wv_bezeichnung',
					'art_fenster_text',
					'wgl_bezeichnung_detail'
				],
				coreParams, facetFields, q;

				if (addParams && typeof addParams === 'object'){
					if (addParams.start || addParams.start === 0){
						stdParams = $.extend(stdParams, {'start': addParams.start});
						delete addParams.start;
					}
					addParams = Utils.getUrlParamsFromJson(addParams);
					addParams = '&' + addParams.substring(1, addParams.length);
				}else{
					addParams = '';
				}
				coreParams = null;
				facetFields = null;
				if (type === 'searchProposals'){
					facetFields = searchPhraseFacets;
					q = $.trim(phrase).split(' ');
					if (q[0] !== '' && q[0] !== ' '){
						if (q.length === 1){
							searchPhraseParamExt['facet.prefix'] = q[0].toLowerCase();
							searchPhraseParamExt['q.alt'] = '*:*';
						}else{
							if (q.length > 1 && q[q.length -1] !== ' '){
								stdParams.q = q.slice(0, q.length -1).join(' ');
								searchPhraseParamExt['facet.prefix'] = q[q.length -1].toLowerCase();
							}
						}
						coreParams = $.extend(stdParams, searchPhraseParamExt);
					}
				}else if (type === 'productProposals'){
					facetFields = productSearchFacets;
					stdParams.rows = 10;
					stdParams.q = phrase;
					coreParams = $.extend(stdParams, productSearchParamExt);
				}
				if (coreParams){
					coreParams = Utils.getUrlParamsFromJson(coreParams);
					// extend core params cgi string with facet fields.
					$(facetFields).each(function(i){
						coreParams += '&facet.field=' + this;
					});
					return coreParams + addParams;
				}
				return null;
			},
			getFacetParamsAsJson: function(facet){
				if (typeof facet === 'object'){
					this.currentFacets = $.extend(this.currentFacets, facet);
					return this.currentFacets;
				}else if (typeof facet === 'string'){
					delete this.currentFacets[facet];
				}
				return this.currentFacets;
			},
			handleSearchPhraseProposals: function(phrase){
				var params = this.getQueryParams('searchProposals', phrase), opts = this.defaults,
						url, self, proposals, proposal, i, count, item, searchTextSnippet, offset, pos;
				if (opts.positionAbsolute){
					$('body').append(opts.searchPhraseProposals);
					offset = opts.proposalsTarget.offset();
					opts.searchPhraseProposals.css({
						left: offset.left,
						top: offset.top,
						zIndex: 1000000
					});
					if (opts.relativeTargetPosition){
						opts.searchPhraseProposals.css({
							left: offset.left + opts.relativeTargetPosition.left,
							top: offset.top + opts.relativeTargetPosition.top
						});
					}
				}else{
					opts.searchPhraseProposals.removeAttr('style');
					opts.proposalsTarget.append(opts.searchPhraseProposals);
				}
				if (params){
					url = AjaxURLManager.getUrlWithKey('search').replace('/backend', '') + params;
					this.proposalItems.current = 0;
					this.proposalItems.items = [];
					this.proposalItems.items.push(opts.proposalsTarget.find(':input'));
					self = this;
					$.getJSON(url, function(data, textStatus){
						if (self.keyCnt === data.responseHeader.params.keyCnt * 1){
							self.data = data;
							opts.searchPhraseProposals.find('.title').text($.lang('searchPhraseProposalTitle'));
							$('#searchPhraseProposalsScrollPane').empty();
							if (data.facet_counts.facet_fields.textpropose.length > 0){
								proposals = data.facet_counts.facet_fields.textpropose;
								searchTextSnippet = '';
								if (phrase.search(' ') > -1){
									searchTextSnippet = phrase.substring(0, phrase.lastIndexOf(' ')) + ' ';
								}
								for (i = 0; i < proposals.length; i+=1){
									if (i % 2 === 1){continue;}
									proposal = searchTextSnippet + proposals[i];
									count = proposals[i+1];
									item = SearchPhraseProposalsItem.create(proposal, count, this.phrase);
									item.id = i / 2;
									item.parent = self;
									item.make();
									self.proposalItems.items.push(item);
								}
								opts.searchPhraseProposals.show('fast');
							}else{
								opts.searchPhraseProposals.hide('fast');
								self.proposalItems.current = 0;
								self.proposalItems.items = [];
							}
							opts.searchOuterId.unbind('keydown').bind('keydown', function(e){
								self.handleKeyPress(e);
							});
							opts.searchOuterId.find('.submitButton').bind('click', function(e){
								self.fire();
							});
						}
					});
				}else{
					opts.searchPhraseProposals.hide('fast');
					$('#searchPhraseProposalsScrollPane').empty();
				}
			},
			handleProductProposals: function(phrase, params){
				var opts = this.defaults, url, self, docs, item, p, facetParams, realParams,
						start, rows, numFound, currentPage, pObj;
				if (phrase && phrase !== ''){
					if (! params){params = this.getQueryParams('productProposals', phrase);}
					if (params){
						url = AjaxURLManager.getUrlWithKey('search').replace('/backend', '') + params;
						this.proposalItems.current = 0;
						this.proposalItems.items = [];
						this.proposalItems.items.push($('#productSearchFieldImage').find(':input'));
						self = this;
						$.getJSON(url, function(data, textStatus){
							self.data = data;
							self.makeFacetPanels(opts.facetPanelsTarget, phrase);
							$('#productSearchProposals').find('.titleInner').html($.lang('productProposalTitle'));
							$('#productSearchProposals').find('.title .searchInfo').html(self.makeSearchSummaryLayout());
							$('#productSearchProposalsScrollPane').empty();
							if (data.response.docs.length > 0){
								docs = data.response.docs;
								$(docs).each(function(i){
									item = ProductProposalsItem.create();
									item.id = i;
									item.parent = self;
									item.data = this;
									item.make();
									self.proposalItems.items.push(item);
								});
							}
							if (opts.pagerTopTarget){
								Pager1 = PagerElement.create({
									target: opts.pagerTopTarget,
									frameWidth: 10,
									callback: function(page){
										p = page;
										facetParams = self.getFacetParamsAsJson();
										realParams = {'fq': []};
										for (var k in facetParams){
											realParams.fq.push([k,':"',facetParams[k],'"'].join(''));
										}
										realParams = $.extend(realParams, {'start': (p-1) * data.responseHeader.params.rows});
										params = self.getQueryParams('productProposals', phrase, realParams);
										self.handleProductProposals(phrase, params);
									}
								});
							}
							if (opts.pagerBottomTarget){
								Pager2 = PagerElement.create({
									target: opts.pagerBottomTarget,
									frameWidth: 10,
									callback: function(page){
										p = page;
										facetParams = self.getFacetParamsAsJson();
										realParams = {'fq': []};
										for (var m in facetParams){
											realParams.fq.push([m,':"',facetParams[m],'"'].join(''));
										}
										realParams = $.extend(realParams, {'start': (p-1) * data.responseHeader.params.rows});
										params = self.getQueryParams('productProposals', phrase, realParams);
										self.handleProductProposals(phrase, params);
									}
								});
							}
							start = data.response.start;
							rows = data.responseHeader.params.rows;
							numFound = data.response.numFound;
							currentPage = start / rows + 1;
							pObj = {
								pager:{
									currentPage: currentPage,
									overall: numFound,
									offset: rows
								}
							};
							if (opts.pagerTopTarget){Pager1.update(pObj);}
							if (opts.pagerBottomTarget){Pager2.update(pObj);}
						});
					}else{
						$('#productSearchProposalsScrollPane').empty();
					}
				}
			},
			removeProposalsHoverEffect: function(){
				$(this.proposalItems.items).each(function(i){
					if (i > 0){
						this.jqElm.removeClass('searchProposalItemHover');
					}
				});
			},
			completePhrase: function(){
				var opts = this.defaults, field = opts.proposalsTarget.find(':input'),
						currentPhrase = $.trim(field.val()),
						proposal = this.proposalItems.items[this.proposalItems.current];
				field.val(proposal.proposal);
			},
			completePhraseAndSetFocusToInput: function(proposal){
				var opts = this.defaults, field = opts.proposalsTarget.find(':input'), currentPhrase;
				if (!proposal){
							currentPhrase = $.trim(field.val());
							proposal = this.proposalItems.items[this.proposalItems.current];
					if (typeof proposal !== 'undefined'){
						field.val(proposal.proposal);
					}
				}else{
					field.val(proposal);
					field.focus();
				}
				this.proposalItems.current = 0;
				opts.searchPhraseProposals.hide('fast');
			},
			fire: function(){
				var opts = this.defaults, field = opts.proposalsTarget.find(':input'),
						action = opts.searchFormId.attr('action');
				if (window.location.href.search(action) === -1){
					window.location.href = action + Utils.getUrlParamsFromJson({'phrase': $.trim(field.val())});
				}else{
					this.handleProductProposals($.trim(field.val()));
				}
			},
			handleKeyPress: function(e){
				e.stopPropagation();
				var pItems = this.proposalItems, current, opts = this.defaults;
				if (e.keyCode === 13){ // if return key
					this.completePhraseAndSetFocusToInput();
					opts.searchPhraseProposals.hide('fast');
					this.fire();
				}else if (e.keyCode === 38 || e.keyCode === 40){ // if up or down cursor key
					this.removeProposalsHoverEffect();
					if (e.keyCode === 38){
						if (pItems.current > 0){
							current = pItems.current -= 1;
						}else{
							current = pItems.items.length -1;
							pItems.current = current;
						}
					}else{
						if (pItems.current < pItems.items.length -1){
							current = pItems.current +=1;
						}else{
							current = 0;
							pItems.current = current;
						}
					}
					if (current > 0){
						pItems.items[current].jqElm.addClass('searchProposalItemHover');
					}else{
						pItems.items[0].focus();
					}
					this.completePhrase();
				}else if(e.keyCode === 27){ // if escape key
					opts.searchPhraseProposals.hide('fast');
				}else{
				}
			},
			make: function(){
				var self = this, opts = this.defaults,
						field = opts.proposalsTarget.find(':input');
				field.focus(function(e){
					self.removeProposalsHoverEffect();
					self.proposalItems.current = 0;
				});
				this.originalTarget = field;
				field.attr({'autocomplete': 'off'});
				opts.searchFormId.bind('submit', function(e){
						e.preventDefault();
						e.stopPropagation();
				});
				field.bind('keyup', function(e){
					self.keyCnt +=1;
					if (e.keyCode === 8 || e.keyCode > 45 || e.keyCode === 0){
						field = $(this);
						if (field.val().charCodeAt(field.val().length - 1) !== 32){
							self.handleSearchPhraseProposals(field.val());
						}
					}
				});
			},
			makeDetail: function(target){
				var phrase = null, params = Utils.getUrlParamsAsJson();
				if (params && params.phrase !== 'undefined'){
					 phrase = params.phrase;
				}
				target.append(this.makeProductProposalPaneLayout());
				this.handleProductProposals(phrase);
			},
			makeFacetPanels: function(target, phrase){
				var d = this.data, cnt = 0, iCnt = 0, searchFacet = [], facets, facet, searchFacets,
						k, panel, i, title, count, item, j;
				target.empty();
				searchFacets = (d.responseHeader && d.responseHeader.params.fq) ? d.responseHeader.params.fq : [];
				if (searchFacets){
					if (typeof searchFacets !== 'string'){
						for (i = 0; i < searchFacets.length; i+=1){
							searchFacet.push(searchFacets[i].split(':')[0]);
						}
					}else{
						searchFacet.push(searchFacets.split(':')[0]);
					}
				}
				facets = d.facet_counts.facet_fields;
				for (k in facets){
					if (k !== 'art_fenster_text'){
						facet = facets[k];
						panel = ProductFacetPanel.create();
						panel.target = target;
						panel.parent = this;
						panel.id = cnt;
						panel.domId = 'facetPanel_' + cnt;
						panel.title = k;
						if ($.inArray(k, searchFacet) > -1){
							item = ProductFacetPanelBackItem.create();
							item.id = -1;
							item.parent = panel;
							item.phrase = phrase;
							item.domId = 'facetPanelItem_' + cnt + '-1';
							item.title = $.lang('searchFacetPanelItemBack');
							item.count = count;
							item.attributeName = k;
							panel.items.push(item);
						}
						for (j = 0; j < facet.length; j+=1){
							if (j % 2 === 1){
								iCnt += 1;
								continue;
							}
							title = facet[j];
							count = facet[j+1];
							item = ProductFacetPanelItem.create();
							item.id = iCnt;
							item.parent = panel;
							item.phrase = phrase;
							item.domId = 'facetPanelItem_' + iCnt;
							item.title = title;
							item.count = count;
							item.attributeName = k;
							panel.items.push(item);
						}
						panel.make();
						cnt += 1;
					}
				}
			}
		}
	);
	
	SearchPhraseProposalsItem = $.extend(
		$.clone(LLObject),
		{
			create: function(proposal, count, phrase){
				var o = LLObject.create.call(this);
				o.id = null;
				o.parent = null;
				o.proposal = proposal;
				o.jqElm = null;
				o.count = count;
				o.phrase = phrase;
				return o;
			},
			changeProposalFirstLetterCase: function(){
				var fl = this.proposal.substring(0, 1);
				var rest = this.proposal.substring(1, this.proposal.length);
				if (isNaN(fl)){
					fl = fl.toUpperCase();
				}
				return fl + rest;
			},
			makeItemLayout: function(){
				var lay = $(
					'<div class="proposalItem searchProposalItem">' +
						'<div class="viewport"><div class="count"></div></div>' +
						'<div class="proposal"></div>' +
					'</div>'
				);
				lay.find('.proposal').text(this.changeProposalFirstLetterCase()).end().find('.count').text('(' + this.count + ')');
				lay.hover(
					function(){
						$(this).addClass('searchProposalItemHover');
					},
					function(){
						$(this).removeClass('searchProposalItemHover');
					}
				);
				var self = this;
				lay.bind('click', function(e){
					self.parent.proposalItems.current = self.id;
					self.parent.completePhraseAndSetFocusToInput(self.proposal);
					self.parent.fire();
				});
				return lay;
			},
			make: function(){
				var item = this.makeItemLayout();
				this.jqElm = item;
				$('#searchPhraseProposalsScrollPane').append(item);
			}
		}
	);
	
	ProductProposalsItem = $.extend(
		$.clone(LLObject),
		{
			create: function(){
				var o = LLObject.create.call(this);
				o.id = null;
				o.parent = null;
				o.data = null;
				o.jqElm = null;
				o.descAttrs = [
					'fo_bezeichnung',
					'fo_zusatzinfo',
					'fb_bezeichnung',
					'sf_bezeichnung',
					'gr_bezeichnung',
					'wv_bezeichnung',
					'ka_bezeichnung',
					'au_bezeichnung',
					'art_fenster_text',
					'var_bezeichnung',
					'art_seiten_drucken_text',
					'xs_bezeichnung'
					/*'artl_zusatzinfo1',
					'artl_bezeichnung',
					'auf_auflage_min',
					'auf_auflage_max',
					'wgl_bezeichnung',
					'wgl_bezeichnung_detail'*/
				]
				return o;
			},
			getDescription: function(){
				var str = '';
				var self = this;
				$(this.descAttrs).each(function(i){
					if (typeof self.data[this] != 'undefined'){
						str += self.data[this] + ', ';
					}
				});
				if (str.length > 0) return str.substring(0, str.length -2);
				return str;
			},
			makeItemLayout: function(){
				var img = '';
				var d = this.data;
				if (this.data.img_src){
					iattrs = {
						src: d.img_src,
						width: d.img_width,
						height: d.img_height,
						border: 0
					}
					var img = $('<img/>').attr(iattrs);
				}
				var lay = $(
					'<div class="proposalItem productProposalItem">' +
						'<div class="proposal">' +
							'<div class="image"></div>' +
							'<div class="textOuter">' +
								'<h1 class="headline">' + d.artl_bezeichnung + '</h1>' +
								'<p class="desc">' + this.getDescription() + '</p>' +
							'</div>' +
							'<div class="floatTerm"></div>' +
						'</div>' +
					'</div>'
				);
				lay.find('.image').append(img);
				lay.hover(
					function(){
						$(this).addClass('productProposalItemHover');
					},
					function(){
						$(this).removeClass('productProposalItemHover');
					}
				);
				var self = this;
				lay.bind('click', function(){
					window.location.href = d.url.replace('http://www.flyerpilot.de', '');
				})
				return lay;
			},
			make: function(){
				var item = this.makeItemLayout();
				this.jqElm = item;
				$('#productSearchProposalsScrollPane').append(item);
			}
		}
	);
	
	ProductFacetPanel = $.extend(
		$.clone(LLObject),
		{
			create: function(){
				var o = LLObject.create.call(this);
				o.target = null;
				o.parent = null;
				o.id = null;
				o.domId = null;
				o.title = null;
				o.items = [];
				o.panelTitelMapper = {
					'fo_bezeichnung': 'Endformat',
					'wgl_bezeichnung': 'Warengruppe',
					'gr_bezeichnung': 'Papier',
					'wv_bezeichnung': 'Weiterverarbeitung',
					'art_fenster_text': null,
					'wgl_bezeichnung_detail': 'Warengruppe (Detail)'
				};
				return o;
			},
			makePanelLayout: function(){
				var lay = $(
					'<div id="' + this.domId + '" class="facetPanel"></div>'
				);
				return lay;
			},
			makeTitleLayout: function(){
				var title, lay;
				title = this.panelTitelMapper[this.title];
				lay = $(
					'<div class="facetPanelTitle">' +
						'<span>' + title + '</span>' +
					'</div>'
				);
				return lay;
			},
			appendPanelItems: function(panel){
				var self = this;
				$(this.items).each(function(i){
					panel.append(this.make());
				});
			},
			make: function(){
				var panel = this.makePanelLayout();
				panel.append(this.makeTitleLayout());
				this.appendPanelItems(panel);
				this.target.append(panel);
			}
		}
	);
	
	ProductFacetPanelItem = $.extend(
		$.clone(LLObject),
		{
			create: function(){
				var o = LLObject.create.call(this);
				o.id = null;
				o.panel = null;
				o.phrase = null;
				o.domId = null;
				o.title = null;
				o.count = null;
				o.attributeName = null;
				return o;
			},
			makeItemTitleLayout: function(){
				var lay, topParent = this.parent.parent, self = this, facetParams, realParams, k;
				lay = $(
					'<a href="#" id="' + this.domId + '" class="facetItem">' +
						'<span class="viewport">' +
							'<span class="count">(' + this.count + ')</span>' +
						'</span>' +
						'<span class="title">' + this.title + '</span>' +
					'</a>'
				);
				lay.bind('click', function(e){
					e.preventDefault();
					e.stopPropagation();
					facetParams = {};
					facetParams[self.attributeName] = self.title;
					facetParams = topParent.getFacetParamsAsJson(facetParams);
					realParams = {'fq': []};
					for (k in facetParams){
						realParams.fq.push([k,':"',facetParams[k],'"'].join(''));
					}
					realParams = topParent.getQueryParams('productProposals', self.phrase, realParams);
					topParent.handleProductProposals(self.phrase, realParams);
				});
				return lay;
			},
			make: function(){
				var item = this.makeItemTitleLayout();
				return item;
			}
		}
	);

	ProductFacetPanelBackItem = $.extend(
		$.clone(ProductFacetPanelItem),
		{
			create: function(){
				var o = ProductFacetPanelItem.create.call(this);
				return o;
			},
			makeItemTitleLayout: function(){
				var lay, topParent = this.parent.parent, self = this, facetParams, realParams, k;
				lay = $(
					'<a href="#" id="' + this.domId + '" class="facetItem facetBackItem">' +
						'<span class="title">' + this.title + '</span>' +
					'</a>'
				);
				lay.bind('click', function(e){
					e.preventDefault();
					e.stopPropagation();
					facetParams = topParent.getFacetParamsAsJson(self.attributeName);
					realParams = {'fq': []};
					for (k in facetParams){
						realParams.fq.push([k,':"',facetParams[k],'"'].join(''));
					}
					realParams = topParent.getQueryParams('productProposals', self.phrase, realParams);
					topParent.handleProductProposals(self.phrase, realParams);
				});
				return lay;
			}
		}
	);
/* << */

/* >> Pager element */
	PagerElement = $.extend(
		$.clone(LLObject),
		{
			create: function(opts){
				var o = LLObject.create.call(this);
				o.opts = opts || null;
				o.currentPage = 1;
				o.overall = null;
				o.offset = null;
				return o;
			},
			getPages: function(){
				var ov, off;
				ov = this.overall;
				off = this.offset;
				return ov % off > 0 ? Math.ceil(ov / off) : ov / off;
			},
			makeArrowNaviLayout: function(){
				var opts = this.opts;
				var tpl = $(
					'<td class="pagerArrowOuter">' +
						'<div></div>' +
					'</td>'
				);
				var firstBind = false;
				var lastBind = false;
				if (this.currentPage > 1){
					var divFirstClass = 'firstPage';
					var divPrevClass = 'previousPage';
					firstBind = true;
					if (this.currentPage < this.getPages()){
						var divLastClass = 'lastPage';
						var divNextClass = 'nextPage';
						lastBind = true;
					}else{
						var divLastClass = 'lastPagePass';
						var divNextClass = 'nextPagePass';
					}
				}else{
					var divFirstClass = 'firstPagePass';
					var divPrevClass = 'previousPagePass';
					if (this.currentPage < this.getPages()){
						var divLastClass = 'lastPage';
						var divNextClass = 'nextPage';
						lastBind = true;
					}else{
						var divLastClass = 'lastPagePass';
						var divNextClass = 'nextPagePass';
					}
				}
				var self = this;
				var firstCol = tpl.clone();
				firstCol.find('div').addClass(divFirstClass).hover(
					function(e){if (self.currentPage > 1){$(this).addClass('firstPageOver')}},
					function(e){$(this).removeClass('firstPageOver')}
				);
				var previousCol = tpl.clone();
				previousCol.find('div').addClass(divPrevClass).hover(
					function(e){if (self.currentPage > 1){$(this).addClass('previousPageOver')}},
					function(e){$(this).removeClass('previousPageOver')}
				);
				var lastCol = tpl.clone();
				lastCol.find('div').addClass(divLastClass).hover(
					function(e){if (self.currentPage < self.getPages()){$(this).addClass('lastPageOver')}},
					function(e){$(this).removeClass('lastPageOver')}
				);
				var nextCol = tpl.clone();
				nextCol.find('div').addClass(divNextClass).hover(
					function(e){if (self.currentPage < self.getPages()){$(this).addClass('nextPageOver')}},
					function(e){$(this).removeClass('nextPageOver')}
				);
				var cb = opts.callback;
				if (cb && typeof cb === 'function'){
					if (firstBind){
						firstCol.find('div').bind('click', function(e){
							cb.call(self, 1);
						});
						previousCol.find('div').bind('click', function(e){
							cb.call(self, self.currentPage - 1);
						});
					}
					if (lastBind){
						lastCol.find('div').bind('click', function(e){
							cb.call(self, self.getPages());
						});
						nextCol.find('div').bind('click', function(e){
							cb.call(self, self.currentPage + 1);
						});
					}
				}
				return {
					first: firstCol.add(previousCol),
					last: nextCol.add(lastCol)
				};
			},
			makePageLayout: function(page, here){
				var lay = $('<td class="pageOuter"><div class="page"><span>' + page + '</span></div></td>');
				if (here){
					lay.find('.page').addClass('pageHere');
				}else{
					var cb = this.opts.callback;
					var self = this;
					if (cb && typeof cb === 'function'){
						lay.find('div').bind('click', function(e){
							cb.call(self, page);
						});
					}
					lay.find('.page').hover(
						function(e){$(this).addClass('pageOver')},
						function(e){$(this).removeClass('pageOver')}
					);
				}
				return lay;
			},
			makePagerLayout: function(){
				var opts = this.opts;
				var pOuter = $('<table cellpadding="0" cellspacing="0" class="jsonTablePager"><tr></tr></table>');
				var pages = this.getPages();
				var currPage = this.currentPage;
				var halfFrameWidth = opts.frameWidth / 2;
				if (currPage - halfFrameWidth > 0){
					var start = currPage - halfFrameWidth;
					var end = start + opts.frameWidth;
				}else{
					var start = 1;
					var end = start + opts.frameWidth;
					if (end > pages) end = pages + 1;
				}
				
				if (currPage + halfFrameWidth > pages){
					start = start - (halfFrameWidth - (pages - currPage)) +1;
					var end = start + opts.frameWidth + 1;
					if (start <= 0) start = 1;
				}
				var row = pOuter.find('tr');
				row.append(this.makeArrowNaviLayout().first);
				for (var i = start; i < end; ++i){
					if (i > pages) break;
					if (i === currPage){
						row.append(this.makePageLayout(i, true));
					}else{
						row.append(this.makePageLayout(i, false));
					}
				}
				row.append(this.makeArrowNaviLayout().last);
				return pOuter;
			},
			update: function(data){
				var target = this.opts.target;
				this.currentPage = data.pager.currentPage;
				this.overall = data.pager.overall;
				this.offset = data.pager.offset;
				target.empty().append(this.makePagerLayout());
			}
		}
	);
/* << */



/* >> first level subnavigation */
	FirstLevelSubnavigation = $.extend(
		$.clone(LLObject),
		{
			create: function(){
				var o = LLObject.create.call(this);
				o.nav = $('table.nav');
				return o;
			},
			bindNavigation: function(){
				var nav = this.nav;
				var ni = nav.find('td.navItem');
				$(ni).each(function(i){
					$(this).bind('mouseenter', function(e){
						var layer = $(this).find('.layeredNavOuterShell');
						var firstItem = $(layer.find('.navItem').get(0));
						var lastItem = $(layer.find('.navItem').get(layer.find('.navItem').size() - 1));
						firstItem.addClass('navItemFirst');
						lastItem.addClass('navItemLast');
						layer.show();
					})
					$(this).bind('mouseleave', function(e){
						$(this).find('.layeredNavOuterShell').hide();
					})
				});
			}
		}
	);
	
	$(function(){
		SubNabVar1 = FirstLevelSubnavigation.create();
		SubNabVar1.bindNavigation();
	});
/* << */


/* >> first level subnavigation variant 2*/
	FirstLevelSubnavigationVariant2 = $.extend(
		$.clone(FirstLevelSubnavigation),
		{
			create: function(){
				var o =  FirstLevelSubnavigation.create.call(this);
				o.container = [
					'printprodukte',
					'grossformat_displays',
					'poster_fotos_more',
					'creativpilot'
				];
				o.nav = $('table.nav');
				return o;
			},
			bindNavigation: function(){
				var nav = this.nav,
						ni = nav.find('td.navItem'),
						i, j, cont, className;
				for (i = 0; i < this.container.length; i+=1){
					cont = $('.flyout_' + this.container[i]);
					ni.eq(i).append(cont);
				}
				$(ni).each(function(j){
					$(this).unbind();
					$(this).bind('mouseenter', function(e){
						$('body').find('div[class^=stdSty flyout_]').hide();
						className = $(this).find(':first-child').attr('class').split(' ');
						if (className.length > 1){
							className = className[1];
						}else{
							className = className[0];
						}
						className = '.flyout_' + className.substring(3, className.length);
						$(className).show();
					});
					$(this).bind('mouseleave', function(e){
						$('body').find('div[class^=stdSty flyout_]').hide();
					})
				});
			}
		}
	);
	
	$(function(){
		var url = window.location.href;
		//if (url.search(/displayPreviewAction\.do/) > -1 || url.search(/startseite-neu\.htm/) > -1){
			SubNavVar2 = FirstLevelSubnavigationVariant2.create();
			SubNavVar2.bindNavigation();
		//}
	});
/* << */


/* >> window wide keyboard and mouse events handler */
	$(function(){
		$(window).bind('click', function(e){
			handleWindowWideEvents(e);
		}).bind('keydown', function(e){
			handleWindowWideEvents(e);
		});
		handleWindowWideEvents = function(e){
			if (e.keyCode === 27 || $(e.target).attr('name') != 'search_string'){
				//$('#searchPhraseProposals').hide('fast');
			}
		}
	})
/* << */


/* >> Login / Logout for trail content */
	$(function(){
		if (XIST4C_GLOBALS.login === true){
			var shell = $('div.tc_loginLink div.loginLinkInner');
			shell.find('span').text('Logout');
			shell.find('a').attr('href', 'http://flyerpilot.xist4c.de/online-druckerei-guenstig-drucken.htm?logout=standardCug');
			shell.find('img').addClass('logout');
		}
	});
/* << */


// >> weekly special
	WeeklySpecial = $.extend(
		$.clone(LLObject),
		{
			create: function(){
				var o = LLObject.create.call(this);
				o.currentInterval = null;
				return o;
			},
			update: function(interval){
				var url = AjaxURLManager.getUrlWithKey('weeklyspecial'),
						self = this, c, action, form, intv;
				$.getJSON(url, function(data, textStatus){
					if (data && data.type === 'weekSpecialStartpage'){
						c = $('#weeklySpecial');
						c.show('fast');
						c.find('.infoButton').css({'visibility': 'visible'});
						$('#weeklySpecial').find('.productTable').show();
						$('#weeklySpecial').find('.noSuperSpecial').hide();
						if (c.size() > 0){
							c.find('.rest').html(data.restText);
							c.find('.productText').html(data.productText);
							c.find('.price').html(data.priceText);
							c.find('.hint').html(data.shippingInfoText);
							c.find('.info').html(data.infoText);
							c.find('.infoButton').hover(
								function(){
									$('#weeklySpecial').find('h1, h2, table, .info, .infoButton').hide();
									$('#weeklySpecial').find('.panel').show();
								},
								null
							);
							c.find('.panel').hover(
								null,
								function(e){
									$('#weeklySpecial').find('h1, h2, table, .info, .infoButton').show();
									$(this).hide();
								}
							);
							// update form action url
							action = $('.wkElementTop').find('a').attr('href');
							form = c.find('form');
							// prepare weekly special form
							form.attr({'action': action});
							$('#formField_auf_id_0').val(data.auf_id);
							// bind product text with event
							c.find('.productText, .price, .image img').css({'cursor': 'pointer'}).bind('click', function(e){
								form.submit();
							});
						}
						
						if (!self.currentInterval){
							if (interval > 0){
								intv = interval;
							}else{
								if (self.currentInterval){
									clearInterval(self.currentInterval);
									self.currentInterval = null;
								}
								intv = null;
							}
							if (intv){
								self.currentInterval = setInterval(function(){
									self.update(intv);
								}, intv);
							}
						}
					}else{
						$('#weeklySpecial').show('fast');
						$('#weeklySpecial').find('.infoButton').css({'visibility': 'hidden'});
						$('#weeklySpecial').find('.productTable').hide();
						$('#weeklySpecial').find('.noSuperSpecial').show();
						$('#weeklySpecial').find('.info').html($.lang('noSuperSpecial'));
					}
				});
			}
		}
	);
// <<


// >> weekly special teaser variant
	WeeklySpecialTeaserVariant = $.extend(
		$.clone(WeeklySpecial),
		{
			create: function(){
				var o =  WeeklySpecial.create.call(this);
				o.teaserTitle = $('#weeklySpecialTeaserVariant').parents('div.desOut1').find('.panelTitle h3');
				o.teaserTitleText = $('#weeklySpecialTeaserVariant').parents('div.desOut1').find('.panelTitle h3').text();
				return o;
			},
			getImage: function(data){
				var img;
				if (data){
					img = $('<img/>');
					img.attr(data);
					return img;
				}
				return null;
			},
			update: function(interval){
				var url = AjaxURLManager.getUrlWithKey('weeklyspecial'),
						self = this, c, action, form, intv, oldTeaserTitleText, teaserTitle,
						c = $('#weeklySpecialTeaserVariant');
				$.getJSON(url, function(data, textStatus){
					if (data && data.type === 'weekSpecialStartpage'){
						c.show();
						c.find('.infoButton').css({'visibility': 'visible'});
						c.find('.productTable, .restInfo, .hint').show();
						c.find('.noSuperSpecial').hide();
						if (c.size() > 0){
							if (data.remainingDaysText){
								self.teaserTitle.text(self.teaserTitleText + ' ' + data.remainingDaysText);
							}
							c.find('.rest').html(data.overall - data.current);
							c.find('.popupRest').html(data.restText);
							c.find('.overall').html(data.overall);
							c.find('div.image').html(self.getImage(data.prdImage));
							c.find('.productText').html(data.productText);
							c.find('.price').html(data.priceText);
							c.find('.hint').html(data.shippingInfoText);
							c.find('.info').html(data.infoText);
							c.find('.popupInfoButton').hover(
								function(){
									$('#weeklySpecial').find('.panel').show();
									$('.popupInfoButton').hide();
								},
								null
							);
							c.find('.panel').bind('mouseout', function(e){
								$(this).hide();
								$('.popupInfoButton').show();
							});
							// update form action url
							action = $('.wkElementTop').find('a').attr('href');
							form = c.find('form');
							// prepare weekly special form
							form.attr({'action': action});
							$('#formField_auf_id_1').val(data.auf_id);
							// bind product text with event
							c.find('.productText, .price, .image img').css({'cursor': 'pointer'}).bind('click', function(e){
								form.submit();
							});
							// bind teaser more button
							c.parents('.content2').next().find('a').bind('click', function(e){
								e.preventDefault();
								e.stopPropagation();
								form.submit();
							});
						}
						
						if (!self.currentInterval){
							if (interval > 0){
								intv = interval;
							}else{
								if (self.currentInterval){
									clearInterval(self.currentInterval);
									self.currentInterval = null;
								}
								intv = null;
							}
							if (intv){
								self.currentInterval = setInterval(function(){
									self.update(intv);
								}, intv);
							}
						}
						$('#weeklySpecialHoverArea').unbind();
						$('#weeklySpecialHoverArea').hover(
							function(){
								$('#weeklySpecial').show('fast');
							},
							function(){
								$('#weeklySpecial').hide('fast');
							}
						);
					}else{
						$('#weeklySpecialTeaserVariant').show('fast');
						$('#weeklySpecialTeaserVariant').find('.infoButton').css({'visibility': 'hidden'});
						$('#weeklySpecialTeaserVariant').find('.productTable, .restInfo, .hint').hide();
						$('#weeklySpecialTeaserVariant').parents('.content2').next().find('a').hide();
						$('#weeklySpecialTeaserVariant').find('.noSuperSpecial').show();
						$('#weeklySpecialTeaserVariant').find('.info').html($.lang('noSuperSpecial'));
					}
				});
			}
		}
	);
// <<


/* >> alternative billing address */
	AltBillingAddressHandler = $.extend(
		$.clone(LLObject),
		{
			create: function(){
				var o = LLObject.create.call(this);
				this.bindButton();
				this.testFields();
				return o;
			},
			bindButton: function(){
				var self = this;
				$('div.altBillButton a').bind('click', function(e){
					e.preventDefault();
					e.stopPropagation();
					self.showShell();
				});
			},
			showShell: function(){
				$('div.altBillingAddressShellOuter').show();
			},
			testFields: function(){
				var self = this;
				var addFormCont = $('div.altBillingAddressShellOuter table.innerTable :text');
				
				for (var i = 0; i < addFormCont.length; ++i) {
					if ($(addFormCont[i]).val().length > 0){
						self.showShell();
						break;
					}
				}
			}
		}
	);
	$(function(){AltBillingAddressHandler.create()});
/* << */


/* modify first tab's title class */
	ModifyFirstTabsTitleClass = $.extend(
		$.clone(LLObject),
		{
			create: function(){
				var o = LLObject.create.call(this);
				this.modifyTabTitle();
				return o;
			},
			modifyTabTitle: function(){
				$('div.tabShell ul li:first a').addClass('first');
			}
		}
	);
	$(function(){ModifyFirstTabsTitleClass.create()});
/* << */


// >> product table to slider element
	ProductTableToSlider = $.extend(
		$.clone(LLObject),
		{
			create: function(opts){
				var o = LLObject.create.call(this);
				o.defaults = {
					'source': null,
					'width': 100,
					'sliderPositions': [0, 10, 21]
				};
				if (opts && typeof opts === 'object'){
					o.defaults = $.extend(o.defaults, opts);
				}
				return o;
			},
			init: function(){
				var self = this, lay, Helper, scrollPane, src, rows, firstRow, i, spacer, sliderPositions, controller;
				src = Utils.getDefault.call(this, 'source');
				Helper = {
					makeScrollPaneLayout: function(){
						lay = $(
							'<div class="prdSliderElm">' +
								'<div class="inner">' +
									'<div id="prdSliderScrollPane" class="prdSliderScrollPane">' +
										'<div id="prdSliderContent" class="prdSliderContent"></div>' +
									'</div>' +
								'</div>' +
							'</div>'
						);
						lay.find('#prdSliderScrollPane').css({'width': Utils.getDefault.call(self, 'width')});
						return lay;
					},
					makeControllerLayout: function(){
						return $(
							'<div id="prdSliderController" class="controllerOuter controllerClickArea_0">' +
								'<div class="viewport"></div>' +
							'</div>'
						);
					},
					makeClickArea: function(sliderPos, index){
						lay = $('<div class="clickArea clickArea_' + index + '"></div>');
						if (sliderPos){
							lay.bind('click', function(e){
								$('#prdSliderController').attr({'class': null});
								$('#prdSliderController').addClass('controllerOuter');
								$('#prdSliderController').addClass('controllerClickArea_' + index);
								$('#prdSliderScrollPane').scrollTo(sliderPos, {'axis': 'x', 'duration': 1000});
							});
						}
						return lay;
					},
					prepareControllerClickAreas: function(){
						sliderPositions = Utils.getDefault.call(self, 'sliderPositions');
						controller = $('#prdSliderController');
						if (typeof sliderPositions.length === 'number'){
							for (i = 0; i < sliderPositions.length; i+=1){
								controller.find('.viewport').append(this.makeClickArea($('.poSpecial tr').children().eq(sliderPositions[i]), i));
							}
						}
					},
					reconstructPrdTable: function(){
						if (src && typeof src === 'object'){
							src.hide();
							rows = src.children().children();
							firstRow = rows.eq(0);
							spacer = firstRow.children().eq(1);
							for (i = 1; i < rows.length; i+=1){
								spacer = spacer.clone();
								firstRow.append(rows.append(spacer).eq(i).children());
							}
						}
						return null;
					}
				};
				if (src){
					scrollPane = Helper.makeScrollPaneLayout();
					src.before(scrollPane);
					Helper.reconstructPrdTable();
					scrollPane.find('.prdSliderContent').append(src);
					src.show();
					scrollPane.append(Helper.makeControllerLayout());
					Helper.prepareControllerClickAreas();
				}
			}
		}
	);
// <<


// >> product table picker to slider element
	ProductTablePickerToSlider = $.extend(
		$.clone(ProductTableToSlider),
		{
			create: function(opts){
				var o = ProductTableToSlider.create.call(this);
				o.defaults = {
					'source': null,
					'width': 100,
					'height': 100,
					'sliderPositions': [0, 10, 21]
				};
				o.grpCurrent = 0; // index of the current selected group.
				o.currentTable = null; // jquery element of the current product table.
				o.currentIndex = 0; // current index of the selected product item.
				if (opts && typeof opts === 'object'){
					o.defaults = $.extend(o.defaults, opts);
				}
				o.scrollInterval = null;
				delete o.reconstructPrdTable;
				return o;
			},
			init: function(){
				var self = this, Helper, scrollPane, src;
				src = Utils.getDefault.call(this, 'source');
				Helper = {
					makeScrollPaneLayout: function(){
						var lay;
						lay = $(
							'<div class="prdSliderElm">' +
								'<div class="inner">' +
									'<div id="prdSliderScrollPane" class="prdSliderScrollPane">' +
										'<div id="prdSliderContent" class="prdSliderContent"></div>' +
									'</div>' +
								'</div>' +
							'</div>'
						);
						lay.find('#prdSliderScrollPane').css({
							'width': Utils.getDefault.call(self, 'width'),
							'height': Utils.getDefault.call(self, 'height')
						});
						return lay;
					},
					makeControllerLayout: function(){
						return $(
							'<div id="prdSliderController" class="controllerOuter controllerClickArea_0">' +
								'<div class="viewport"></div>' +
							'</div>'
						);
					},
					makeClickArea: function(sliderPos, index){
						var lay = $('<div class="clickArea clickArea_' + index + '"></div>');
						self.currentTable = $('#prdSliderContent').children().eq(0);
						if (sliderPos){
							lay.bind('click', function(e){
								self.grpCurrent = index;
								self.currentTable = $('#prdSliderContent').children().eq(index);
								self.currentIndex = 0;
								$('#prdSliderScrollPane').scrollTo(0, {'duration': 500, 'axis': 'x'}
								);
								$('#prdSliderController').attr({'class': null});
								$('#prdSliderController').addClass('controllerOuter');
								$('#prdSliderController').addClass('controllerClickArea_' + index);
								$('#prdSliderContent').children().hide();
								$('#prdSliderContent').children().eq(index).show();
							});
						}
						$('#prdSliderContent').children().eq(0).show();
						return lay;
					},
					makeArrowLayout: function(type){
						var lay = $(
							'<div class="arrowOuter">' +
								'<div class="arrow"></div>' +
							'</div>'
						).clone();
						lay.find('.arrow').hover(
							function(){
								$(this).addClass('arrowHover');
							},
							function(){
								$(this).removeClass('arrowHover');
							}
						);
						if (type === 'left'){
							lay.addClass('arrowOuterLeft');
							return lay;
						}
						lay.addClass('arrowOuterRight');
						return lay;
					},
					prepareControllerClickAreas: function(){
						var sliderPositions = Utils.getDefault.call(self, 'sliderPositions'),
								controller, i, leftArrow, rightArrow, nextItem = null, items;
						controller = $('#prdSliderController');
						if (typeof sliderPositions.length === 'number'){
							for (i = 0; i < sliderPositions.length; i+=1){
								controller.find('.viewport').append(this.makeClickArea($('.poSpecial tr').children().eq(sliderPositions[i]), i));
							}
						}
						$('#prdSliderContent').children().eq(0).show();
						// prepare arrows
						leftArrow = this.makeArrowLayout('left');
						rightArrow = this.makeArrowLayout('right');
						controller.find('.viewport').append(leftArrow, rightArrow);
						leftArrow.hover(
							function(){
								self.scrollInterval = setInterval(function(){
									if (self.currentIndex > 0){
										nextItem = self.currentTable.find('>tbody>tr>td.hasContent').eq(self.currentIndex -= 1);
										$('#prdSliderScrollPane').scrollTo(nextItem, {'duration': 300, 'axis': 'x'});
									}
								}, 500);
							},
							function(){
								if (self.scrollInterval){
									clearInterval(self.scrollInterval);
									self.scrollInterval = null;
								}
							}
						);
						rightArrow.hover(
							function(){
								items = self.currentTable.find('>tbody>tr>td.hasContent');
								self.scrollInterval = setInterval(function(){
									if (self.currentIndex + 1 < items.length){
										nextItem = items.eq(self.currentIndex += 1);
										$('#prdSliderScrollPane').scrollTo(nextItem, {'duration': 300, 'axis': 'x'});
									}
								}, 500);
							},
							function(){
								if (self.scrollInterval){
									clearInterval(self.scrollInterval);
									self.scrollInterval = null;
								}
							}
						);
					},
					preparePrdTablesAndAppendToScrollPane: function(){
						var tables;
						if (src && typeof src === 'object'){
							src.hide();
							tables = src.find('.poSpecial');
							tables.each(function(i){
								var cols = tables.find('>tbody>tr>td.prdOuterItem');
								cols.each(function(j){
										if (!$(this).children(':first-child').hasClass('dummyProd')){
											$(this).addClass('hasContent');
										}
								});
							});
							$('#prdSliderContent').empty().append(tables.hide());
							$('#prdSliderContent').find('div[id^=prdPanel_intermedstepov_]').unbind();
						}
					}
				};
				if (src){
					scrollPane = Helper.makeScrollPaneLayout();
					src.before(scrollPane);
					Helper.preparePrdTablesAndAppendToScrollPane();
					scrollPane.append(Helper.makeControllerLayout());
					Helper.prepareControllerClickAreas();
				}
			}
		}
	);
// <<



// >> startpage panel enhancer
	StartpagePanelEnhancer = $.extend(
		$.clone(LLObject),
		{
			create: function(opts){
				var o = LLObject.create.call(this);
				o.defaults = {
					'target': null,
					'titleTarget': null,
					'titleMore': 'more',
					'titleLess': 'less',
					'minHeight': 100,
					'maxHeight': 500
				};
				if (opts && typeof opts === 'object'){
					o.defaults = $.extend(o.defaults, opts);
				}
				return o;
			},
			init: function(){
				var self = this, Helper, target, ttarget, tm, tl, minH, maxH, lay;
				ttarget = Utils.getDefault.call(this, 'titleTarget');
				Helper = {
					makePanelTitleLayout: function(){
						tm = Utils.getDefault.call(self, 'titleMore');
						tl = Utils.getDefault.call(self, 'titleLess');
						minH = Utils.getDefault.call(self, 'minHeight');
						maxH = Utils.getDefault.call(self, 'maxHeight');
						target = Utils.getDefault.call(self, 'target');
						lay = $(
							'<div class="viewport panelEnhancerTitle">' +
								'<div class="title"><span>' + tm + '</span>' + Utils.pixelAsString() + '</div>' +
							'</div>'
						);
						lay.find('.title').toggle(
							function(){
								$(this).parent('div').addClass('panelEnhancerTitleDown').find('span').text(tl);
								target.height(maxH);
							},
							function(){
								$(this).parent('div').removeClass('panelEnhancerTitleDown').find('span').text(tm);
								target.height(minH);
							}
						);
						return lay;
					}
				};
				ttarget.append(Helper.makePanelTitleLayout());
				
			}
		}
	);
// <<


// >> position database form content to normal content
	PositionDatabaseFormCont = $.extend(
		$.clone(LLObject),
		{
			create: function(lastContEl, targetEl){
				var o = LLObject.create.call(this);
				o.targetEl = targetEl || $('div.contColDes5');
				o.lastContEl = lastContEl || null;
				o.position();
				return o;
			},
			position: function(){
				var contentElements = (this.lastContEl).nextAll(),
						that = this, i;
				for (i = 0; i < contentElements.length; i+=1) {
					(that.targetEl).append(contentElements[i]);
					if ($(contentElements[i]).context.nodeName === 'FORM') {
						break;
					}
				}
			}
		}
	);
// <<


// >> startpage stage controller
	// listen to link clicks and controls the stage if specified attributes.
	StartpageStageController = $.extend(
		$.clone(LLObject),
		{
			create: function(){
				var o = LLObject.create.call(this);
				return o;
			},
			listen: function(){
				var self = this;
				$(document).find('a, area').bind('click', function(e){
					var i, href, params, dataArr, data = null;
					href = $(this).attr('href');
					params = Utils.getUrlParamsAsJson(href);
					if (params && typeof params.jsElement !== 'undefined'){
						e.preventDefault();
						e.stopPropagation();
						dataArr = params.jsElement.split('_');
						for (i = 0; i < dataArr.length; i += 1){
							if (! data){data = {};}
							if (i % 2 !== 0){continue;}
							data[dataArr[i]] = parseInt(dataArr[i+1], 10);
						}
						self.controlStage(data);
					}
				});
			},
			getStageTabs: function(){
				return $('#uiTab1');
			},
			controlStage: function(data){
				var tabs, self = this, currTab, pager;
				if (data){
					tabs = this.getStageTabs();
					if (tabs.length > 0){
						tabs.tabs( 'select' , data.tab);
						if (typeof data.pager !== 'undefined'){
							currTab = tabs.find('>div:not(.ui-tabs-hide)');
							pager = currTab.find('.jsPagerShell');
							pager.data('jsPager').slideToPos(data.pager);
						}
					}
				}
			}
		}
	);
	$(function(){
		var SpStCont = StartpageStageController.create();
		SpStCont.listen();
	});
// <<


// >> shopping cart flyout
	ShoppingCartFlyout = $.extend(
		$.clone(LLObject),
		{
			create: function (test) {
				var o = LLObject.create.call(this);
				o.wkTopShell = $('div.wkTopShell');
				o.wkTopInner = $('div.wkTopShell div.wktsInner');
				o.prepareFlyout(test);
				return o;
			},
			prepareFlyout: function (test) {
				if ($(this.wkTopInner).find('span.amount').text() !== '0') {
					var cardID = this.getCardID(),
						self = this,
						url = window.location.href,
						session;
					if (cardID !== null) {
						session = this.getSession(url);
						$(this.wkTopInner).bind("mouseenter", function (e) {
							if ($('div.wkFlyout').length === 0) {
								self.handleJSON(cardID, session, test);
							}
						});
						$(this.wkTopInner).bind("mouseleave", function (e) {
							self.handleFlyout("hide");
						});
					}
				}
			},
			getSession: function (url) {
				var session = null;
				if (url.search(/jsessionid=/) !== -1) {
					if (url.search(/\?/) !== -1) {
						session = url.substring(url.search(/jsessionid=/), url.search(/\?/));
					}
					else {
						session = url.substring(url.search(/jsessionid=/), url.length);
					}
				}
				return session;
			},
			getCardID: function () {
				var cardID = null;
				if (XIST4C_GLOBALS.shop && XIST4C_GLOBALS.shop.scID !== "null") {
					cardID = XIST4C_GLOBALS.shop.scID;
				}
				return cardID;
			},
			handleJSON: function (cardID, session, test) {
				var self = this, url = null;
				
				if (test) {
					url = "flyerpilot_shoppingCard.text";
				} else {
					url = "/backend/shoppingcart_flyout?vor_id=" + cardID;
				}
				
				$.getJSON(url,
					function (data, textStatus) {
						self.setLayout(data, session);
					}
				);
			},
			outerShells: function (wkLink) {
				var src = '<div class="wkFlyout">' +
					'<div id="wkFlyout_content" class="wkFlyout_content">' +
						'<table width="100%" cellpadding="0" cellspacing="0" border="0"></table>' +
					'</div>' +
					'<div id="wkFlyout_button" class="wkFlyout_button">' +
						'<div class="stdButtonShell"><div class="stdButtonInner"><div class="stdButton">' +
							'<a href="' + wkLink + '" target="_self" class="buttonInner"><span>Zur Kasse</span></a>' +
						'</div></div></div>' +
					'</div>' +
					'<div class="infoText">Preise inkl. MwSt., Premium-Datencheck <br />&amp; Versand (deutschlandweit)</div>' +
				'</div>';
				return src;
			},
			setLayout: function (data, session) {
				var wkOuterShell, wkText, wkLink, wkFlyout, waehrung, overall, i, item, href;
				
				wkOuterShell = $(this.wkTopInner);
				wkText = wkOuterShell.html();
				wkLink = wkOuterShell.find('a')[0].href;
				
				$(this.wkTopInner).append(this.outerShells(wkLink));
				
				wkFlyout = $(wkOuterShell.find('div.wkFlyout')[0]);
				if (data) {
					waehrung = "&nbsp;&euro;";
					overall = data.overall;
					$('#wkFlyout_overall').html(overall + '&nbsp;' + waehrung);
					for (i = 0; i < data.items.length; i += 1) {
						item = data.items[i];
						href = this.replaceJSONHref(item.href, session);
						$('#wkFlyout_content table').append(
							'<tr><td class="text"><div class="title"><a href="' + href + '" target="_self">' + item.title + '</a></div><div class="desc"><a href="' + href + '" target="_self">' + item.desc + '</a></div></td><td class="price"><a href="' + href + '" target="_self">' + item.price + waehrung + '</a></td></tr>'
						);
					}
					$('#wkFlyout_content table').append('<tr class="overall"><td class="text"><div class="title">Gesamt</div></td><td id="wkFlyout_overall" class="price">' + overall + waehrung + '</td></tr>');
				}
				this.handleFlyout("show");
			},
			replaceJSONHref: function (href, session) {
				var hrefNew = href, repStr;
				if (href.search(/\$ext\$/) !== -1) {
					if (session) {
						repStr = '.htm;' + session;
					}
					else {
						repStr = '.htm';
					}
					hrefNew = href.replace('$ext$', repStr);
				}
				return hrefNew;
			},
			handleFlyout: function (mode) {
				if (mode === "show") {
					$(this.wkTopShell).addClass('wkFlyoutOuter');
					$('div.wkFlyout').show();
				}
				else {
					var self = this;
					$('div.wkFlyout').hide();
					$(this.wkTopShell).removeClass('wkFlyoutOuter');
					$(this.wkTopInner).unbind("mouseenter");
					$(this.wkTopInner).bind("mouseenter", function (e) {
						$(self.wkTopShell).addClass('wkFlyoutOuter');
						$('div.wkFlyout').show();
					});
					
				}
			}
		}
	);
// <<


// >> overlay image
	OverlayHandler = $.extend(
		$.clone(LLObject),
		{
			create: function () {
				var o = LLObject.create.call(this);
				o.banner = $('div.overlay');
				o.prepareBanner();
				return o;
			},
			prepareBanner: function () {
				var img, self;
				img = $(this.banner).find('img');
				self = this;
				$(img).bind("click", function (e) {
					self.handleBanner("hide");
				});
				this.handleBanner("show", img);
			},
			setPositions: function (img) {
				var marginLeft, marginTop, imgHeight, imgWidth;
				$(this.banner).height($(document).height());
				$(this.banner).width($(window).width());
				$(this.banner).find('div.des1').css('top', $(window).height() / 2);
				imgHeight = $(img).attr('height');
				imgWidth = $(img).attr('width');
				marginTop = Math.round(imgHeight / 2) * (-1) * 1.4;
				marginLeft = Math.round(imgWidth / 2) * (-1);
				$(img).css({'top': marginTop, 'left': marginLeft});
			},
			handleBanner: function (mode, img) {
				if (mode === "show") {
					$('td.msCont').prepend($(this.banner));
					$(this.banner).show();
					this.setPositions(img);
				}
				else {
					$(this.banner).hide();
				}
				
			}
		}
	);
//<<


// >> google analytics for payment methods
	PaymentMethodsAnalytics = $.extend(
		$.clone(LLObject),
		{
			create: function () {
				var o = LLObject.create.call(this);
				o.handlePaymentMethods();
				return o;
			},
			handlePaymentMethods: function () {
				var paymentRows, prompt;
				paymentRows = $('div.mOfPayContent div.item div.checkbox tr');
				paymentRows.each(function (i) {
					prompt = $(this).find('th.prompt span').text();
					$(this).find('td.ifield input').click(
						function () {
							_gaq.push(['_setCustomVar', 3, 'Zahlungsmoeglichkeiten', prompt, 2]);
						}
					);
				});
			}
		}
	);
// <<


// >> ShoppingcartOverlay
	ShoppingcartOverlay = $.extend(
		$.clone(LLObject),
		{
			create: function(){
				var o = LLObject.create.call(this);
				o.cartLink = null;
				o.readState = false;
				return o;
			},
			makeLayout: function(){
				var lay = $(
					'<div id="shoppingcartOverlay" class="shoppingcartOverlay">' +
						'<div class="articleInfoOuter">' +
							'<div class="hint">' + $.lang('shoppingcartOverlayHint') + '</div>' +
							'<div class="info"></div>' +
						'</div>' +
						'<div class="buttonsOuter viewport">' +
							'<div class="b1"></div>' +
							'<div class="b2"></div>' +
						'</div>' +
						'<iframe name="putArticleToShoppingcart"></iframe>' +
					'</div>'
				);
				lay.find('iframe').attr({
					src: '#',
					frameborder: 0,
					width: 0,
					height: 0
				}).css({
					visibility: 'hidden'
				});
				return lay;
			},
			makeInfoTableLayout: function(){
				return $(
					'<table cellpadding="0" cellspacing="0" border="0" class="overlayInfoTable">' +
						'<caption></caption>' +
					'</table>'
				);
			},
			makeInfoTableRow: function(){
				return $(
					'<tr>' +
						'<th></th>' +
						'<td></td>' +
					'</tr>'
				);
			},
			centerOverlay: function(){
				var ovl = $('#shoppingcartOverlay'), x, y, ovlWidth, ovlHeight;
				ovlWidth = ovl.width();
				ovlHeight = ovl.height();
				x = ($(window).width() - ovlWidth) / 2;
				y = ($(window).height() - ovlHeight) / 2 - 40 + $(window).scrollTop();
				ovl.css({'left': x, 'top': y});
			},
			getSessionWithExistingParamsOnDisabledCookies: function(){
				var href = null, sessId;
				if (!navigator.cookieEnabled && !Utils.getXist4cSessionId()){
					href = window.putArticleToShoppingcart.XIST4C_GLOBALS.sitemap[0].href;
					if (href.search(/\?/) > -1){
						href = href.substring(0, href.search(/\?/));
					}
					if (href.search(/;jsessionid=/) > -1){
						sessId = href.substring(href.search(/;jsessionid=/));
						return sessId;
					}
				}
				return '';
			},
			bindButtons: function(){
				var b1 = $('#shoppingcartOverlay .b1'),
				b2 = $('#shoppingcartOverlay .b2'), self = this, params = Utils.getUrlParamsAsJson() || '',
				url = window.location.href, sessId = this.getSessionWithExistingParamsOnDisabledCookies(),
				topWkHref = $('.wkTopShell a').attr('href');
				if (url.search(/\?/) > -1){
					url = url.substring(0, url.search(/\?/));
				}
				b1.bind('click', function(e){
					self.wkReadyState(false);
					window.location = [url,sessId].join('');
					$('#modalPane, #shoppingcartOverlay').fadeOut('fast');
				});
				b2.unbind().css({
					opacity: 0.3
				});
				setTimeout(function(){
					b2.bind('click', function(e){
						window.location = [topWkHref,sessId].join('');
						self.wkReadyState(false);
					}).css({
						opacity: 1
					});
				}, 2000);
			},
			showOverlay: function(){
				var data, modalPane, panel, table = this.makeInfoTableLayout(), row,
				slotPmt, slotValue, slotCurrItem, self = this, prdTitle = 'productTitle';
				if (FLYPI_CONFIGURATION_TYPE === 'sm'){
					if (typeof Sm_TabbedImageMode === 'object'){
						data = Sm_TabbedImageMode.data;
					}else{
						data = SlotMachine.data;
					}
				}else{
					if (!StepFilteredConfigurator.data){
						data = DisplayPilotMachine.data;
					}else{
						data = StepFilteredConfigurator.data;
					}
					prdTitle = 'productTitleorig';
				}
				modalPane = $('<div id="modalPane"></div>').hide();
				modalPane.width($(document).width());
				modalPane.height($(document).height());
				if ($('#modalPane').length == 0){
					$('body').append(modalPane);
				}
				panel = $('#shoppingcartOverlay');
				if (panel.length === 0){
					panel = this.makeLayout();
					$('body').append(panel);
				}
				panel.hide().find('.info').empty();
				if (typeof data.productImg !== 'undefined' && typeof data.productImg === 'object'){
					panel.find('.info').css({
						background: 'url(' + data.productImg.src + ') left top no-repeat'
					});
				}else{
					panel.find('.info').css({
						padding: 0
					});
				}
				// build panel
				table.find('caption').text(data[prdTitle]);
				if (typeof data.slots !== 'undefined'){
					$(data.slots).each(function(i){
						slotCurrItem = this.items[this.currentItem];
						slotPmt = this.title;
						slotValue = slotCurrItem.title;
						if (slotCurrItem.addInfoText){
							slotValue += ' (' + slotCurrItem.addInfoText + ')';
						}
						row = self.makeInfoTableRow().clone();
						row.find('th').text(slotPmt);
						row.find('td').text(slotValue);
						table.append(row);
					});
				}
				if (data.infoText){
					row = self.makeInfoTableRow().clone();
					row.find('th').text('Info');
					row.find('td').text(data.infoText);
					table.append(row);
				}
				panel.find('.info').append(table);
				this.centerOverlay();
				Utils.busyWait(
					function(intervalObj){
						if (
							window.putArticleToShoppingcart.XIST4C_GLOBALS && 
							window.putArticleToShoppingcart.XIST4C_GLOBALS.sitemap && 
							window.putArticleToShoppingcart.XIST4C_GLOBALS.sitemap[0]
						){
							return true;
						}
						return false;
					},
					100,
					500,
					function(intervalObj){
						self.bindButtons();
						$('#modalPane').show();
						$('#shoppingcartOverlay').fadeIn('slow');
					}
				);
			},
			wkReadyState: function(state){
				if (state){
					this.readyState = state;
					return state;
				}
				return this.readyState;
			},
			make: function(){
				var target = $('body'), form = $('.prdConfTopWkShell form'), self = this,
				topWkEntries = $('.wkTopShell a span.amount'), wkEntries, self = this;
				if (form.length){
					if (Utils.getXist4cSessionId()){
						this.cartLink = '/impressum.htm' + Utils.getXist4cSessionId({
							returnWithPrefix: true
						});
					}else{
						this.cartLink = '/impressum.htm';
					}
					form.attr({
						target: 'putArticleToShoppingcart'
					});
					Utils.busyWait(
						function(intervalObj){
							if (form.attr('action') == '#'){
								return true;
							}
							return false;
						},
						100,
						500,
						function(intervalObj){
							form.attr({
								action: self.cartLink
							});
						}
					),
					form.bind('submit', function(e){
						self.showOverlay();
						wkEntries = parseInt(topWkEntries.text()) + 1 ;
						topWkEntries.text(wkEntries);
					});
				}
			}
		}
	);
	
	// spy on slotmachines
	$(function(){
		if (typeof FLYPI_CONFIGURATION_TYPE !== 'undefined'){
			if (FLYPI_CONFIGURATION_TYPE === 'sm' || FLYPI_CONFIGURATION_TYPE === 'xxl'){
				SCart_Overlay = ShoppingcartOverlay.create();
				SCart_Overlay.make();
			}
		}
	});
// <<


/* >> Move top wk shell to bottom container */
	MoveTopContainterToBottom = $.extend(
		$.clone(LLObject),
		{
			create: function (el, newBannerName) {
				var o = LLObject.create.call(this);
				o.bottomContainer = $('div.pageBottomContainer');
				o.bottomContainerClassPrefix = "pbSty";
				o.moveContainer(el, newBannerName);
				return o;
			},
			moveContainer: function (el, newBannerName) {
				var newContainer, newContainerWrap, containerClass;
				if (newBannerName){
					containerClass = this.bottomContainerClassPrefix + " " + newBannerName;
				} else {
					containerClass = this.bottomContainerClassPrefix + " " + 'newBottomContainer';
				}
				newContainerWrap = '<div class="' + containerClass + '" />';
				this.bottomContainer.append(el.wrap('' + newContainerWrap).parent('div'));
				el.show();
			}
		}
	);
/* << */


/* >> Handle chat mode text */
	ChatModeTextHandler = $.extend(
		$.clone(LLObject),
		{
			create: function () {
				var o = LLObject.create.call(this);
				o.waitForChat();
				return o;
			},
			waitForChat: function () {
				var self = this;
				Utils.busyWait(
					function () {
						if ($('#service_chat .chatLink').length) {
							return true;
						}
						return false;
					},
					500,
					100,
					function () {
						self.handleChatText();
					}
				);
			},
			handleChatText: function () {
				var chatModeText, mode, modeText, newHTML;
				chatModeText = $('#service_chat .chatLink').text();
				if (chatModeText.search('geöffnet') < 0) {
					mode = "closed";
					modeText = "geschlossen";
				} else {
					mode = "open";
					modeText = "geöffnet";
				}
				newHtml = 'Live Chat <span class="' + mode + '">' + modeText + '</span>';
				$('#service_chat a').html(newHtml);
			}
		}
	);
/* << */

// >>>> NEW STARTPAGE SCRIPTS
// >> Element randomizer
	ElementRandomizer = $.extend(
		$.clone(LLObject),
		{
			create: function(opts){
				var o = LLObject.create.call(this);
				o.defaults = {
					elms: null, // jQuery selected elements.
					maxElmsInOrder: 1, // How many elements are showed at the same time.
					initCallback: function(elms){
						elms.each(function(i){
							elms.hide();
						});
					},
					callback: function(elms, chosenElms){
						$(chosenElms).each(function(i){
							$(this).show();
						});
					}
				};
				if (opts && Utils.isObject(opts)){
					$.extend(o.defaults, opts);
				}
				return o;
			},
			init: function(){
				var elms = this.defaults.elms, elm, chosenElms = [], maxElms = this.defaults.maxElmsInOrder,
				icb = this.defaults.initCallback, cb = this.defaults.callback;
				if (Utils.isFunction(icb)){
					icb.call(this, elms);
				}
				if (elms.length){
					while(chosenElms.length != maxElms){
						elm = elms.eq(Math.floor(elms.length * 1000000 * Math.random()) / 1000000).get(0);
						if ($.inArray(elm, chosenElms) == -1){
							chosenElms.push(elm);
						}
					}
					if (Utils.isFunction(cb)){
						cb.call(this, elms, chosenElms);
					}
				}
			}
		}
	);
// <<

// >> LoadQuickfinder
	LoadQuickfinderXPopup = $.extend(
		$.clone(LLObject),
		{
			create: function(opts){
				var o = LLObject.create.call(this);
				o.defaults = {
					auf_id: null,
					freeConfig: true,
					sharedId: null,
					passiveBulletColor: null,
					activeBulletColor: null,
					shoppingcartSymbolColor: null
				};
				if (opts && typeof opts === 'object'){
					$.extend(o.defaults, opts);
				}
				return o;
			},
			init: function(){
				var tabs = $('#uiTab1'),
				url = '/sharedConfigurator/standard_de_sharingConfigurator.html';
				url += Utils.getUrlParamsFromJson(this.defaults, noEmptyParams = true);
				LL_XPopup.registerPopup(
					tabs.find('a.tabHead_quickfinder'),
					'click',
					'WEBPAGE',
					'p_c',
					'c',
					0,
					0,
					{
						url: url,
						height: 380,
						width: 780,
						background: 'true'
					},
					// function context 'this' is the xpopup content object instance.
					// 'action' is a string of the current xpopup action: 'close' | 'show' | 'load' | 'loadError'.
					function(action){
						if (action === 'close'){
							tabs.tabs('select', 0);
						}
					}
				);
			}
		}
	);
	$(function(){
		var co_id = null, opts;
		if (XIST4C_GLOBALS && XIST4C_GLOBALS.meta){
			co_id = XIST4C_GLOBALS.meta.coID;
		}
		if (co_id == 3886){ // premium
			opts = {
				sharedId: 5460,
				activeBulletColor: 'f6c535'
			};
		}else if (co_id == 3893){ // öko
			opts = {
				sharedId: 5450,
				activeBulletColor: '77a043'
			};
		}else{ // print
			opts = {
				sharedId: 4610
			};
		}
		LoadQuickfinderXPopup.create(opts).init();
	})
// <<

// >> Automatic tab switcher
	AutomaticTabSwitcher = $.extend(
		$.clone(LLObject),
		{
			create: function(opts){
				var o = LLObject.create.call(this);
				o.defaults = {
					target: null,
					interval: 6000,
					maxSwitches: 100,
					tabElm: null,
					stopOnUserAction: true
				};
				if (opts && Utils.isObject(opts)){
					$.extend(o.defaults, opts);
				}
				o.stopped = -1;
				o.interval = null;
				o.appendDataToTabs();
				if (o.defaults.stopOnUserAction){
					o.bindTabsWithUserAction();
				}
				return o;
			},
			bindTabsWithUserAction: function(){
				var tabs = this.defaults.tabElm, self = this;
				tabs.find('ul li a').bind('click', function(e){
					self.stop();
				});
			},
			appendDataToTabs: function(){
				var tabs = this.defaults.tabElm;
				if (tabs.length){
					tabs.data('AutomaticTabSwitcher', this);
				}
			},
			run: function(){
				var self = this, opts = this.defaults, tabs = opts.tabElm;
				this.stopped = -1;
				Utils.busyWait(
					function(intervalObj){
						self.interval = intervalObj;
						if (self.stopped === 1){
							return true;
						}
						var tabs = opts.tabElm, currTab = tabs.tabs('option', 'selected'),
						tabsCnt = tabs.find('ul li').length - 1;
						if (currTab == tabsCnt){
							currTab = 0;
						}else{
							currTab++;
						}
						tabs.tabs('option', 'selected', currTab);
						return false;
					},
					opts.interval,
					opts.maxSwitches,
					function(intervalObj){
					}
				);
			},
			stop: function(){
				this.stopped = 1;
				if (this.interval){
					clearInterval(this.interval);
					this.interval = null;
				}
			}
		}
	);
// <<

// >> Border sliding service tabs
	BorderSlidingServiceTabs = $.extend(
		$.clone(LLObject),
		{
			create: function(){
				var o = LLObject.create.call(this);
				o.domel = $('.globalLayerShell .socialMedia_flags');
				o.slideTabs = false;
				o.staticPos = 160;
				o.interval = null;
				return o;
			},
			init: function(){
				var self = this, win = $(window), domel = this.domel;
				if (domel.length){
					$('body').append(domel);
					this.interval = setInterval(function(){
						domel.animate({
							top: self.staticPos + win.scrollTop(),
							opacity: 1
						}, 300);
					}, 600);
				}
			}
		}
	);
	$(function(){
		ServiceTabs = BorderSlidingServiceTabs.create();
		ServiceTabs.init();
	});
// <<
// <<<<


/* >> LivingLogic Newsticker (requires jQuery 1.2.6 +) */
	LL_Newsticker = $.extend(
		$.clone(LLObject),
		{
			text: null,
			textWidth: null,
			target: null,
			duration: 10,
			width: 500,
			height: 20,
			scrollWidth: 1,
			startPos: 0,
			bidirectional: false,
			bidiSwitch: 1,
			onOver: null,
			onOut: null,
			onClick: null,
			scrollInterval: null,
			create: function(text, options){
				var o = LLObject.create.call(this);
				o.text = text;
				if (options && typeof options == 'object') o = $.extend(o, options);
				return o;
			},
			makeTickerLayout: function(){
				var t = $(
					'<div id="ll-nt-baseShell">' +
						'<div id="ll-nt-scrollPane" class="ll-nt-scrollPane">' +
							'<div id="ll-nt-textboxOuter" class="ll-nt-textboxOuter">' +
							'</div>' +
						'</div>' +
					'</div>'
				);
				var w = this.width;
				var h = this.height;
				var sty = {'width': w, 'height': h};
				t.css(sty).find('#ll-nt-scrollPane').css($.extend(sty, {'overflow': 'hidden'}));
				return t;
			},
			makeTickerTextElements: function(text){
				var te = $('<span class="ll-nt-textbox"></span>');
				te.html(text);
				return te;
			},
			scroll: function(scrollPane){
				var iv = this.scrollInterval;
				if (this.bidirectional){
					var width = this.width - this.textWidth;
					if (width < 0){
						width = this.textWidth - this.width;
					}
					if (this.startPos >= width && this.bidiSwitch == 1){
						this.bidiSwitch = -1;
					}
					if (this.startPos <= 0){
						this.bidiSwitch = 1;
					}
					this.startPos += this.scrollWidth * this.bidiSwitch;
				}else{
					this.startPos += this.scrollWidth;
					if (this.startPos >= this.textWidth){
						this.startPos = 0;
					}
				}
				scrollPane.scrollLeft(this.startPos);
				var self = this;
				if (!iv){
					this.scrollInterval = setInterval(function(){
						self.scroll(scrollPane);
					}, this.duration);
				}
			},
			getScrollPane: function(){
				return this.target.find('#ll-nt-scrollPane');
			},
			start: function(){
				if (this.bidirectional || this.textWidth > this.width){
					var scrollPane = this.getScrollPane();
					this.scroll(scrollPane);
				}
			},
			stop: function(){
				var scrollPane = this.getScrollPane();
				var iv = this.scrollInterval;
				if (iv){
					clearInterval(iv);
					this.scrollInterval = null;
				}
			},
			reset: function(){
				this.stop();
				this.startPos = 0;
				var scrollPane = this.getScrollPane();
				scrollPane.scrollLeft(this.startPos);
			},
			make: function(){
				if (this.target.size() > 0){
					var tar = this.target;
					var ticker = this.makeTickerLayout();
					tar.append(ticker);
					var te = this.makeTickerTextElements(this.text);
					var textBox = ticker.find('#ll-nt-textboxOuter');
					textBox.append(te);
					textWidth = this.textWidth = te.width();
					textBox.css({'width': textWidth});
					if (textWidth > this.width && !this.bidirectional){
						textBox.append(te.clone()).css({'width': textWidth * 2});
					}else if(this.bidirectional){
						if (textWidth < this.width){
							var padding = this.width - textWidth;
							te.css({'padding': '0 ' + padding, 'background': '#ccc'});
						}
					}
				}
			}
		}
	)
	
	Flyerpilot_Newsticker = $.extend(
		$.clone(LLObject),
		{
			load: function () {
				var text = $('#newsTickerText').text();
				$('#newsTickerText').text('');
				var ticker = LL_Newsticker.create(text, {'target': $('#newsTickerText'), 'width': 386, 'duration': 30});
				ticker.make();
				ticker.start()
			}
		}
	)
/* << */
