(function($){
	$.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;
		}
	});
	// i18n support
	$.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
				lang = $('html').attr('lang');
			if (!lang)
				lang = 'en';
			if (arguments.length == 0)
				return lang;
			if ($.lang._res && $.lang._res[name] && $.lang._res[name][lang])
				return $.lang._res[name][lang];
			return '?-invalid-language-resource-' + name + '-?';
		}
	});
	// date and time format
	$.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 y = y < 10 ? '0' + y : y;
			var md = d < 10 ? '0' + d : d;
			var mm = m + 1 < 10 ? '0' + (m + 1) : m + 1;
			var my = fy;
			if (lang == 'de'){
				return {
					'_short': d + sep + (m + 1) + sep + y,
					'_middle': md + sep + mm + sep + my,
					'_long': [md + sep,dateBox[lang].month[m],fy].join('&nbsp;')
				}
			}
			return {
				'_short': (m + 1) + sep + d + sep + y,
				'_middle': mm + sep + md + sep + my,
				'_long': [dateBox[lang].month[m] + sep,md,fy].join('&nbsp;')
			}
		},
		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 {'time': h + ':' + m + ':' + s, 'timeWithoutSec': h + ':' + m};
		}
	});
})(jQuery);


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);
	}
}


// >> Schnellsuche
	function changeQSAction(type){
		f = $('#quickSearch');
		i = $('#quickSearchAppName');
		
		if (type == "news"){
			f.attr({'action': '/xist4c/web/Suche_id_141_.htm'});
			i.val('');
		}else if(type == "stocks"){
			f.attr({'action': '/xist4c/web/Kurssuche_id_610_.htm'});
			i.val('');
		}
	}
// <<


// >> popup handling (require StandardPopup)
	function newPopup(href, name, height, width){
		var pup = new StandardPopup({'href': href, 'name': name, 'height': height, 'width': width});
		return pup.open();
	}
// <<

// >> client current date (require jquery 1.2.6+)
	CURRENT_DATE_INTERVAL = null;
	function getCurrentDate(id){
		var container = $('#' + id);
		container.empty();
		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 y = date.getFullYear();
		var std = date.getHours();
		var min = date.getMinutes();
		if (min < 10) min = "0" + min;
		container.append('<div>' + d + ', ' + dom + '. ' + m + ' ' + y + ', ' + std + ':' + min + ' Uhr</div>');
		if (!CURRENT_DATE_INTERVAL) CURRENT_DATE_INTERVAL = setInterval(function(){getCurrentDate(id)}, 1000);
	}
// <<


// >> abstract key event controller (require mochikit 1.4)
	function KeyActionListener(){
		this.connection = null;
		this.connectObject();
	}

	KeyActionListener.prototype.connectObject = function(){
	}
		
	KeyActionListener.prototype.actionPerformed = function(e){
	}
// <<


// >> Layered script navigation (requires MochiKit 1.4+)
	function LSNaviKeyActionListener(){
		this.connectObject();
	}
	LSNaviKeyActionListener.prototype = new KeyActionListener();
	LSNaviKeyActionListener.prototype.connectObject = function(){
		var self = this;
		$(document).bind('keydown', function(e){self.actionPerformed(e)});
	}

	LSNaviKeyActionListener.prototype.actionPerformed = function(e){
		if (e.keyCode == 27) LSNavi.resetPanels(e);
	}


	function LSNaviDocumentMouseActionListener(){
		this.connectObject();
	}
	LSNaviDocumentMouseActionListener.prototype = new KeyActionListener();
	LSNaviDocumentMouseActionListener.prototype.connectObject = function(){
		var self = this;
		$(document).bind('click', function(e){self.actionPerformed(e)});
	}

	LSNaviDocumentMouseActionListener.prototype.actionPerformed = function(e){
		LSNavi.resetPanels(e);
	}


	function LayeredScriptNavigation(){
		this.levels = 3;
		this.levelPanels = [];
		this.nodes = [];
		this.rootNode = null;
		this.level = 0;
		this.oldPath = [];
		this.panels = [];
		this.topNodeConnect = null;
		this.listeners = [];
	}
	
	LayeredScriptNavigation.prototype.init = function(levels){
		if (levels) this.levels = levels;
		this.makeLevelPanels();
		this.listeners.push(new LSNaviKeyActionListener());
		this.listeners.push(new LSNaviDocumentMouseActionListener());
	}
	
	LayeredScriptNavigation.prototype.hideFallbackNavi = function(id){
		$('#' + id).css({'display': 'none'});
	}

	LayeredScriptNavigation.prototype.registerNode = function(id){
		var self = this;
		setTimeout(function(){
			var elm = $('#' + id).get(0);
			var parentStyleName = elm.parentNode.className;
			var sty = null;
			if (parentStyleName.substring(0, 3) == 'co_') sty = parentStyleName;
			var nid = self.getNodeId(id);
			var pid = self.getParentId(id);
			var refelm = self.getNodeReferenceElement(id);
			var node = new Node(elm, nid, pid, refelm, sty);
			if (nid != pid){
				$(refelm).bind('mouseenter.showPanel', function(e){self.showPanel(nid, e)});
			}
			self.nodes[node.nid] = node;
		}, 10);
	}
	
	LayeredScriptNavigation.prototype.buildTree = function(){
		var ns = this.nodes;
		for (var node in ns){
			if (Number(node)){
				node = ns[node];
				if (node.nid != node.pid){
					var parent = ns[node.pid];
					node.parent = parent;
					parent.children.push(node);
				}else{
					this.rootNode = node;
				}
			}
		}
	}

	LayeredScriptNavigation.prototype.getParentId = function(id){
		return id.substring(id.lastIndexOf('_') + 1, id.length);
	}

	LayeredScriptNavigation.prototype.getNodeId = function(id){
		return id.substring(id.indexOf('_') + 1, id.lastIndexOf('_'));
	}

	LayeredScriptNavigation.prototype.getNodeReferenceElement = function(id){
		return $('#' + id.replace('n_', 'ref_')).get(0);
	}
	
	LayeredScriptNavigation.prototype.getNode = function(nid){
		return this.nodes[nid];
	}
	
	LayeredScriptNavigation.prototype.makeLevelPanels = function(){
		for (var i = 0; i < this.levels; ++i){
			var panel = $(
				'<div id="lsn_outerShell_' + i + '" class="lsn_outerShell_' + i + '" style="z-index: ' + (100 + i) +'">' +
					'<div id="lsn_innerShell_' + i + '" class="lsn_innerShell_' + i + '">' +
						'<div id="lsn_panel_' + i + '" class="lsn_panel_' + i + '" style="z-index: ' + i + '">' +
						'</div>' +
					'</div>' +
				'</div>'
			);
			this.levelPanels.push(panel.get(0));
		}
	}
	
	LayeredScriptNavigation.prototype.makePanelTitle = function(node){
		if (node.href){
			var title = $('<a class="lsn_title"></a>')
			.attr({'href': node.href})
			.html(node.title);
		}else{
			var title = $('<span class="lsn_title_here"></span>')
				.html(node.title);
		}
		return $('<div id="lsn_titleShell"></div>').append(title).get(0);
	}
		
	LayeredScriptNavigation.prototype.showPanel = function(nid, e){
		var node = this.getNode(nid);
		var level = node.getLevel() - 1;
		var parentNode = node.refelm.parentNode.parentNode.parentNode;
		if (level > 0) parentNode = node.refelm.parentNode.parentNode;
		var nodes = node.children;
		var childId = 1;
		var self = this;
		if (level > 0 && level < 2){
			$(node.parent.refelm).bind('mouseleave.topNodeConnect', function(e){self.resetPanels(e)});
		}
		if (nodes.length > 0){
			var panel = this.levelPanels[level];
			$(panel).css({'display': 'block'});
			var panelContentContainer = panel.childNodes[0].childNodes[0];
			var oldChildLength = panelContentContainer.childNodes.length;
			if (oldChildLength > 0) $(panelContentContainer).empty();
			if (level < 1) panelContentContainer.appendChild(this.makePanelTitle(node));
			for (var j = 0; j < nodes.length; ++j){
				(function(n, that){
					var newNode = $(n.elm);
					newNode.bind('mouseenter.showPanel', function(e){that.showPanel(n.nid, e)});
					if (n.sty){
						var outer = $('<div class="' + n.sty + '"></div>');
						outer.append(newNode);
						$(panelContentContainer).append(outer);
					}else{
						$(panelContentContainer).append(newNode);
					}
				})(nodes[j], self);
			}
			if (level > 0){
				$(panel).prependTo($(parentNode.childNodes[0]));
				$(panelContentContainer).css({'display': 'none'});
			}else{
				parentNode.appendChild(panel);
			}
			$(panelContentContainer).show();
		}
	}
	
	LayeredScriptNavigation.prototype.inArray = function(item, arr){
		for (var i = 0; i < arr.length; ++i){
			if (item == arr[i]) return true;
		}
		return false;
	}
	
	LayeredScriptNavigation.prototype.resetPanels = function(e){
		$('table.layeredScriptNavi a').unbind('mouseleave.topNodeConnect');
		for (var i = 0; i < this.levelPanels.length; ++i){
			$(this.levelPanels[i]).css({'display': 'none'});
			$(this.levelPanels[i].childNodes[0].childNodes[0]).css({'display': 'none'});
		}
	}

	LayeredScriptNavigation.prototype.showNavigation = function(target){
		var self = this;
		var target = $('#' + target).empty();
		setTimeout(function(){
			self.buildTree();
			var nodesBody = $('<tr></tr>');
			var firstChildren = self.rootNode.children;
			nodesBody.append(self.getColumn(self.rootNode));
			for (var i = 0; i < firstChildren.length; ++i){
				nodesBody.append(self.getColumnSeparator());
				nodesBody.append(self.getColumn(firstChildren[i]));
			}
			var nodesShell = $('<table cellpadding="0" cellspacing="0" border="0" class="layeredScriptNavi"></table>')
				.append(nodesBody);
			target.append(nodesShell);
		}, 1000);
	}
	
	LayeredScriptNavigation.prototype.getColumn = function(node){
		var td = $('<td class="item"></td>').append($(node.elm));
		return td;
	}

	LayeredScriptNavigation.prototype.getColumnSeparator = function(){
		return $('<td class="sep"><img src="../px/spc.gif" width="1" height="1"/></td>');
	}

	// Layered script navigation Node
	function Node(elm, nid, pid, refelm, sty){
		this.elm = elm;
		this.nid = nid;
		this.pid = pid;
		this.sty = sty;
		this.href = this.getLink();
		this.title = this.getTitle();
		this.refelm = refelm;
		this.children = [];
		this.parent = null;
		this.panel = null;
	}
	
	Node.prototype.getLink = function(){
		var n = this.elm;
		while (n){
			var nName = n.nodeName.toLowerCase();
			var type = n.nodeType;
			if (type == 1 && nName == 'a') return n.href;
			n = n.childNodes[0];
		}
		return null;
	}
	
	Node.prototype.getTitle = function(){
		var n = this.elm;
		while (n){
			if (n.nodeType == 1) n = n.childNodes[0];
			if (n.nodeType == 3) return n.nodeValue;
		}
		return 'foo';
	}
	
	Node.prototype.getLevel = function(){
		var node = this;
		var level = 0;
		while (node.parent){
			node = node.parent;
			++level;
		}
		return level;
	}
	
	Node.prototype.getPath = function(){
		var node = this;
		var path = [];
		while (node){
			path.push(node);
			node = node.parent;
		}
		path.reverse();
		return path;
	}
	
	Node.prototype.__repr__ = function(){
		return "title: " + this.title + " nid: " + this.nid + " pid: " + this.pid + " Stylename: " + this.sty + " parent: " + this.parent + " children: " + this.children;
	}
// <<


LSNavi = new LayeredScriptNavigation();
LSNavi.init(3);


/* >> utilities requires jQuery 1.2.6 Version: rel-1-0-0 */
	/**
	 * @author: LivingLogic AG / Peter Boeker
	 * @arguments: []
	 * @arguments description:
	 * @description:
	 * return: void
	 * TODO: nothing to do
	 * Known bugs: nothing known
	 */
	Utils = {
		pixelPath: 'resources/img/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){
			if (!url) var url = window.location.href;
			if (url.search(/\?/) > -1){
				var urlParams = url.substring(url.search(/\?/) + 1 , url.length);
				urlParams = urlParams.split('&');
				jParams = {};
				$(urlParams).each(function(i){
					var parVal = this.split('=');
					jParams[decodeURI(parVal[0])] = decodeURI(parVal[1]);
				});
				return jParams;
			}
			return null;
		},
		getUrlParamsFromJson: function(params){
			var paramStr = '?';
			for (var k in params){
				paramStr += [encodeURI(k),'=',encodeURI(params[k]),'&'].join('');
			}
			return paramStr.substring(0, paramStr.length - 1);
		},
		stripTags: function(str){
			if (typeof str == 'string') return str.replace(/<\/?[^>]+>/gi, '');
			return null;
		},
		parseDeFloat: function(f){
			var f = f.replace(/\./g, '');
			f = f.replace(/\,/, '.');
			return f;
		}
	}
/* << */


/* >> AJAX URL Manager jQuery 1.2.6 Version: rel-1-0-0 */
	AjaxURLManager = {
		mode: 'static',
		URL: {},
		sessionData: null,
		baseURL: '/datagateway/',
		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('indexlist', null, 'json_stockinfoTable_test.text', false);
	AjaxURLManager.registerKey('dbflyout', null, 'json_deutscheBankFlyout_test.text', false);
	AjaxURLManager.registerKey('dboverview', null, 'json_deutscheBankOverview_test.text', false);
	AjaxURLManager.registerKey('dboverviewlist', null, 'json_deutscheBankOverviewList_test.text', false);
	AjaxURLManager.registerKey('dbrelatedproducts', null, 'json_deutscheBankRelatedProducts_test.text', false);
	AjaxURLManager.registerKey('boersenkiosk', null, null, false);
/* << */


/* >> i18n (requires LL lang extension and jQuery 1.2 6 +) */
	$.lang('tipOfTheDay', {
		'de': 'Tipp des Tages',
		'en': 'Tip of the day'
	});
	$.lang('noIframeSupport', {
		'de': 'Dieser Browser unterstützt leider keine eingebetteten Frames!',
		'en': 'This browser has no support for embeded frames!'
	});
	$.lang('powereditorVideoHeadline', {
		'de': 'Video zum Thema',
		'en': 'Related Video'
	});
/* << */


/* >> json panel content renderer require jQuery 1.2.6 Version: rel-1-0-0 */
	JSONPanelContentRenderer = {
		parent: null,
		panelId: null,
		target: null,
		targetId: null,
		idPrefix: null,
		data: null,
		render: function(data, parent, target){
			this.data = data;
			this.parent = parent;
			this._cacheDataToParent(data);
			this.target = target;
			switch (data.type){
				case 'stockinfoTable':
					this.renderStockinfoTable(data);
					break;
				case 'deutscheBankOverviewList':
					this.renderDeutscheBankOverviewList(data);
					break;
				case 'deutscheBankRelatedProducts':
					this.renderDeutscheBankRelatedProducts(data);
					break;
			}
		},
		renderStockinfoTable: function(data, target, callback, dontClearBefore){
			var t = $('<table cellpadding="0" cellspacing="0" border="0"></table>');
			if (data.stylename) t.attr({'class': data.stylename});
			var tar = this.target;
			if (target) tar = target;
			if (! dontClearBefore) tar.empty();
			var self = this;
			if (data.allowSearch){
				this._makeMenuBarAndContentShell();
				this._renderSearchFieldBar('searchWknIsinName');
			}
			var parent = self.parent;
			if (data.columnOrder){
				var r = $('<tr></tr>');
				$(data.columnOrder).each(function(i){
					var c = $('<th class="thead thead' + i + '"><span>' + this.header + '</span></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){
							var listKey = 'rows';
							(function(p, k){
								if (k != p.orderKey) p.orderBy = 0;
								// order values description: 0 = no order; 1 = order ascending; 2 = order descending.
								p.orderBy = p.orderBy == 1 ? 2 : 1 //(p.orderBy + 1) % 2;
								p.prepareContCacheWithOrder(listKey, key);
								p.renderContentWithContCache(tar);
							})(parent, key);
						});
					}
					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.attr({'class': 'odd'});
				if (this.special) r.addClass('special');
				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 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){
							if (cell.title.__datetime__){
								var title = $('<span>' + $.formatDate(cell.title.value, $.lang())._middle  + '&nbsp;' + $.formatTime(cell.title.value).time + '</span>');
							}else if (typeof cell.title == 'object' && cell.title.type == 'relation'){
								var title = self._getRelationTableLayout(cell.title.mode, cell.title.width);
							}else if (typeof cell.title == 'object' && cell.title.type == 'additionalButtons'){
								var title = self._getAdditionalButtonsLayout(cell.title.chartUrl, cell.title.newsUrl);
							}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 + '"></a>');
						}else{
							if (k == 'deutscheBank'){
								var title = self._getCellWithDeutscheBankService(row[data.pk]);
								c.append(title);
							}
						}
						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 + '"></a>');
						r.append(c);
						cnt++;
					}
				}
				t.append(r);
			});
			if (data.allowSearch){
				tar.find('div[id$=_content]').append(t);
			}else{
				tar.append(t);
			}
		},
		renderDeutscheBankOverviewList: function(data, target, callback, dontClearBefore){
			var t = $('<table cellpadding="0" cellspacing="0" border="0"></table>');
			if (data.stylename) t.attr({'class': data.stylename});
			var tar = this.target;
			if (target) tar = target;
			if (! dontClearBefore) 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;
			$(rows).each(function(i){
				r = $('<tr></tr>');
				if (i % 2 != 0) r.attr({'class': 'odd'});
				if (this.special) r.addClass('special');
				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 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){
							if (cell.title.__datetime__){
								var title = $('<span>' + $.formatDate(cell.title.value, $.lang()).middle  + '</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>');
								}
							}
						}else{
							var title = $('<span>-</span>');
						}
						c.append(title);
						if (cell.href) title.wrap('<a href="' + cell.href + '"></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 + '"></a>');
						r.append(c);
						cnt++;
					}
				}
				t.append(r);
			});
			if (data.allowSearch){
				tar.find('div[id$=_content]').append(t);
			}else{
				tar.append(t);
			}
		},
		renderDeutscheBankRelatedProducts: function(data, target, callback, dontClearBefore){
			this.renderStockinfoTable(data, target, callback, dontClearBefore);
		},
		_cacheDataToParent: function(data){
			var p = this.parent;
			if (p){
				p.contCache = data;
			}
		},
		_getRelationTableLayout: function(mode, width){
			var spacerTpl = $(
				'<div class="stdSpacer">' +
						'<img height="1" width="1" src="../px/spc.gif" alt=""/>' +
				'</div>'
			);
			var lay = $(
				'<table cellpadding="0" cellspacing="0" border="0" class="stdRelation">' +
					'<tr>' +
						'<td class="cLeft"></td>' +
						'<td class="middle">' +
							'<img height="1" width="1" src="../px/spc.gif" alt=""/>' +
						'</td>' +
						'<td class="cRight"></td>' +
					'</tr>' +
				'</table>'
			);
			var spcLeft = spacerTpl.clone();
			var spcRight = spacerTpl.clone();
			if (width > 0){
				if (mode == 1){
					spcRight.css({'background-position': (-100 + width) + ' 0'});
				}else{
					spcLeft.css({'background-position': (30 - width) + ' 0'});
				}
			}
			lay.find('.cLeft').append(spcLeft);
			lay.find('.cRight').append(spcRight);
			return lay;
		},
		_getAdditionalButtonsLayout: function(chartUrl, newsUrl){
			var lay = $(
				'<div class="additionalButtons"><div class="floatTerm"></div></div>'
			);
			var buttonTpl = $('<a href="" class="button"></a>');
			var dummyButtonTpl = $('<div class="dummyButton"></div>');
			if (chartUrl){
				var b = buttonTpl.clone();
				b.attr({'href': chartUrl}).addClass('buttonChart');
				lay.prepend(b);
			}else{
				var b = dummyButtonTpl.clone();
				lay.prepend(b);
			}
			
			if (newsUrl){
				var b = buttonTpl.clone();
				b.attr({'href': newsUrl}).addClass('buttonNews');
				lay.prepend(b);
			}else{
				var b = dummyButtonTpl.clone();
				lay.prepend(b);
			}
			return lay;
		},
		_getCellWithDeutscheBankService: function(isin){
			var lay = $(
				'<div class="viewport dbSymbol">' +
					'<div class="panel">' +
						'<div class="inner"></div>' +
					'</div>' +
				'</div>'
			);
			lay.bind('mouseenter', function(e){
				$('.dbSymbol .panel').hide();
				var url = AjaxURLManager.getUrlWithKey('dbflyout', {'isin': isin});
				var panelInner = $(this).find('.inner').empty();
				var elm = $(this);
				$.getJSON(url, function(data, textStatus){
					$('.dbSymbol .panel').hide();
					var title = $('<div class="prdTitle">Produkte zu ' + data.akt_name + '</div>');
					panelInner.append(title);
					var tpl = $('<div class="dbItem"></div>');
					$(data.items).each(function(i){
						var item = tpl.clone();
						item.text(this.prompt);
						var d = this;
						item.bind('click', function(e){
							window.location = '/xist4c/web/Deutsche-Bank_id_2102_.htm?aib=' + data.akt_id_basis + '&lit=' + d.lup_id_typ;
						});
						panelInner.append(item);
					});
					elm.find('.panel').show();
				});
			});
			lay.find('.panel').bind('mouseleave', function(e){
					$(this).hide();
			});
			return lay;
		}
	}
/* << */


/* >> tabbed elements require jQuery 1.2.6 Version: rel-1-1-0 */
	TabbedElements = {
		tabGroups: [],
		tabsCont: null,
		tabsOuter: null,
		defaults: {
			actionEvent: 'click'
		},
		register: function(tabEl, activeId, opts){
			if (opts && typeof opts == 'object') this.defaults = $.extend(this.defaults, opts);
			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(this._getDefault('actionEvent'), 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'});
			}
			
		},
		_getDefault: function(name){
			if (name && typeof this.defaults[name] != 'undefined'){
				return this.defaults[name];
			}
		},
		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;
		}
	}
/* << */


// >> Standard Ajax methods
	function getXMLHttpReqObj(){
		req = false;
		if (window.XMLHttpRequest){
			try{
				req = new XMLHttpRequest();
			}catch(e){
				req = false;
			}
		}else if (window.ActiveXObject){
			try{
				req = new ActiveXObject("Msxml2.XMLHTTP");
			}catch(e){
				try{
					req = new ActiveXObject("Microsoft.XMLHTTP");
				}catch(e){
					req = false;
				}
			}
		}
		return req;
	}
// <<


// >> Ajax for tab controlled charts
	function TabGroup(gId, tCount){
		this.gId = gId;
		this.tCount = tCount;
		this.tabs = new Array();
		this.activeId = null;
		this.tabPrefix = "tab_";
		for (i = 0; i < this.tCount; i++){
			if (document.getElementById(this.tabPrefix + this.gId + "_infin_" + i)){
				tabId = this.tabPrefix + this.gId + "_infin_" + i;
				tabEl = document.getElementById(tabId);
				this.tabs.push(new Tab(tabId, tabEl, true));
			}else{
				tabId = this.tabPrefix + this.gId + "_" + i;
				tabEl = document.getElementById(tabId);
				this.tabs.push(new Tab(tabId, tabEl));
			}
		}
	}
		
	TabGroup.prototype.doChartRequest = function(tId, target){
		this.req = getXMLHttpReqObj();
		if (this.activeId != null){
			oldTab = this.tabs[this.activeId];
			oldTab.deactivate(this.req);
		}
		tab = this.tabs[tId];
		tab.target = document.getElementById(target);
		this.activeId = tId;
		if (this.req){
			var that = this;
			this.req.onreadystatechange = function(){that.processChartReq(tab);};
			tab.activate(this.req);
		}
		return false;
	}
	
	TabGroup.prototype.processChartReq = function(tab){
		if (this.req.readyState < 4){
			tab.chartIsLoading();
		}else if (this.req.readyState == 4){
			if (this.req.status == 200){
				window.setTimeout("tab.present()", 1000);
				tab.changeTargetSrc(this.req);
			}else{
				tab.chartLoadingAborted();
				tab.present();
			}
		}
		return false;
	}
	
	function Tab(tId, tabEl, infinite){
		this.id = tId;
		this.tabEl = tabEl;
		this.target = null;
		this.chatIsLoadingSrc = ""
		if (infinite === undefined){
			this.styNames = new Array("stdTBItem", "tabLoading", "stdTBItemHere");
		}else{
			this.styNames = new Array("infinTBItem", "tabInfinLoading", "infinTBItemHere");
		}
	}
		
	Tab.prototype.deactivate = function(toAbortReq){
		attrNode = document.createAttribute("class");
		attrNode.nodeValue = this.styNames[0];
		this.tabEl.setAttributeNode(attrNode);
		if (toAbortReq){
			toAbortReq.abort();
		}
	}
	
	Tab.prototype.activate = function(req){
		attrNode = document.createAttribute("class");
		attrNode.nodeValue = this.styNames[1];
		this.tabEl.setAttributeNode(attrNode);
		req.open('GET', this.tabEl.href, true);
		req.send(null);
	}
	
	Tab.prototype.present = function(){
		attrNode = document.createAttribute("class");
		attrNode.nodeValue = this.styNames[2];
		this.tabEl.setAttributeNode(attrNode);
	}
	
	Tab.prototype.changeTargetSrc = function(req){
		this.target.src = req.responseText;
	}
	
	Tab.prototype.chartIsLoading = function(){
		this.target.src = 'aktionaer/01/img/chartIsLoading.png';
	}

	Tab.prototype.chartLoadingAborted = function(){
		this.target.src = 'aktionaer/01/img/chartLoadingAborted.png';
	}
// <<

// >> Ajax for single charts with timed refresh
	function InvChart(isin, chartTpl, period, target, refreshTime){
		this.req = null;
		this.isin = isin;
		this.chartTpl = chartTpl;
		this.period = period;
		this.targetObj = document.getElementById(target);
		this.rTime = refreshTime;
		this.mSecOp = 60000;
		this.urlPref = '/charts/';
	}

	InvChart.prototype.getURL = function(){
		return this.urlPref + this.isin.toUpperCase() + '.html';
	}

	InvChart.prototype.requestChartHTML = function(){
		this.req = getXMLHttpReqObj();
		if (this.req){
			var that = this;
			this.req.onreadystatechange = function(){that.processChartReq();};
			this.req.open('GET', this.getURL(), true);
			this.req.send(null);
		}
		return false;
	}
	
	InvChart.prototype.cloneXML2DOM = function(src, tar, igRoot){
		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++){
							if (node.attributes[j].nodeName.toLowerCase() == 'class'){
								newNode.className = node.attributes[j].nodeValue;
							}else{
								newNode.setAttribute(node.attributes[j].nodeName, node.attributes[j].nodeValue);
							}
						}
						this.cloneXML2DOM(node, newNode, false);
						break;
					}else{
						this.cloneXML2DOM(node, tar, false);
						break;
					}
				case 3:
					subNode = document.createTextNode(node.nodeValue);
					tar.appendChild(subNode);
			}
		}
	}

	InvChart.prototype.showProcessBar = function(path){
		imgEl = document.createElement("img");
		imgEl.src = path;
		imgEl.border = 0;
		imgEl.alt = "loading chart ....";
		if (this.targetObj.childNodes.length > 0){
			this.targetObj.replaceChild(imgEl, this.targetObj.childNodes[0]);
		}else{
			this.targetObj.appendChild(imgEl);
		}
	}

	InvChart.prototype.showNotFoundImg = function(path){
		imgEl = document.createElement("img");
		imgEl.src = path;
		imgEl.border = 0;
		imgEl.alt = "Chart not found";
		if (this.targetObj.childNodes.length > 0){
			this.targetObj.replaceChild(imgEl, this.targetObj.childNodes[0]);
		}else{
			this.targetObj.appendChild(imgEl);
		}
	}

	InvChart.prototype.showChartImage = function(resXML){
		while (this.targetObj.childNodes.length){
			this.targetObj.removeChild(this.targetObj.childNodes[0]);
		}
		this.cloneXML2DOM(resXML, this.targetObj, true);
	}

	InvChart.prototype.processChartReq = function(){
		if (this.chartTpl == '1'){
			path = 'aktionaer/01/img/thumbChartInProcess.gif';
			pathNotFound = 'aktionaer/01/img/thumbChartNotFound.gif';
		}else if(this.chartTpl == '0'){
			path = 'aktionaer/01/img/bigChartInProcess.gif';
			pathNotFound = 'aktionaer/01/img/bigChartNotFound.gif';
		}
		if (this.req.readyState < 4){
			this.showProcessBar(path);
		}else if (this.req.readyState == 4){
			var that = this;
			if (this.req.status == 200 && this.req.responseXML){
				this.showChartImage(this.req.responseXML);
				if (this.rTime != 0){
					window.setTimeout(function(){that.requestChartHTML();}, this.rTime * this.mSecOp);
				}
			}else if (! this.req.responseXML || this.req.status >= 400){
				this.showNotFoundImg(pathNotFound);
				if (this.rTime != 0){
					window.setTimeout(function(){that.requestChartHTML();}, this.rTime * this.mSecOp);
				}
			}
		}
	}


	function FlatexInvChart(isin, chartTpl, period, target, refreshTime){
		this.req = null;
		this.isin = isin;
		this.chartTpl = chartTpl;
		this.period = period;
		this.targetObj = document.getElementById(target);
		this.rTime = refreshTime;
		this.mSecOp = 60000;
		this.urlPref = '/flatexcharthtml/';
	}

	FlatexInvChart.prototype.getURL = function(){
		return this.urlPref + this.isin.toUpperCase() + '/' + this.period + '/' + this.chartTpl;
		//return this.urlPref + "depotliga_miniChartsTest.xml";
	}

	FlatexInvChart.prototype.requestChartHTML = function(){
		this.req = getXMLHttpReqObj();
		if (this.req){
			var that = this;
			this.req.onreadystatechange = function(){that.processChartReq();};
			this.req.open('GET', this.getURL(), true);
			this.req.send(null);
		}
		return false;
	}
	
	FlatexInvChart.prototype.cloneXML2DOM = function(src, tar, igRoot){
		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++){
							if (node.attributes[j].nodeName.toLowerCase() == 'class'){
								newNode.className = node.attributes[j].nodeValue;
							}else{
								newNode.setAttribute(node.attributes[j].nodeName, node.attributes[j].nodeValue);
							}
						}
						this.cloneXML2DOM(node, newNode, false);
						break;
					}else{
						this.cloneXML2DOM(node, tar, false);
						break;
					}
				case 3:
					subNode = document.createTextNode(node.nodeValue);
					tar.appendChild(subNode);
			}
		}
	}

	FlatexInvChart.prototype.showProcessBar = function(path){
		imgEl = document.createElement("img");
		imgEl.src = path;
		imgEl.border = 0;
		imgEl.alt = "loading chart ....";
		if (this.targetObj.childNodes.length > 0){
			this.targetObj.replaceChild(imgEl, this.targetObj.childNodes[0]);
		}else{
			this.targetObj.appendChild(imgEl);
		}
	}

	FlatexInvChart.prototype.showNotFoundImg = function(path){
		imgEl = document.createElement("img");
		imgEl.src = path;
		imgEl.border = 0;
		imgEl.alt = "Chart not found";
		if (this.targetObj.childNodes.length > 0){
			this.targetObj.replaceChild(imgEl, this.targetObj.childNodes[0]);
		}else{
			this.targetObj.appendChild(imgEl);
		}
	}

	FlatexInvChart.prototype.showChartImage = function(resXML){
		while (this.targetObj.childNodes.length){
			this.targetObj.removeChild(this.targetObj.childNodes[0]);
		}
		this.cloneXML2DOM(resXML, this.targetObj, true);
	}

	FlatexInvChart.prototype.processChartReq = function(){
		if (this.chartTpl == '1'){
			path = 'aktionaer/01/img/thumbChartInProcess.gif';
			pathNotFound = 'depotliga/01/img/thumbChartNotFound.gif';
		}else if(this.chartTpl == '0'){
			path = 'aktionaer/01/img/bigChartInProcess.gif';
			pathNotFound = 'aktionaer/01/img/bigChartNotFound.gif';
		}
		if (this.req.readyState < 4){
			this.showProcessBar(path);
		}else if (this.req.readyState == 4){
			var that = this;
			if (this.req.status == 200){
				this.showChartImage(this.req.responseXML);
				if (this.rTime != 0){
					window.setTimeout(function(){that.requestChartHTML();}, this.rTime * this.mSecOp);
				}
			}else if (this.req.status >= 400){
				this.showNotFoundImg(pathNotFound);
				if (this.rTime != 0){
					window.setTimeout(function(){that.requestChartHTML();}, this.rTime * this.mSecOp);
				}
			}
		}
	}	
// <<


// >> table sorter (require mochikit 1.4+) Version: rel-1-0-0
	/*
		DEPRECATION WARNING for sort modes:
		Mode isin, wkn, time are obsolete sorting criterion.
		Use mode text instead.
	*/
	function TableSorter(){
		this.tableId = null;
		this.tableHead = null;
		this.tableRows = [];
		this.colId = 0;
		this.config = null;
		this.sortDirection = 0;
		this.here = null
	}
	
	TableSorter.prototype.init = function(args){
		this.tableId = args.tableId;
		if (args.sortDirection) this.sortDirection = args.sortDirection;
		if (args.config && typeof args.config == 'object') this.config = args.config;
		this.loadTableRowsAndSeparateHead();
		this.prepareTableHead();
		if (args.initSortDefault > -1){
			var sCol = args.initSortDefault;
			if (sCol > this.config.length - 1) sCol = 0;
			var c = this.config[sCol];
			this.sortColumnWithMode(sCol, c.sortMode, c.useDifferentColumn, null);
		}
	}
	
	TableSorter.prototype.loadTableRowsAndSeparateHead = function(){
		this.tableRows = [];
		var tBody = $('#' + this.tableId).get(0).childNodes[0];
		for (var i = 0; i < tBody.childNodes.length; ++i){
			if (i == 0){
				this.tableHead = tBody.childNodes[i];
			}else{
				if (tBody.childNodes[i].style.display != 'none'){
					this.tableRows.push(tBody.childNodes[i]);
				}
			}
		}
	}
	
	TableSorter.prototype.prepareTableHead = function(){
		var hCols = this.tableHead.childNodes;
		var conf = this.config;
		for (var i = 0; i < hCols.length; ++i){
			var hc = hCols[i];
			var c = conf[i];
			if (c.sortMode){
				var prompt = false;
				if (! c.prompt) prompt = this.getColumnValue(this.tableHead, i);
				hc.innerHTML = '';
				hc.appendChild(this.makeTablePrompt(i, prompt));
			}
		}
	}
	
	TableSorter.prototype.makeTablePrompt = function(cId, prompt){
		var c = this.config[cId];
		var pmt = prompt ? prompt : c.prompt;
		var content = $(
			'<div class="sortingPromptOuter">' +
				'<a href="#" class="sortableColumn"><span>' + pmt + '</span><img src="../px/spc.gif" alt=""/></a>' +
			'</div>'
		);
		var self = this;
		content.find('a').bind('click', function(e){self.sortColumnWithMode(cId, c.sortMode, c.useDifferentColumn, e)});
		return content.get(0);
	}
	
	TableSorter.prototype.replaceTableRows = function(){
		var trs = this.tableRows;
		var tbody = $('#' + this.tableId).get(0).childNodes[0];
		for (var i = 0; i < trs.length; ++i){
			var className = (i % 2 == 0) ? null : 'odd';
			$(trs[i]).attr('class', className);
			tbody.appendChild(trs[i]);
		}
	}
	
	TableSorter.prototype.sortColumnWithMode = function(colId, sortMode, diffCol, e){
		if (e) e.preventDefault();
		var startSorting = 'sort_' + sortMode;
		this.here = colId;
		if (diffCol) colId = diffCol;
		this.colId = colId;
		var that = this;
		function compare(a, b){
			if (a.style.display == 'none' && b.style.display != 'none'){
				return -1;
			}else if (a.style.display != 'none' && b.style.display == 'none'){
				return 1;
			}else{
				return eval('that.' + startSorting + '(a, b)');
			}
		}
		this.tableRows.sort(compare);
		if (this.sortDirection == 1){
			this.tableRows.reverse();
			this.sortDirection = 0;
		}else{
			this.sortDirection = 1;
		}
		this.activateSortingImagePlaceholder();
		this.highlightColumn();
		this.replaceTableRows();
	}
	
	TableSorter.prototype.activateSortingImagePlaceholder = function(){
		var here = this.here;
		for (var i = 0; i < this.tableHead.childNodes.length; ++i){
			var hCol = this.tableHead.childNodes[i];
			var img = hCol.getElementsByTagName('img');
			$(img[0]).css({'border': 'none'});
			if (i == here){
				var styName = this.sortDirection ? 'sortUp': 'sortDown';
				$(img[0]).attr('class', styName);
			}else{
				$(img[0]).attr('class', null);
			}
		}
	}

	TableSorter.prototype.highlightColumn = function(){
		var rows = this.tableRows;
		var sty, col;
		for (var i = 0; i < rows.length; ++i){
			var cols = rows[i].childNodes;
			for (var j = 0; j < cols.length; ++j){
				col = cols[j];
				var attr = $(col).attr('class');
				attr = attr.replace(/\ssorted.+/, '');
				if (j == this.here){
					if (i < 1){
						attr += ' sorted_first';
					}else if ((i + 1) == rows.length){
						attr += ' sorted_last';
					}else{
						attr += ' sorted_inner';
					}
					$(col).attr('class', attr);
				}else{
					$(col).attr('class', attr);
				}
			}
		}
	}

	TableSorter.prototype.getColumnValue = function(tr, id){
		node = tr.childNodes[id];
		while (node.nodeType == 1){
			node = node.firstChild;
		}
		return node.nodeValue;
	}
	
	TableSorter.prototype.sort_text = function(a, b){
		var av = this.getColumnValue(a, this.colId);
		var bv = this.getColumnValue(b, this.colId);
		if (av == bv){
			return 0;
		}else if(av < bv){
			return -1;
		}else if(av > bv){
			return 1;
		}
	}

	/* DEPRECATED: Use sort mode text instead */
	TableSorter.prototype.sort_isin = function(a, b){
		return this.sort_text(a, b);
	}

	/* DEPRECATED: Use sort mode text instead */
	TableSorter.prototype.sort_wkn = function(a, b){
		return this.sort_text(a, b);
	}
	
	TableSorter.prototype.sort_integer = function(a, b){
		var av = this.getColumnValue(a, this.colId);
		var bv = this.getColumnValue(b, this.colId);
		av = av.replace(/\./g, '');
		av = av.replace(/\,/g, '');
		av = av.replace(/\±/g, '');
		av = parseInt(av);
		bv = bv.replace(/\./g, '');
		bv = bv.replace(/\,/g, '');
		bv = bv.replace(/\±/g, '');
		bv = parseInt(bv);
		return av - bv;
	}

	TableSorter.prototype.sort_float = function(a, b){
		var av = this.getColumnValue(a, this.colId);
		var bv = this.getColumnValue(b, this.colId);
		av = av.replace('.', '');
		av = av.replace(',', '.');
		av = av.replace('\xb1', '');
		av = isNaN(parseFloat(av)) ? 0 : parseFloat(av);
		bv = bv.replace('.', '');
		bv = bv.replace(',', '.');
		bv = bv.replace('\xb1', '');
		bv = isNaN(parseFloat(bv)) ? 0 : parseFloat(bv);
		return av - bv;
	}
	
	/* DEPRECATED: Use sort mode text instead*/
	TableSorter.prototype.sort_time = function(a, b){
		return this.sort_text(a, b);
	}

	TableSorter.prototype.sort_german_date = function(a, b){
		var av = this.getColumnValue(a, this.colId);
		var bv = this.getColumnValue(b, this.colId);
		avDateParts = av.split('.');
		avEnDate = avDateParts[2] + '/' + avDateParts[1] + '/' + avDateParts[0];
		var avTimestamp = new Date(avEnDate).toGMTString();
		avTimestamp = Date.parse(avTimestamp);
		bvDateParts = bv.split('.');
		bvEnDate = bvDateParts[2] + '/' + bvDateParts[1] + '/' + bvDateParts[0];
		var bvTimestamp = new Date(bvEnDate).toGMTString();
		bvTimestamp = Date.parse(bvTimestamp);
		return avTimestamp - bvTimestamp;
	}
// <<


// >> zahlarten umschalter fuer abo-formulare (require mochikit 1.4+) Version: rel-1-0-0
	function displayZahlartPanel(id) {
		if (! id){
			id = false;
			options = ['opBankeinzug', 'opKreditkarte', 'opRechnung'];
			for (i = 0; i < options.length; ++i){
				var opt = $('#' + options[i]).get(0);
				if (opt.checked) id = $(opt).val();
			}
			if (! id) id = 'Bankeinzug';
		}
		ids = ['Bankeinzug', 'Kreditkarte', 'Rechnung', 'Vorauskasse'];
		for(i = 0; i < ids.length; ++i){
			if (id == ids[i]){
				$('#' + ids[i]).show();
			}else{
				$('#' + ids[i]).hide();
			}
		}
		return false;
	}
// <<


// >> quicksearch mode switcher (require MochiKit 1.4+) Version: rel-1-0-0
	QuickSearchModeSwitcher = {
		buttons: [],
		buttonObs: [],
		formular: 'quickSearchForm',
		textfield: 'search_phrase',
		submitButton: 'search_button',
		buttonDeferred: null,
		fieldDeferred: null,
		setDefault: function(elm){
			this.handleButtonClick(elm);
		},
		init: function(args){
			var self = this;
			if ($('#' + this.formular).size() > 0) $('#' + this.formular).bind('submit', function(e){self.handleSubmit(e)});
			for (var i = 0; i < this.buttons.length; ++i){
				$('#' + this.buttons[i][0]).bind('click', function(e){self.handleButtonClick(this, e)});
			}
			if (typeof args == 'object' && typeof args.defaultButton == 'object'){
				this.setDefault(args.defaultButton.get(0));
			}
		},
		addButton: function(obj){
			if (typeof obj == 'object'){
				this.buttonObs.push(obj);
				this.buttons.push([obj.id, obj.fieldLabel]);
				return obj;
			}
			return null;
		},
		handleSubmit: function(e){
			e.preventDefault();
			for (var i = 0; i < this.buttonObs.length; ++i){
				var b = this.buttonObs[i];
				if (b.active) b.submit($(this.textfield).value);
			}
		},
		handleButtonClick: function(b, e){
			for (var i = 0; i < this.buttonObs.length; ++i){
				var button = this.buttonObs[i];
				if (b){
					if (button.getButton() == b){
						button.deactivate();
						this.activateTextField(button.fieldLabel);
					}else{
						button.activate();
					}
				}
			}
		},
		activateTextField: function(label){
			var f = $('#' + this.textfield).get(0);
			f.disabled = null;
			$(f).attr({'value': label});
			var self = this;
			$(f).bind('click', function(e){self.emptyField(this, e)});
		},
		emptyField: function(f, e){
			$(f).unbind('click');
			$(f).val('');
		}
	}
	
	// Abstract button with limited features
	// Create inherit specialized buttons to increase the features
		function QuickSearchModeSwitcherButton(id, fieldLabel){
			this.id = id;
			this.fieldLabel = fieldLabel;
			this.formular = null;
			this.active = false;
		}
		
		QuickSearchModeSwitcherButton.prototype.getButton = function(){
			return $('#' + this.id).get(0);
		}
		
		QuickSearchModeSwitcherButton.prototype.activate = function(){
			$('#' + this.id).attr('class', this.id + '_active');
			this.active = false;
		}
	
		QuickSearchModeSwitcherButton.prototype.deactivate = function(){
			$('#' + this.id).attr('class', this.id + '_passive');
			this.active = true;
		}
		
		QuickSearchModeSwitcherButton.prototype.submit = function(){
			if (this.formular) this.formular.submit();
		}


	// specialized news search button
		function QuickSearchModeSwitcherNewsButton(id, fieldLabel){
			this.constructor(id, fieldLabel);
			this.formular = $('#quickSearchForm').get(0);
			this.actionStr = '/xist4c/web/Newssuche_id_627_.htm';
		}
		
		QuickSearchModeSwitcherNewsButton.prototype = new QuickSearchModeSwitcherButton();
		
		QuickSearchModeSwitcherNewsButton.prototype.activate = function(){
			$('#' + this.id).attr('class', this.id + '_active');
			this.active = false;
		}
	
		QuickSearchModeSwitcherNewsButton.prototype.deactivate = function(){
			this.formular.action = this.actionStr;
			$('#' + this.id).attr('class', this.id + '_passive');
			this.active = true;
		}

		QuickSearchModeSwitcherNewsButton.prototype.submit = function(phrase){
			if (typeof wt_is != 'undefined') wt_is = 'News: ' + phrase;
			if(typeof(wt_sendinfo) != "undefined") wt_sendinfo('de.search.news');
			if (this.formular) this.formular.submit();
		}


	// specialized kurse search button
		function QuickSearchModeSwitcherKurseButton(id, fieldLabel){
			this.constructor(id, fieldLabel);
			this.formular = $('#quickSearchForm').get(0);
			this.actionStr = "/xist4c/web/Kurssuche_id_610_.htm";
		}
		
		QuickSearchModeSwitcherKurseButton.prototype = new QuickSearchModeSwitcherButton();
		
		QuickSearchModeSwitcherKurseButton.prototype.activate = function(){
			$('#' + this.id).attr('class', this.id + '_active');
			this.active = false;
		}
	
		QuickSearchModeSwitcherKurseButton.prototype.deactivate = function(){
			this.formular.action = this.actionStr;
			$('#' + this.id).attr('class', this.id + '_passive');
			this.active = true;
		}

		QuickSearchModeSwitcherKurseButton.prototype.submit = function(phrase){
			if (typeof wt_is != 'undefined') wt_is = 'Kurse: ' + phrase;
			if(typeof(wt_sendinfo) != "undefined") wt_sendinfo('de.search.kurse');
			if (this.formular) this.formular.submit();
		}
// >>


// >> LL_TableColumnEnhancer (require MochiKit 1.4) Version: rel-1-0-0
	LL_TableColumnViewer = function(){
		this.table = null;
		this.colConfig = [0,2,3,4,8,9];
		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;
		
		this.enterDeferred = null;
		this.leaveDeferred = null;
		this.moveDeferred = null;
		this.panel = null;
	}
	
	LL_TableColumnViewer.prototype.init = function(id, idOuter, display){
		var t = $('#' + id).get(0);
		this.idOuter = idOuter ? idOuter : null;
		var columnsIndex = [];
		var self = this;
		if (t.nodeName.toLowerCase() == 'table'){
			this.table = t;
			$(this.table).bind('mouseleave', function(e){self.hidePanel(e)});
			$(this.table).bind('mousemove', function(e){self.correctPanelPosition(e)});
			this.tableFullWidth = t.offsetWidth;
			this.tableFullHeight = t.offsetHeight;
			var tb = this._getElementChildNodeWithName(t, 'tbody', null);
			for (var i = 0; i < this._getElementChildNodesCount(tb, 1, 'tr'); i++){
				var row = self._getElementChildNodeWithName(tb, 'tr', i);
				(function(idx, r){
					if (idx > 0){
						$(r).bind('mouseenter', function(e){self.showPanel(idx, e)});
					}
				})(i, row);
				for (var j = 0; j < this._getElementChildNodesCount(row, 1, ['td', 'th']); j++){
					columnsIndex = this.getColumnsIndex(this._getElementChildNodesCount(row, 1, ['td', 'th']), this.colConfig);
					var cell = this._getElementChildNodeWithName(row, ['td', 'th'], 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);
						}
					}
				}
			}
		}
		this.updateDisplay(display);
	}
	
	LL_TableColumnViewer.prototype.makePanel = function(){
		this.panel = $('<div id="tableColumnViewerPanel"></div>').css({'display': 'none', 'position': 'absolute', 'z-index': 100})
			.append('<div id="panelContent", class="inner"></div>').get(0);
		//this.panel = DIV({'id': 'tableColumnViewerPanel', 'style': {'display': 'none', 'position': 'absolute', 'z-index': 100}}, DIV({'id': 'panelContent', 'class': 'inner'}));
		var elms = ['tbody', 'tr', 'th'];
		var curr = this.table;
		for (var i = 0; i < elms.length; ++i){
			var elm = this._getElementChildNodeWithName(curr, elms[i], null);
			curr = elm;
		}
		elm.appendChild(this.panel);
	}
	
	LL_TableColumnViewer.prototype.getPanelEntry = function(headerCell, contentCell, oddNum){
		var odd = oddNum % 2 == 0 ? {'class': null} : {'class': 'odd'};
		var row = $('<tr></tr>').attr(odd);
		var th = $('<th></th>').attr(headerCell.attrs).html(headerCell.content);
		var td = $('<td></td>').attr(contentCell.attrs).html(contentCell.content);
		row.append(th, td);
		return row.get(0);
	}
	
	LL_TableColumnViewer.prototype.appendPanelEntrys = function(rowId){
		var inner = $('#panelContent').get(0);
		inner.innerHTML = '';
		var table = $('<table cellpadding="0" cellspacing="0" border="0" class="' + $(this.table).attr('class')  + ' tableColumnViewerPanelContent"></table>').get(0);
		var tbody = $('<tbody></tbody>').get(0);
		var cnt = 0;
		var oddNum = 0;
		for (var i = 0; i < this.columns.length; ++i){
			var col = this.columns[i];
			if (typeof col == 'object' && col.cells){
				for (var j = 0; j < col.cells.length; ++j){
					if (j == rowId){
						tbody.appendChild(this.getPanelEntry(col.cells[0], col.cells[j], oddNum));
						oddNum++;
					}
					cnt++;
				}
			}
		}
		table.appendChild(tbody)
		inner.appendChild(table);
	}
	
	LL_TableColumnViewer.prototype.showPanel = function(rowId, e){
		e.preventDefault();
		if (! this.panel) this.makePanel();
		var pos = {'x': e.pageX + 30, 'y': e.pageY - 20};
		this.appendPanelEntrys(rowId);
		$(this.panel).fadeIn('fast');
	}

	LL_TableColumnViewer.prototype.hidePanel = function(e){
		e.preventDefault();
		if (this.panel) $(this.panel).fadeOut('fast');
		//if (this.panel) fade(this.panel, {'duration': 0.5});
	}
	
	LL_TableColumnViewer.prototype.correctPanelPosition = function(e){
		if (this.panel){
			var eDims = $(this.panel).offset();
			var vpDims = {'w': $(window).width(), 'h': $(window).height()};
			var vpPos = {'x': $(document).scrollLeft(), 'y': $(document).scrollTop()};
			//var eDims = getElementDimensions(this.panel);
			//var vpDims = getViewportDimensions();
			//var vpPos = getViewportPosition();
			var panelWidth = eDims.w;
			var panelHeight = eDims.h;
			var xPos = e.pageX + 30;
			var yPos = e.pageY - 20;
			//var xPos = e.mouse().page.x + 30;
			//var yPos = e.mouse().page.y - 20;
			if (xPos + panelWidth > vpDims.w + vpPos.x) xPos = vpDims.w + vpPos.x - (panelWidth + 30);
			if (yPos + panelHeight > vpDims.h + vpPos.y) yPos = vpDims.h + vpPos.y - (panelHeight + 10);
			$(this.panel).css({'left': xPos, 'top': yPos});
			//Move(this.panel, {'x': xPos, 'y': yPos, 'mode': 'absolute', 'duration': 0.2});
		}
	}

	LL_TableColumnViewer.prototype.updateDisplay = function(display, e){
		if (e) e.preventDefault();
		for (var i = 0; i < this.columns.length; ++i){
			var col = this.columns[i];
			if (col instanceof DefaultTableColumn) col.setDisplay(display);
		}
	}
	
	LL_TableColumnViewer.prototype._inArray = function(needle, arr){
		for (var i = 0; i < arr.length; ++i){
			if (needle == arr[i]) return true;
		}
		return false;
	}
	
	LL_TableColumnViewer.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){
					if (name && typeof name == 'string'){
						var nname = c.nodeName.toLowerCase();
						var n = name.toLowerCase();
						if (n == nname && count == pos) return c;
						++count;
					}else if(name && typeof name == 'object' && name.length > 0){
						var nname = c.nodeName.toLowerCase();
						if (this._inArray(nname, name) && count == pos) return c;
						++count;
					}
				}
			}
		}
		return null;
	}
	
	LL_TableColumnViewer.prototype._getElementChildNodesCount = function(parent, type, name){
		var childs = parent.childNodes;
		var count = 0;
		if (childs){
			for (var i = 0; i < childs.length; ++i){
				var c = childs[i];
				if (name && typeof name == 'string'){
					var nname = c.nodeName.toLowerCase();
					var name = name.toLowerCase();
					if (c.nodeType == type && nname == name) ++count;
				}else if(name && typeof name == 'object' && name.length > 0){
					var nname = c.nodeName.toLowerCase();
					if (c.nodeType == type && this._inArray(nname, name)) ++count;
				}else{
					if (c.nodeType == type) ++count;
				}
			}
		}
		return count;
	}

	LL_TableColumnViewer.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': ''});
			//setNodeAttribute(this.domel, 'style', {'display': ''});
			return true;
		}
		this.hidden = true;
		$(this.domel).css({'display': 'none'});
		//setNodeAttribute(this.domel, 'style', {'display': 'none'});
		return true;
	}
// <<


/* >> LL_RelationshipManager (require mochikit 1.4) 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-0 */
	/*
		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){
			//type = 'AJAX';
			var self = this;
			setTimeout(function(){self.makePopup()}, 1);
			switch (type){
				case 'IMAGE':
					this.xpopups.push(new ImageXPopup(elm, event, spos, ppos, margin_w, margin_h, TypeAttrs));
					break;
				case 'WEBPAGE':
					this.xpopups.push(new WebpageXPopup(elm, event, spos, ppos, margin_w, margin_h, TypeAttrs));
					break;
				case 'AJAX':
					this.xpopups.push(new AjaxXPopup(elm, event, spos, ppos, margin_w, margin_h, TypeAttrs));
					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': '../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){
			if (this.popup){
				if(e){
					if (e.type == 'keydown'){
						if (e.keyCode == 27){
							$(this.popup).fadeOut();
							this.cleanUp();
						}
					}else if (e.type == 'click' || e.type == 'mouseleave' || e.type == 'mouseout'){
						if (e.type == 'click'){
							$(this.popup).fadeOut();
							this.cleanUp();
						}else{
							$(this.popup).hide();
							this.cleanUp();
						}
					}
				}else{
					$(this.popup).fadeOut();
					this.cleanUp();
				}
			}
		}
	}
	
	DefaultXPopup = function(src, event, spos, ppos, margin_w, margin_h, TypeAttrs){
		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;
		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());
	}
	
	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(){
				self.setPopupPosition(src, mousePos);
				$(LL_XPopup.popup).fadeIn();
			},
			1
		);
	}

	// Image xpopup
	ImageXPopup = function(src, event, spos, ppos, margin_w, margin_h, TypeAttrs){
		/* 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);
		this.image = this.makeImage(this.getAttr('url'), {'border': 0, 'alt': '', 'title': ''});
		this.appearingHud = null;
	}
	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.appearingHud = 1;
			var self = this;
			$('#xpopupHoverMenuOuter').fadeIn('fast', function(){self.appearingHud = null});
		}
	}
	
	ImageXPopup.prototype.deactivateHud = function(e){
		$('#xpopupHoverMenuOuter').fadeOut('slow');
	}

	ImageXPopup.prototype.makeHudAndPrepareGallery = function(){
		var self = this;
		$(LL_XPopup.popup).bind('mousemove.specials', function(e){self.activateHud(e)});
		$(LL_XPopup.popup).bind('mouseleave.specials', function(e){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)}
		).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)}
		).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)}
		).get(0);
	}

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

	ImageXPopup.prototype.getCloseButton = function(){
		return $('<div>').attr(
			{'class': 'closeButton_pass', 'id': 'xpopupHoverMenuCloseButton'}
		).click(
			function(e){LL_XPopup.destruct(e)}
		).get(0);
	}

	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){
		/* 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);
	}
	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);
	}

	// Ajax xpopup
	AjaxXPopup = function(src, event, spos, ppos, margin_w, margin_h, TypeAttrs){
		/* 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);
		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){
		container.innerHTML = def.responseText;
	}

	AjaxXPopup.prototype.loadContentError = function(def){
		if (console && console.log) console.log('Fehler beim Abruf von AJAX content:', def.message);
	}
/* << */


/* >> LL_SimpleAjax (require mochikit 1.4) Version: rel-1-0-0 */
	LL_SimpleAjax = {
		target: null,
		setTarget: function(t){
			if (typeof $(t) == 'object') this.target = t; return t;
			return null;
		},
		makeRequest: function(url){
			var def;
			if (this.target){
				var self = this;
				$.ajax({
					type: 'get',
					url: url,
					success: function(data, msg){self.swapHTML(data, msg)},
					error: function(req, status, error){self.swapHTMLError(req, status, error)}
				});
			}
		},
		swapHTML: function(data, msg){
			$(this.target).empty().html(data);
			return data;
		},
		swapHTMLError: function(req, status, error){
			if (console && console.log) console.log('Folgender Fehler ist aufgetreten:', error, status);
		}
	}
/* << */


/* >> LL_PerformDAFVideoListSizeAction (require mochikit 1.4) Version: rel-1-0-0 */
	LL_PerformDAFVideoListSizeAction = {
		connect: function(id){
			var self = this;
			$('#dafVideoAddOnMoreButton_' + id).bind('click', function(e){self.action(id, e)})
			//connect($('dafVideoAddOnMoreButton_' + id), 'onclick', bind('action', this, id));
		},
		action: function(id, e){
			var className = $('#dafVideoAddOnList_' + id).attr('class');
			//var className = getNodeAttribute($('dafVideoAddOnList_' + id), 'class');
			if (className == 'list listLess'){
				var class1 = 'list listMore';
				var class2 = 'buttonLess';
				//setElementClass($('dafVideoAddOnList_' + id), 'list listMore');
				//setElementClass($('dafVideoAddOnMoreButton_' + id), 'buttonLess');
			}else{
				var class1 = 'list listLess';
				var class2 = 'buttonMore';
				//setElementClass($('dafVideoAddOnList_' + id), 'list listLess');
				//setElementClass($('dafVideoAddOnMoreButton_' + id), 'buttonMore');
			}
			$('#dafVideoAddOnList_' + id).attr('class', class1);
			$('#dafVideoAddOnMoreButton_' + id).attr('class', class2);
		}
	}
/* << */



// >> LL_MoveBanner (require jQuery)
	function LL_MoveBanner(){
		
		var footerShell = $('div.footerContainer');
		var footerContainer = footerShell.find('div[class^=footerSty moveBannerTo_]');
		var list = footerContainer.get();
		for (var i in list){
			var source = list[i];
			var id = source.className.replace('footerSty moveBannerTo_', '');
			if (id != ''){
				var target = document.getElementById(id);
				if (target){
					target.appendChild(source);
				}
			}
		}
	}
// <<



// >> LL_MoveBannerAlt (require MochiKit 1.4)
	function LL_MoveBannerAlt(){
		var footerShell = $('div.footerContainer');
		var footerContainer = footerShell.find('div').get();
		for (var i = 0; i < footerContainer.length; ++i) {
			footerBanner = footerContainer[i]
			var classname = getNodeAttribute(footerBanner, 'class');
			if (classname && classname.lastIndexOf('moveBannerTo_') > 0) {
				bannerID = classname.replace('footerSty moveBannerTo_', "");
				if (getElement(bannerID)) {
					getElement(bannerID).innerHTML = footerBanner.innerHTML;
					footerBanner.innerHTML = '';
				}
			}
		}
	}
// <<


// >> teaserContentReceiver (require mochikit 1.4+) Version: rel-1-0-0
	TeaserContentReceiver = {
		url: '/teaserContentReceiver',
		receive: function(src, target){
			var target = $('#' + target);
			if (target.size() > 0){
				var url = [this.url, '?src=',encodeURIComponent(src)].join('');
				var self = this;
				$.ajax({
					type: 'get',
					url: url,
					success: function(data, msg){self.receiveSuccess(data, msg, target)},
					error: function(req, status, error){self.receiveError(req, status, error, target)}
				});
				/*var def = doSimpleXMLHttpRequest(url);
				def.addCallbacks(bind('receiveSuccess', this, target), bind('receiveError', this, url, target));*/
			}
		},
		receiveSuccess: function(data, msg, target){
			target.html(data);
		},
		receiveError: function(req, status, error, target){
			target.html('<span style="color: darkred;">Fehler beim Laden des Elements!</span>');
		}
	}
// <<


//>> Handle FieldPrompts (requires jQuery 1.2.6)
	function handleFieldPrompt(fieldList){
		$(function(){
			for (var i = 0; i < fieldList.length; ++i){
				function x(f){
					var 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');
	}
//<<


//>> Stock Handler (requires jQuery 1.2.6)
	StockHandler = {
		isins: [],
		btrIds: [],
		getIdentifiers: function(){
			var self = this;
			$('div[class*=stockShell_], span[class*=stockShell_]').each(function(i){
				var cName = $(this).attr('class');
				var id = cName.substring(cName.indexOf('stockShell_'), cName.length);
				if (id.search(' ') > -1){
					id = id.substring(0, id.indexOf(' ')).split('_')[1];
				}else{
					id = id.substring(0, id.length).split('_')[1];
				}
				if (id.substring(0, 3) === 'btr'){
					if ($.inArray(id, self.btrIds) < 0) {
						self.btrIds.push(id);
					}
				}else{
					if ($.inArray(id, self.isins) < 0) {
						self.isins.push(id);
					}
				}
			});
			$('tr[class*=stockListItem_]').each(function(i){
				var isin = $(this).attr('class').split(' ')[1].split('_')[1];
				if ($.inArray(isin, self.isins) < 0) {
					self.isins.push(isin);
				}
			});
			//console.log(self.isins);
		},
		sentAjax: function(){
			var self = this;
			$.ajax({
				type: "GET",
				url: "/datagateway/kurs/" + self.isins.join(","),
				success: function(data, msg){self.showStocks()},
				error: function(req, status, error){}
			});
		},
		setMode: function(mode, modeShell){
			modeShell.removeClass('stockMode');
			if (mode == 1) {
				modeShell.addClass('stockMode_vPlus');
			} else if (mode == -1) {
				modeShell.addClass('stockMode_vMinus');
			} else {
				modeShell.addClass('stockMode_noChange');
			}
		},
		placeStockValues: function(data, type){
			var self = this;
			for (var i = 0; i < this[type].length; ++i) {
				if (data[this[type][i]]){
					var dataIsin = data[this[type][i]];
					var shell = $('.stockShell_' + this[type][i]);
					//console.log(dataIsin, shell);
					var modeShell = null;
					var mode = dataIsin.mode;
					var waehrung = '';
					
					if (dataIsin.waehrung){
						waehrung = ' ' + dataIsin.waehrung
					}
					
					shell.each(function(i){
						var item = $(this);
						if (item.children('div.stockMode').length > 0){
							modeShell = item.children('div.stockMode');
						} else {
							modeShell = item;
						}
						self.setMode(mode, modeShell);
						item.find('span.stockName').text(dataIsin.name);
						item.find('span.stockPerf').text(dataIsin.absperf + waehrung);
						item.find('span.stockPerfPerc').text(dataIsin.relperf + "%");
						item.find('span.stockValue').text(dataIsin.value + waehrung);
						item.find('span.stockTime').text($.formatTime(dataIsin.timestamp).timeWithoutSec);
						item.find('span.stockDate').text($.formatDate(dataIsin.timestamp, 'de')._short);
						item.find('span.sep').text("|");
					});
				}
			}
		},
		handleJSON: function(test){
			var self = this;
			var urls = [];
			if (test){
				urls.push("aktionaer_stockInfo.text");
			}else{
				if (this.isins.length > 0){
					urls.push(["/datagateway/kurs/" + self.isins.join(","), 'isins']);
				}
				if (this.btrIds.length > 0){
					urls.push(["/datagateway/tippdestagesperf/" + self.btrIds.join(","), 'btrIds']);
				}
			}
			for (var i = 0; i < urls.length; i += 1){
				(function(url, type){
					$.getJSON(url,
						function(data, textStatus){
							self.placeStockValues(data, type);
						}
					);
				})(urls[i][0], urls[i][1]);
			}
		},
		showStocks: function(test){
			this.getIdentifiers(),
			this.handleJSON(test)
		}
	}
//<<


// >> Top Flop Handler (requires jQuery 1.2.6)
	TopFlop_Handler = $.extend(
		$.clone(LLObject),
		{
			create: function(){
				var o = LLObject.create.call(this);
				return o;
			},
			getMode: function(mode){
				if (mode == 1) {
					return 'stockMode_vPlus';
				} else if (mode == -1) {
					return'stockMode_vMinus';
				} else {
					return'stockMode_noChange';
				}
			},
			setHeader: function(el){
				el.append(
					'<tr valign="top">' +
						'<td class="topFlopStocks">' + 
							'<table cellpadding="0" cellspacing="0" border="0">' +
								'<tr>' +
									'<th class="itemName">Wertpapier</th>' +
									'<th class="itemValue">Kurs in &euro;</th>' +
									'<th class="itemPerfPerc">%</th>' +
									'<th class="itemNews">&nbsp;</th>' +
								'</tr>' +
							'</table>' +
						'</td>' +
						'<td class="spacer">' +
							'<img width="1" alt="spacer" src="../px/spc.gif" height="1" />' +
						'</td>' +
						'<td class="topFlopNews">' +
							'<table cellpadding="0" cellspacing="0" border="0">' +
								'<tr>' +
									'<th class="newsDate">Zeit</th>' +
									'<th class="newsText">Meldung</th>' +
								'</tr>' +
							'</table>' +
						'</td>' +
					'</tr>'
				);
			},
			setStockItem: function(el, stock, target){
				var mode = this.getMode(stock.mode);
				var newstoday = null;
				if (stock.newstoday){
					var ntdUrl = stock.newstoday;
					newstoday = 'class="news"';
				}
				else{
					var ntdUrl = '#';
				}
				
				if (stock.url){
					var url = stock.url;
				}else{
					var url = '#';
				}
				
				$(target).append(
					'<tr class="' + mode + ' ' + stock.type + '">' +
						'<td class="itemName"><a href="' + url + '" target="_self"><span class="stockName">' + stock.name + '</span></a></td>' +
						'<td class="itemValue"><a href="' + url + '" target="_self"><span class="stockValue">' + stock.value + '</span></a></td>' +
						'<td class="itemPerfPerc"><a href="' + url + '" target="_self"><span class="stockPerfPerc">' + stock.relperf + '</span></a></td>' +
						'<td class="itemNews"><a href="' + ntdUrl + '" target="_self"><img src="../px/spc.gif" alt="" width=1 height=1 ' + newstoday + '/></a></td>' +
					'</tr>'
				);
			},
			setNewsItem: function(el, news, status){
				var target = el.find('td.topFlopNews table');
				target.append(
					'<tr class="' + status + '">' +
						'<td class="newsDate"><a href="' + news.url + '" target="_self"><span class="newsDate">' + news.date + '</span></a></td>' +
						'<td class="newsText"><a href="' + news.url + '" target="_self"><span class="newsText">' + news.title + '</span></a></td>' +
					'</tr>'
				);
			},
			placeStockValues: function(data, el){
				if (data){
					var stocks = data["aktien"];
					var news = data["news"];
					this.setHeader(el.find('table.topFlopTable'));
					var target = el.find('td.topFlopStocks table');
					
					for (var i = 0; i < stocks.length; ++i) {
						this.setStockItem(el, stocks[i], target);
					}
					for (var j = 0; j < news.length; ++j) {
						if (j%2 == 0) {
							status = "even";
						} else {
							status = "odd"
						}
						this.setNewsItem(el, news[j], status);
					}
				}
			},
			handleJSON: function(name, el, test){
				var self = this;
				var url = null;
				
				if (test){
					url = "aktionaer_stockInfoTopFlop" + name + ".text";
				} else {
					url = "/datagateway/topsflops/" + name
				}
				
				$.getJSON(url,
					function(data, textStatus){
						self.placeStockValues(data, el);
					}
				);
			},
			showItems: function(test){
				var topFlopShell = $('div.topFlopShell');
				var self = this;
				topFlopShell.each(function(i){
					var topFlopName = $(this).attr('class').split(' ')[1].split('_')[1];
					self.handleJSON(topFlopName, $(this), test);
				});
			}
		}
	);
	TopFlopHandler = TopFlop_Handler.create();
//<<


// >> Top Flop Teaser Handler (requires jQuery 1.2.6)
	TopFlopTeaser_Handler = $.extend(
		$.clone(TopFlop_Handler),
		{
			create: function(){
				var o = TopFlop_Handler.create.call(this);
				return o;
			},
			setHeader: function(el){
				el.append(
					'<tr valign="top">' +
						'<th class="itemName">Wertpapier</th>' +
						'<th class="itemValue">Kurs</th>' +
						'<th class="itemPerfPerc">%</th>' +
						'<th class="itemNews">&nbsp;</th>' +
					'</tr>'
				);
			},
			placeStockValues: function(data, el){
				if (data){
					var chart = data["charturl"];
					var stocks = data["aktien"];
					var sublink = data["detailurl"];
					el.find('div.topFlopTable').replaceWith('<table width="100%" cellspacing="0" cellpadding="0" border="0" class="topFlopTable"><tbody></tbody></table>');
					var target = el.find('table.topFlopTable');
					
					this.setHeader(target);
					this.setChart(el, chart);
					for (var i = 0; i < stocks.length; ++i) {
						this.setStockItem(el, stocks[i], target);
					}
					this.setSublink(el, sublink);
				}
			},
			handleJSON: function(name, el, test){
				var self = this;
				var url = null;
				
				if (test){
					url = "aktionaer_stockInfoTopFlopTeaser" + name + ".text";
				} else {
					url = "/datagateway/topsflops/" + name
				}
				
				$.getJSON(url,
					function(data, textStatus){
						self.placeStockValues(data, el);
					}
				);
			},
			showItems: function(test){
				var topFlopShell = $('div.topFlopTeaserShell');
				var self = this;
				topFlopShell.each(function(i){
					var topFlopName = $(this).attr('class').split(' ')[1].split('_')[1];
					self.handleJSON(topFlopName, $(this), test);
				});
			},
			setChart: function(el, chart){
				var img = '<img src="' + chart + '" alt="" />';
				el.prepend('<div class="chart"></div>');
				el.find('div.chart').html(img);
			},
			setSublink: function(el, sublink){
				el.append('<div class="sublink"><a href="' + sublink + '" target="_self">mehr Tops &amp; Flops</a></div>');
			}
		}
	);
//<<


// >> News by frequency handler (requires jQuery 1.2.6)
	FreqNews_Handler = $.extend(
		$.clone(TopFlopHandler),
		{
			create: function(){
				var o = TopFlopHandler.create.call(this);
				return o;
			},
			setHeader: function(el){
				el.append(
					'<table class="freqNewsTable" border="0" cellspacing="0" cellpadding="0">' +
						'<tr>' +
							'<th class="itemName">Wertpapier</th>' +
							'<th class="itemValue">Kurs</th>' +
							'<th class="itemPerfPerc">%</th>' +
							'<th class="itemFreq">Anzahl</th>' +
							'<th class="itemNews">Top-Nachrichten</th>' +
						'</tr>' +
					'</table>'
				);
			},
			setMinWidth: function(el){
				el.append(
					'<tr class="minWidth">' +
						'<td class="minWidth minWidth_1"><img src="../px/spc.gif" alt="spc" height="1" width="1" /></td>' +
						'<td class="minWidth minWidth_2"><img src="../px/spc.gif" alt="spc" height="1" width="1" /></td>' +
						'<td class="minWidth minWidth_3"><img src="../px/spc.gif" alt="spc" height="1" width="1" /></td>' +
						'<td class="minWidth minWidth_4"><img src="../px/spc.gif" alt="spc" height="1" width="1" /></td>' +
						'<td class="minWidth minWidth_5"><img src="../px/spc.gif" alt="spc" height="1" width="1" /></td>' +
					'</tr>'
				);
			},
			setStockItem: function(el, stock, status){
				var mode = this.getMode(stock.mode);
				var target = el.find('table.freqNewsTable');
				if (stock.url){
					var url = stock.url;
				}else{
					var url = '#'
				}
				target.append(
					'<tr class="' + mode + ' ' + status + '">' +
						'<td class="itemName"><a href="' + url + '" target="_self"><span class="stockName">' + stock.name + '</span></a></td>' +
						'<td class="itemValue"><span class="stockValue">' + stock.value + stock.waehrung + '</span></td>' +
						'<td class="itemPerfPerc"><span class="stockPerfPerc">' + stock.relperf + '</span></td>' +
						'<td class="itemFreq"><span class="stockFreq">' + stock.counter + '</span></td>' +
						'<td class="itemNews"><a href="' + stock.newsUrl + '" target="_self"><span class="newsText">' + stock.newsTitle + '</span></a></td>' +
					'</tr>'
				);
			},
			placeStockValues: function(data, el){
				if (data){
					var stocks = data;
					this.setHeader(el);
					for (var i = 0; i < stocks.length; ++i) {
						if (i%2 == 0) {
							status = "even";
						} else {
							status = "odd"
						}
						this.setStockItem(el, stocks[i], status);
					}
					var table = el.find('table.freqNewsTable');
					this.setMinWidth(table);
				}
			},
			handleJSON: function(name, el, test){
				var self = this;
				var url = null;
				if (test){
					url = "aktionaer_stockInfoFreqNews.text";
				} else {
					url = "/datagateway/newshaeufigkeit/"+ name + "/10"
				}
				
				$.getJSON(url,
					function(data, textStatus){
						self.placeStockValues(data, el);
					}
				);
			},
			showItems: function(test){
				var outerShell = $('div.freqNewsShell');
				var self = this;
				outerShell.each(function(i){
					var itemName = $(this).attr('class').split(' ')[1].split('_')[1];
					self.handleJSON(itemName, $(this), test);
				});
			}
		}
	);
//<<


/* >>LivingLogic Media Slider (requires jQuery 1.2.6 +) */
	MediaSlider = $.extend(
		$.clone(LLObject),
		{
			create: function(options){
				var o = LLObject.create.call(this);
				o.items = [];
				o.groupCnt = -1;
				o.pos = 0;
				o.data = null;
				o.defaults = {
					url: null,
					target: null,
					height: 200,
					width: 300,
					duration: 400,
					itemWidth: null,
					countPerLine: 4,
					btrIdFromLocation: false
				}
				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){
					this.pos = this.groupCnt;
				}
				var id = this.target.attr('id');
				$('#' + id).find('.jsPagerContent').scrollTo(this.width * this.pos, this.duration, {'axis': 'x'});
			},
			prepareContentArea: function(){
				var t = this.target;
				t.css({'overflow': 'auto'});
				var w = this.width;
				var h = this.height;
				var content = t.find('.jsPagerContent').empty();
				content.css({
					'width': w,
					'height': h,
					'overflow': 'hidden'
				});
			},
			makeContentAreaItems: function(){
				var self = this;
				$.getJSON(this.url, function(data, textStatus){
					var t = self.target;
					var prefix = t.attr('id');
					var d = self.data = data;
					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++;
						}
						if (groups > 1){
							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)});
						}
						var scrollPaneWidth = self.width * groups;
						var scrollPane = $('<div class="ms_scrollPane ms_scrollPane_' + prefix + '"></div>');
						scrollPane.css({'width': scrollPaneWidth, 'height': self.height});
						$(d).each(function(i){
							if (i % self.countPerLine == 0){
								self.groupCnt++;
								var hwAttrs = {'width': self.width, 'height': self.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 = MediaSliderItem.create(i, this, self);
							self.items.push(item);
							item = item.make();
							grpShell.find('table tr').append(item);
							scrollPane.append(grpShell);
						});
						t.find('.jsPagerContent').append(scrollPane);
					}
				});
			}
		}
	);

	MediaSliderItem = $.extend(
		$.clone(LLObject),
		{
			create: function(id, data, MediaSlider){
				var o = LLObject.create.call(this);
				o.slider = MediaSlider || null;
				o.id = id;
				o.text = data.text || null;
				o.videourl = data.videourl || null;
				o.imgurl = data.imgurl || null;
				o.imgw = data.imgw || '';
				o.imgh = data.imgh || '';
				o.dafid = data.dafid || null;
				o.itemWidth = MediaSlider.defaults.itemWidth || null;
				return o;
			},
			make: function(){
				var sliderId = this.slider.target.attr('id');
				var url = this.videourl;
				var item = $(
					'<td>' +
						'<a href="' + this.videourl + '" class="ms_item ms_item_' + this.id + ' ms_item_' + sliderId + ' ms_item_' + sliderId + '_' + this.id + '">' +
							'<img src="' + this.imgurl + '" alt="" class="ms_image" width="' + this.imgw + '" height="' + this.imgh + '"/>' +
							'<span class="ms_overlay"></span>' +
							'<span class="ms_text">' + this.text + '</span>' +
						'</a>' +
					'</td>'
				);
				item.css({'vertical-align': 'top', 'text-align': 'center'});
				var a = item.find('a.ms_item');
				var img = item.find('img.ms_image');
				var overlay = item.find('span.ms_overlay');
				if (this.itemWidth && parseInt(this.itemWidth) < parseInt(this.imgw)){
					var diff = this.imgw - this.itemWidth;
					a.css({'overflow': 'hidden', 'width': this.itemWidth});
					img.css({'position': 'relative', 'left': '-' + diff / 2 + 'px'});
					overlay.css({'width': this.itemWidth, 'height': this.imgh});
				}else{
					a.add(overlay).css({'width': this.imgw, 'height': this.imgh});
				}
				
				LL_XPopup.registerPopup(
					item.get(0),
					'click',
					'WEBPAGE',
					'p_c',
					'c',
					'0',
					'0',
					{'height': 450, 'width': 650, 'url': url}
				);
				return item;
			}
		}
	);
/* << */


// >> EPaperContainer (requires jQuery 1.2.6)
	EPaperContainer = {
		handleBox: function(){
			shell = $('#epapercont');
			bigCont = $('#epaperBigCont');
			shell.bind("mouseenter", function(e){bigCont.show()});
			shell.bind("mouseleave", function(e){bigCont.hide()});
		}
	}
// <<


/* >> stock detail data injection */
	StockDetailDataInjection = $.extend(
		$.clone(LLObject),
		{
			create: function(url){
				var o = LLObject.create.call(this);
				o.url = url || null;
				o.prefix = 'stockDetail_';
				return o;
			},
			injectData: function(){
				if (this.url){
					var self = this;
					var p = this.prefix;
					$.getJSON(this.url, function(data, textStatus){
						if (data.info){
							var ts = data.info.timestamp;
							if (ts){
								data.info.timestamp = $.formatTime(ts).timeWithoutSec + ' - ' + $.formatDate(ts, 'de').middle;
							}
							self.injectInfo(data.info, p);
						}
						if (data.fundamentaldata) self.injectFundametaldata(data.fundamentaldata);
						if (data.realtime) self.injectBoerseGo(data, p);
						if (data.charts) self.injectCharts(data.charts, data.tabindex);
							
					});
				}
			},
			injectInfo: function(data, p){
				for(var k in data){
					var dat = data[k];
					if (k == 'mode'){
						var elm = $('#' + this.prefix + 'mode');
						var cname = 'vNoChanges';
						if (data[k] > 0) cname = 'vPlus';
						if (data[k] < 0) cname = 'vMinus';
						elm.attr('class', cname);
						continue;
					}
					if (k == 'value' || k == 'open' || k == 'absperf') dat = data[k] + data.waehrung;
					if (k == 'relperf') dat += '%';
					$('#' + p + k).html((dat || '-'));
				}
				var bidAsk = ((data.bid + data.waehrung) || '-') + ' / ' + ((data.ask + data.waehrung) || '-');
				$('#' + p + 'bidAsk').html(bidAsk);
				var highLow = ((data.high + data.waehrung) || '-') + ' / ' + ((data.low + data.waehrung) || '-');
				$('#' + p + 'highLow').html(highLow);
			},
			injectFundametaldata: function(data){
				$('#fundamentalData').html(data);
			},
			injectBoerseGo: function(data, p){
				if (data.realtime){
					$('#boerseGoData').show();
					$('#' + p + 'bgo_name').html((data.info.name || '-'));
					$('#' + p + 'bgo_bid').html(((data.realtime.bid + data.info.waehrung) || '-'));
					$('#' + p + 'bgo_ask').html(((data.realtime.ask + data.info.waehrung) || '-'));
					var ts = data.realtime.timestamp;
					if (ts){
						data.realtime.timestamp = $.formatTime(ts).timeWithoutSec + ' - ' + $.formatDate(ts, 'de').middle;
					}
					$('#' + p + 'bgo_date').html((data.realtime.timestamp || '-'));
				}else{
					$('#boerseGoData').hide();
				}
			},
			injectCharts: function(data, tabindex){
				$('#chartImage').attr('src', data[tabindex]);
				var tabs = $('div.stdTabbarShell');
				if (tabs.size() > 0){
					tabs.find('.stdTBItem').each(function(i){
						if (i == tabindex){
							$(this).addClass('stdTBItemHere');
						}
						$(this).attr('href', data[i]);
						$(this).bind('click', function(e){
							e.preventDefault();
							e.stopPropagation();
							$('#chartImage').attr('src', $(this).attr('href'));
							$('div.stdTabbarShell').find('.stdTBItem').removeClass('stdTBItemHere');
							$(this).addClass('stdTBItemHere');
						});
					});
				}
			}
		}
	);
/* << */


/* >> stock info handler for related stocks*/
	StockInfoHandler = $.extend(
		$.clone(LLObject),
		{
			create: function(url){
				var o = LLObject.create.call(this);
				o.url = url;
				o.prefix = 'stockInfo_';
				return o;
			},
			injectData: function(){
				var self = this;
				$.getJSON(this.url, function(data, textStatus){
					var target = $('#' + self.prefix + data.isin);
					if(target.size() > 0){
						for (var k in data){
							var elm = target.find('.' + k)
							if (elm){
								if (k == 'mode'){
									var cname = 'vNoChanges';
									if (data[k] > 0) cname = 'vPlus';
									if (data[k] < 0) cname = 'vMinus';
									elm.attr('class', cname);
									continue;
								}else if(k == 'timestamp'){
									var ts = data.timestamp;
									if (ts){
										data.timestamp = $.formatTime(ts).timeWithoutSec + ' - ' + $.formatDate(ts, 'de').middle;
									}
								}else if(k == 'chart'){
									elm.empty();
									elm.height(132);
									elm.width(212);
									elm.css({'background': 'url(' + data[k] + ') -2px -3px no-repeat'});
									continue;
								}
								var dat = data[k]
								if ($.inArray(k, ['value', 'high', 'low', 'absperf', 'ask', 'bid']) > -1) dat = data[k] + data.waehrung;
								if (k == 'relperf') dat = data[k] + '%';
								elm.text(dat);
							}
						}
					}
				});
			}
		}
	);
/* << */


/* >> 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'});
						}
					}
				}
			}
		}
	)
/* << */


// >> Survey teaser (require mochikit 1.4)
	function Survey(args){
		this.surveyId = args.sId;
		this.survey = {'responseText': null};
		this.initUrl = args.initUrl;
		this.voteUrl = args.voteUrl;
		this.resultUrl = args.resultUrl;
		this.oldButtonValue = null;
		this.voteConnect = null;
	}
	
	Survey.prototype._connectButtons = function(){
		if (this.voteConnect)
			disconnect(this.voteConnect);
		this.voteConnect = connect($('surveyVote'), 'onclick', bind('vote', this, $('surveyVote')));
		this.resultConnect = connect($('surveyResult'), 'onclick', bind('getResult', this, $('surveyResult')));
	}
	
	Survey.prototype.getSurvey = function(){
		if (this.survey.responseText){
			this.loadSurvey();
		}else{
			var def = doSimpleXMLHttpRequest(this.initUrl);
			def.addCallbacks(bind('loadSurvey', this), bind('loadSurveyError', this));
		}
	}
	
	Survey.prototype.loadSurvey = function(def){
		if (! def){
			var def = this.survey;
		}else{
			this.survey.responseText = def.responseText;
		}
		Opacity($(this.surveyId), {'from': 1, 'to': 0, 'afterFinish': bind('appearContent', this, def)});
		if (this.oldButtonValue){
			setNodeAttribute($('surveyVote'), 'value', this.oldButtonValue);
			setNodeAttribute($('surveyResult'), 'style', {'display': ''});
		}
		this.oldButtonValue = null;
		this._connectButtons();
	}

	Survey.prototype.loadSurveyError = function(def){
		var elm = DIV(null, DIV({'style': {'color': '#cc0000'}}, "Service nicht verfügbar!"));
		$(this.surveyId).innerHTML = elm.innerHTML;
		logFatal('Survey: Status, ', def.message);
	}
	
	Survey.prototype.vote = function(button, e){
		e.stop();
		var form = button.parentNode.parentNode;
		var qStr = this.preparePost(form.elements);
		if (qStr){
			var def = doXHR(this.voteUrl, {'method': 'POST', 'sendContent': qStr, 'headers': {'Content-Type': 'application/x-www-form-urlencoded'}});
			def.addCallbacks(bind('handleVoting', this), bind('handleVotingError', this));
		}else{
			if ($('voteFirstMsg')){
				removeElement($('voteFirstMsg'));
			}
			$(this.surveyId).appendChild(DIV({'id': 'voteFirstMsg', 'style': {'color': '#cc0000'}}, "Bitte stimmen Sie zuerst ab."));
			callLater(3, function(){fade($('voteFirstMsg'), {'from': 1, 'to': 0, 'duration': 0.4})});
		}
	}
	
	Survey.prototype.handleVoting = function(def){
		pulsate($('surveyResult'), {'duration': 4});
	}
	
	Survey.prototype.handleVotingError = function(def){
		$(this.surveyId).appendChild(DIV({'style': {'color': '#cc0000'}}, "Fehler bei Umfrageeintrag!"));
		log(def.message);
	}
	
	Survey.prototype.preparePost = function(els){
		var k = [];
		var v = [];
		var valid = false;
		var param = {
			push: function(key, value){
				if (key != 'user') valid = true;
				k.push(key);
				v.push(value);
			}
		}
		for (var i = 0; i < els.length; ++i){
			if (els[i].type == 'radio'){
				if (els[i].checked ){
					param.push(els[i].name, els[i].value);
				}
			}else if (els[i].type == 'checkbox'){
				if (els[i].checked ){
					param.push(els[i].name, els[i].value);
				}
			}else if (els[i].type == 'hidden'){
				param.push(els[i].name, els[i].value);
			}
		}
		if (valid) return queryString(k, v);
		return false;
	}

	Survey.prototype.getResult = function(button, e){
		e.stop();
		var def = doSimpleXMLHttpRequest(this.resultUrl);
		def.addCallbacks(bind('switchResult', this), bind('switchResultError', this));
	}
	
	Survey.prototype.switchResult = function(def){
		Opacity($(this.surveyId), {'from': 1, 'to': 0, 'afterFinish': bind('appearContent', this, def)});
		if(! this.oldButtonValue){
			this.oldButtonValue = getNodeAttribute($('surveyVote'), 'value');
		}
		setNodeAttribute($('surveyVote'), 'value', 'Zurück');
		if (this.voteConnect)
			disconnect(this.voteConnect);
		this.voteConnect = connect($('surveyVote'), 'onclick', bind('getSurvey', this, $('surveyVote')));
		hideElement($('surveyResult'));
	}
	
	Survey.prototype.appearContent = function(def){
		$(this.surveyId).innerHTML = '';
		$(this.surveyId).innerHTML = def.responseText;
		appear($(this.surveyId));
	}

	Survey.prototype.switchResultError = function(def){
		
	}
// <<


/* >> Special sortable stock list info table (requires jQuery 1.2.6 +) */
	SpecialSortableStockinfoTable = $.extend(
		$.clone(LLObject),
		{
			create: function(opts){
				var o = LLObject.create.call(this);
				o.target = opts.target || null;
				o.type = opts.type || 'dax';
				o.contCache = null;
				o.orderKey = null;
				o.orderBy = 0;
				return o;
			},
			prepareContCacheWithOrder: function(listKey, orderKey){
				var floatCols = ['price', 'pabs', 'prel', 'vol', 'rel'];
				var c = this.contCache;
				var self = this;
				$(c.columnOrder).each(function(i){
					if (typeof this.order == 'number'){
						this.order = 0;
						if (this.key == orderKey){
							this.order = self.orderBy;
							self.orderKey = this.key;
						}
					}
				});
				if ($.inArray(orderKey, floatCols) > -1){
					if (orderKey == 'rel') orderKey = 'prel';
					c[listKey].sort(function(a, b){return self.sortFloat(a, b, orderKey);});
				}else{
					c[listKey].sort(function(a, b){
						if (a[orderKey].title && b[orderKey].title){
							if (a[orderKey].title.__datetime__) return self.sortDate(a, b, orderKey);
						}
						return self.sortLiteral(a, b, orderKey);
					});
				}
				if (this.orderBy > 1) c[listKey].reverse();
				this.contCache = c;
			},
			sortLiteral: function(a, b, orderKey){
				var a = a[orderKey].title || '';
				var b = b[orderKey].title || '';
				return (a > b) - (a < b);
			},
			sortDate: function(a, b, orderKey){
				var a = new Date(a[orderKey].title.value).getTime();
				var b = new Date(b[orderKey].title.value).getTime();
				return a > b;
			},
			sortFloat: function(a, b, orderKey){
				var a = a[orderKey].title || 0;
				var b = b[orderKey].title || 0;
				var a = Utils.parseDeFloat(a);
				var b = Utils.parseDeFloat(b);
				return a - b;
			},
			renderContentWithContCache: function(target){
				JSONPanelContentRenderer.render(this.contCache, this, target);
			},
			make: function(){
				var url = AjaxURLManager.getUrlWithKey('indexlist', {'list': this.type});
				var self = this;
				$.getJSON(url, function(data, textStatus){
					JSONPanelContentRenderer.render(data, self, self.target);
				});
			}
		}
	);
/* << */


/* >> Deutsche Bank stock list detail with slotmachine filter (requires jQuery 1.2.6 +) */
	/* >> 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.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);
					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 (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, '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 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('dboverview', 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">' +
									'<tr></tr>' +
								'</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('dboverview');
					//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 = $(
						'<td class="' + this.id + '_column selectColumn">' +
							'<div class="slotTitle"><span>' + this.title + '</span></div>' +
							'<div class="slotSelect">' +
								'<select name="' + this.id + '_select" id="' + this.id + '_select"></select>' +
							'</div>' +
						'</td>'
					);
					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 tr');
						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(){
			SlotMachineTitlePrep = SlotMachineTitlePreparer.create();
			DeutscheBankOvList = DeutscheBankOverviewList.create();
			SlotMachineSelectVariant.init(
				{
					'target': $('#deutscheBankOverview'),
					'onAfterInit': function(data){
						SlotMachineTitlePrep.update(data);
					},
					'onAfterSlotCatch': function(slot){
					},
					'onDataRequest': function(slot, oldData){
					},
					'onDataRequestSuccess': function(slot, data){
						DeutscheBankOvList.update(data.params);
					}
				}
			);
		}
	/* << */
/* << */


/* >> Slot machine select variant handler there are triggered on slot machine events */
	/* >> slot machine title */
		SlotMachineTitlePreparer = $.extend(
			$.clone(LLObject),
			{
				create: function(){
					var o = LLObject.create.call(this);
					return o;
				},
				update: function(data){
					var target = $('#deutscheBankOverviewTitle');
					if (data.productTitle){
						target.text(data.productTitle);
					}
				}
			}
		);
	/* << */

	/* >> deutsche bank overview list */
		DeutscheBankOverviewList = $.extend(
			$.clone(LLObject),
			{
				create: function(){
					var o = LLObject.create.call(this);
					return o;
				},
				update: function(params){
					var url = AjaxURLManager.getUrlWithKey('dboverviewlist', params);
					var self = this;
					$.getJSON(url, function(data, textStatus){
						JSONPanelContentRenderer.render(data, self, $('#deutscheBankOverviewList'));
						PagerElem4JsonTables = PagerElement4JsonTables.create({
								'target': $('#deutscheBankOverviewPager'),
								'frameWidth': 10,
								'callback': function(page){ // trigger table reload;
									var params = SlotMachineSelectVariant.data.params;
									params = $.extend(params, {'page': page});
									var url = AjaxURLManager.getUrlWithKey('dboverviewlist', params);
									DeutscheBankOvList.update(params);
								}
						});
						PagerElem4JsonTables.update(data);
					});
				}
			}
		);
	/* << */

	/* >> Pager element for Json rendered tables */
		PagerElement4JsonTables = $.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 firstCol = tpl.clone();
					firstCol.find('div').addClass(divFirstClass);
					var previousCol = tpl.clone();
					previousCol.find('div').addClass(divPrevClass);
					var lastCol = tpl.clone();
					lastCol.find('div').addClass(divLastClass);
					var nextCol = tpl.clone();
					nextCol.find('div').addClass(divNextClass);
					
					var cb = opts.callback;
					var self = this;
					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);
							});
						}
					}
					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;
					}
					pOuter.append(this.makeArrowNaviLayout().first);
					for (var i = start; i < end; ++i){
						if (i > pages) break;
						if (i == currPage){
							pOuter.append(this.makePageLayout(i, true));
						}else{
							pOuter.append(this.makePageLayout(i, false));
						}
					}
					pOuter.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());
				}
			}
		);
	/* << */
/* << */


/* >> Deutsche bank panel */
	DeutscheBankPanel = $.extend(
		$.clone(LLObject),
		{
			create: function(){
				var o = LLObject.create.call(this);
				return o;
			},
			getAktId: function(){
				var url = window.location.href;
				var did = null;
				var rex = /_dId_/;
				if (rex.test(url)){
					var start = url.substring(url.search(rex) + 5, url.length);
					did = start.substring(0, start.indexOf('_'));
					if (did) return did;
					return null;
				}
				return null;
			},
			bindAllDerivateButton: function(akt_id, target){
				target.find('.dbPanelButton').bind('click', function(e){
					$('.dbPanelButton .panel').hide();
					var url = AjaxURLManager.getUrlWithKey('dbflyout', {'akt_id': akt_id});
					var panelInner = $(this).find('.inner').empty();
					var elm = $(this);
					$.getJSON(url, function(data, textStatus){
						var title = $('<div class="prdTitle">Produkte zu ' + data.akt_name + '</div>');
						panelInner.append(title);
						var tpl = $('<div class="dbItem"></div>');
						$(data.items).each(function(i){
							var item = tpl.clone();
							item.text(this.prompt);
							var d = this;
							item.bind('click', function(e){
								window.location = '/xist4c/web/Deutsche-Bank_id_2102_.htm?aib=' + data.akt_id_basis + '&lit=' + d.lup_id_typ;
							});
							panelInner.append(item);
						});
						elm.find('.panel').show('fast');
					});
				});
				target.find('.dbPanelButton .panel').bind('mouseleave', function(e){
						$(this).hide();
				});
			},
			update: function(){
				var akt_id = this.getAktId();
				var target = $('#dbPanelTable');
				var url = AjaxURLManager.getUrlWithKey('dbrelatedproducts', {'akt_id': akt_id});
				var self = this;
				$.getJSON(url, function(data, textStatus){
					target.empty();
					self.bindAllDerivateButton(data.akt_id_basis, $('div.dbPanelOuter .dbPanelTopBar'));
					if (data.rows.length > 0){
						JSONPanelContentRenderer.render(data, self, target);
					}else{
						target.append('<p class="statusMsg">Keine Hebelzertifikate verfügbar!</p>');
					}
				});
			}
		}
	);
	
	initDeutscheBankPanel = function(){
		DeuBaPanel = DeutscheBankPanel.create();
		DeuBaPanel.update();
	}
/* << */


// >> DAF Video activation for power editor articles.
	DafVideoActivator = $.extend(
		$.clone(LLObject),
		{
			create: function(){
				var o = LLObject.create.call(this);
				o.vPh = []; // video placeholders.
				return o;
			},
			collectVideos: function(){
				var self = this, imgInfo;
				$('img.dafVideoContainer').each(function(i){
					imgInfo = Utils.getUrlParamsAsJson($(this).attr('src'));
					if (imgInfo && typeof imgInfo === 'object' && typeof imgInfo.vid !== 'undefined'){
						imgInfo.img = $(this);
						self.vPh.push(imgInfo);
					}
				});
			},
			replaceVideoPlaceholder: function(plh, url){
				var outer = $(
					'<div class="powereditor-video-outer viewport">' +
						'<strong>' + $.lang('powereditorVideoHeadline') + '</strong>' +
						'<div class="frameOuter"></div>' +
					'</div>'
				),
				ifrm, attrs = {}, video;
				video = outer.find('.frameOuter');
				video.css({'padding-left': 65});
				ifrm = $('<iframe>' + $.lang('noIframeSupport') + '</iframe>');
				ifrm.css({'border': 'none'});
				attrs.frameborder = 0;
				attrs.scrolling = 'no';
				attrs.height =  405;
				attrs.width =  415;
				attrs.src = url;
				ifrm.attr(attrs);
				video.append(ifrm);
				plh.replaceWith(outer);
			},
			makeVideos: function(){
				var i, vi, url;
				this.collectVideos();
				for (i = 0; i < this.vPh.length; i += 1){
					vi = this.vPh[i];
					url = 'http://partner00.daf.tmt.de/20/iframe.php/20/iframe.php?id=' + vi.vid + '&partner=10&noautostart=1';
					this.replaceVideoPlaceholder(vi.img, url);
				}
			}
		}
	);
	$(function(){
		DafVideoActivator.create().makeVideos();
	});
// <<


// >> boersenkiosk table
	Boersenkiosk = $.extend(
		$.clone(LLObject),
		{
			create: function(opts){
				var o = LLObject.create.call(this);
				o.defaults = {
					target: null
				};
				return o;
			},
			makePanelLayout: function(){
				return $(
					'<div class="boersenkioskOuter"></div>'
				);
			},
			makePanelTitleLayout: function(){
				return $(
					'<div class="title">Aktuelle Börsenbriefe zu diesem Wert</div>'
				);
			},
			makeZeroItemsLayout: function(){
				return $(
					'<div class="zeroItems">Leider gibt es zu diesem Wert keinen aktuellen Börsenbrief.</div>'
				);
			},
			makeTableLayout: function(){
				var lay = $(
					'<table cellpadding="0" cellspacing="0" border="0" class="boersenkiosk"></table>'
				);
				return lay;
			},
			makeRowLayoutClone: function(){
				return $(
					'<tr>' +
						'<td class="date">&nbsp;</td>' +
						'<td class="title"><div class="inner">&nbsp;</div></td>' +
						'<td class="source">&nbsp;</td>' +
						'<td class="price">&nbsp;</td>' +
					'</tr>'
				).clone();
			},
			makeRow: function(data){
			},
			make: function(){
				var target = $('div[id^=boersenkiosk_]'),
				table, url, isin, outer, title, row, self = this, pop, pstr;
				if (target.length){
					outer = this.makePanelLayout();
					title = this.makePanelTitleLayout();
					outer.append(title);
					isin = target.attr('id').replace('boersenkiosk_', '');
					table = this.makeTableLayout();
					url = AjaxURLManager.getUrlWithKey('boersenkiosk', {'isin': isin});
					$.getJSON(url, function(data, textStatus){
						if (data.items.length){
							$(data.items).each(function(i){
								var item = this;
								row = self.makeRowLayoutClone();
								if (i % 2 === 0){row.addClass('even')}
								if (item.date && item.date.__datetime__){
									row.find('.date').text($.formatDate(item.date.value, $.lang())._short);
								}
								if (item.title){
									row.find('.title .inner').text(item.title).bind('click', function(e){
										pstr = 'menubar=no,scrollbars=yes,resizable=yes,status=no,location=no,toolbar=no,width=885,height=460';
										pop = window.open(item.href, 'boersenkiosk', pstr);
										pop.focus();
									});
								}
								row.find('.source').text(item.source);
								row.find('.price').html(item.price + '&euro;');
								table.append(row);
							});
							outer.append(table);
						}else{
							outer.append(self.makeZeroItemsLayout());
						}
						target.append(outer);
					});
				}
			}
		}
	);
	$(function(){
		Boersenkiosk.create().make();
	})
// <<


