/* Theme Pack 3.1.1+ DO NOT modify */
if(!CS){
	var CS = {};
}
CS.v3 = {};
CS.v3.Base = function() {};
CS.v3.Base.prototype = {
	parsePX: function(amount) {
		var parsed = parseInt(amount); 
		var round = Math.round(parsed);
		return round;
	},
	getStyleValue: function(el,style) {
		var el = $(el);
		
		if (style == 'left' || style == 'right' || style == 'top' 
		|| style == 'bottom' || style == 'width' || style == 'height') {
			value = this.parsePX(el.getStyle(style)) || null; return value;
		}
	},
	noJsCSS: function() {
		var noJs = $('no-js');
		if (noJs != null) {noJs.disabled = true; noJs.remove();}
	},
	hideIECover: function(el) {
		if (Prototype.Browser.IE) {
			var ieCover = $(el).select("iframe[class='ie6-cover']");
			var i = ieCover.length;
			//for (var i = 0, l = ieCover.length; i < l; ++i) {
			while(i--){
				ieCover[i].remove();
			}
		}
	},
	getCustomAttribute: function(el,name) { // get Custom Attribute
		var replace = new RegExp(name);
		this.classNames = $w(el.className); // replace
		this.matchedClasses = this.classNames.findAll(function(n) {return n.startsWith(name)})
		var attributes = [];
		this.matchedClasses.each(function(value,index) {
			this.attribute = this.matchedClasses[index].replace(replace,'').strip();
			attributes.push(this.attribute);
		}.bind(this));
		
		if (attributes.length == 0) {return null;} else {return attributes;}
	},
	getCA: function(el,attribute,replace) { // get Custom Attribute
		this.c = el.className + ' ';
		this.att = [];
		this.c.scan(attribute, function(match){this.att.push(match[0])}.bind(this));
		var aStrip = [];
		
		this.att.each(function(value,index) {
			this.a = this.att[index];
			this.a = this.a.replace(replace,'');
			this.a = this.a.strip();
			
			aStrip.push(this.a);
		}.bind(this));
		return aStrip;
	},
	getBlindDuration: function(el) {
		var duration = 0.2
		var height = this.getStyleValue(el,'height');
		if (height >= 150) { duration = 0.3;}
		if (height > 200) { duration = 0.5;}
		return duration;
	},
	navStatus: function(collection,item) {
		var obj;
		var i = collection.length;
		while(i--){
		//for (var i = 0, l = collection.length; i < l; ++i) {
			obj = collection[i];
			// remove status
			if (obj.hasClassName('csNavOn')) {
				obj.removeClassName('csNavOn');
				var selectedItem = i;
			}
		}
		
		// add status
		item.addClassName('csNavOn');
		return selectedItem;
	}
}

CS.v3.getSelected = Class.create(CS.v3.Base.prototype, {
	initialize: function(item,styleRule) {
		this.selectedIndex = -1;
		this.isFirst = false;
		this.isLast = false;
		
		this.collectionWrap = item.up('*');
		this.collection = this.collectionWrap.select(styleRule);
		
		this.first = this.collection.first();
		this.last = this.collection.last();
		
		item.addClassName('selected');

		this.collection.each(function(value,index) {

			var i = this.collection[index];
			if (i.hasClassName('selected')) {
				this.selectedIndex = index;

				if (this.selectedIndex == 0) {this.isFirst = true;}
				if (this.selectedIndex == (this.collection.length -1)) {this.isLast = 'true';}
			}
			
		}.bind(this));
		
		item.removeClassName('selected');
	}
});


CS.v3.AjaxNav = Class.create(CS.v3.Base.prototype, {
	initialize: function(el,updateTarget,param) {
		this.el = el;
		var time = new Date().getTime();
		var timeParam = '&time=' + time;
		
		if (param.bind) {this.bindEvent = true;}
		if (!param.bind) {this.bindEvent = false;}
		
		if(!param.param) {param.param = ''}
		
		if (this.el.tagName == 'A') {this.url = this.el.href;}
		if (this.el.tagName == 'FORM') {this.url = this.el.action}
		
		this.query = 'false';
		
		// check for "?"
		this.url.scan(/\?+/,function() {this.query = 'true'}.bind(this));
		
		if (this.query == 'false') {
			
			this.mainUrl = this.url + '?' + 'ajax=true' + timeParam + '&' + param.param;
		}
		else {this.mainUrl = this.url + '&' + 'ajax=true' + timeParam + '&' + param.param;}
		
		
		new Ajax.Request(this.mainUrl, {method: 'get',
			onCreate: function () {this.processing(updateTarget)}.bind(this),
			onComplete: function(request) {this.loader(request,updateTarget)}.bind(this)
		});
	},
	processing: function(updateTarget) {
		updateTarget.innerHTML = ''; //request.responseText;
		updateTarget.addClassName('ajax-spinner');
	},
	loader: function(request,updateTarget) {
	
		updateTarget.removeClassName('ajax-spinner');
		updateTarget.innerHTML = request.responseText;
		
		// Add events to snippet
		if (this.bindEvent) {
			new CS.v3.Config(updateTarget,{bind:'true', set:'true'});
		}
	}
});

CS.v3.Components = {};
CS.v3.Config = {};
CS.v3.Config = Class.create(CS.v3.Base.prototype, {
	initialize: function(el,options) {
		var obj;
		for (var i in CS.v3.Components) {
			obj = CS.v3.Components[i];
			if (obj instanceof Function) {
				this.comp = obj;
				this.comp(el,options);
			}
		}
	}
});

document.observe("dom:loaded", function() {
	var body = $$('body');
	CS.v3.Base.prototype.noJsCSS();

	new CS.v3.InterstitialInit();

	new CS.v3.Config(body[0],{bind:'true', set:'true'});
});

CS.v3.InterstitialInit = Class.create(CS.v3.Base.prototype, {
	initialize: function() {
		this.bind();
	},
	bind: function(){
		Event.observe(window,'unload', function(event){ CS.v3.Interstitial.action(); } );
		Event.observe(window,'beforeunload', function(event){ CS.v3.Interstitial.before(); } );
	}
});

CS.v3.Interstitial = {
	before: function(){	this.showInst();},
	action: function(){ this.showInst();},
	showInst: function(){ 
		var inst = document.getElementById('interstitial');
		if (inst) {inst.style.display='block';}
	}
}


//CS.v3.Components.hideIEFocus = function(el,options) {new CS.v3.Config.hideIEFocus(el,options)};
CS.v3.Config.hideIEFocus = Class.create(CS.v3.Base.prototype, {
	initialize: function(el,options) {
		if (Prototype.Browser.IE) {this.ieMenuItems = $(el).select("div.csTabs li a"); this.bind();}
	},
	bind: function() {
		var ar = this.ieMenuItems;
		var obj;
		var i = ar.length;
		//for (var i = 0, l = ar.length; i < l; ++i) {
		while(i--){
			obj = ar[i];
			Event.observe(obj, 'focus', function(event) {
				var target = $(Event.element(event)); 
				target.hideFocus = true;
			});
		}
	}
});


// GET SETTINGS
CS.v3.getCompNode = Class.create(CS.v3.Base.prototype, {
	initialize: function(target) {
		
		this.getClass = this.getClasses(target);
		this.compNode = '';
		if(this.getClass){
		this.compNode = CS.v3.up(target,this.getClass);
		}
	},
	getClasses: function(target) {
		
		this.classNames = $w(target.className);
		this.classNames.each(function(name) {
			var obj = CS.v3.componentTargets[name];
			if (obj) {this.getComponentName = obj.component;}
		}.bind(this)); 
		
		return this.getComponentName; 
	}
});

CS.v3.ComponentAttributes = Class.create(CS.v3.Base.prototype, {
	initialize: function(target) {
		// all DOM
		this.readToShow = target.readAttribute('data-csNodesToShow');
		this.showContent = $$(this.readToShow);
		
		this.readToHide = target.readAttribute('data-csNodesToHide');
		this.hideContent = $$(this.readToHide);
		
		this.readToToggle = target.readAttribute('data-csNodesToToggle');
		this.toggleContent = $$(this.readToToggle);
		
		// up DOM
		this.readToHideUp = target.readAttribute('data-csNodeToHideUp');
		if (this.readToHideUp) {this.hideContentUp = CS.v3.up(target,this.readToHideUp);}
		
		this.readToRemoveUp = target.readAttribute('data-csNodeToRemoveUp');
		if (this.readToRemoveUp) {this.removeContentUp = CS.v3.up(target,this.readToRemoveUp);}
	}
});


CS.v3.Components.addOver = function(section,options) {new CS.v3.Config.addOver(section,options)};
CS.v3.Config.addOver = Class.create(CS.v3.Base.prototype, {
	initialize: function(section) {
		var mouseOver = $$('.csOver');
		new CS.v3.addEvents(mouseOver,'over');
	}
});


/*** ADD EVENTS ***/
CS.v3.Components.addEvents = function(section,options) {
	var version3;
	if (section.match('body.csV-3')) {
		version3 = $$('.csV-3');
	} else {
		version3 = section.select('.csV-3');
	}
	
	new CS.v3.addEvents(version3,'click');
};

CS.v3.addEvents = Class.create(CS.v3.Base.prototype, {
	initialize: function(sections,eventType) {
		//this.log('initialize:init');
		 // wrap is body
		this.observeNodes = sections;
		if (eventType == 'click') {this._bindClick()}
		if (eventType == 'over') {this._bindOver()}
	},
	_bindClick: function() {
		//this.log('_getClasses:init');
		this.observeNodes.each(function(node) {
			Event.observe(node, 'click', function(event) {
				var target = $(Event.element(event));
				new CS.v3.CloseNavsX(target);
			
				this._handle(event,'.csClick');
			}.bind(this));
			
			//Note: Required for IE Fixed dropdown to work
			Event.observe(node, 'keydown', function(event) { 
			
				if (event.keyCode == Event.KEY_RETURN) {
				
					this._handle(event,'.csClick');
				}
			}.bind(this));
		
		}.bind(this));
	},
	_bindOver: function() {
		//this.log('_bindOver:init');
		var ar = this.observeNodes;
		var node;
		var i = ar.length;
		//this.observeNodes.each(function(node) {
		while(i--){
			node = ar[i];
			Event.observe(node, 'mouseover', function(event) { 
			
				this._handle(event,'.csOver');
			}.bind(this));
			
			Event.observe(node, 'mouseout', function(event) {
			
				this._handle(event,'.csOver');
			}.bind(this));
			
			
			Event.observe(node, 'keydown', function(event) { 
			
				if (event.keyCode == Event.KEY_RETURN) {
				
					this._handle(event,'.csOver');
				}
			}.bind(this));
		}
		//}.bind(this));
		//this.log('_bindOver:exit');
	},
	_handle: function(event,eventClass) {
		//this.log('_handle:init');
		var target = $(Event.element(event));
		var elements = new CS.v3.getCompNode(target,event);
		
		if (target.match(eventClass) || elements.compNode.match(eventClass)) {
			
			this._getClasses(target,event);
			event.preventDefault(event);
		}
		//this.log('_handle:exit');
	},
	_getClasses: function(target,event) {
		//this.log('_getClasses:init');
		var classNames = $w(target.className);
		var name;
		var obj;
		var i = classNames.length;
		//classNames.each(function(name) {
		while(i--){
			name = classNames[i];
			obj = CS.v3.componentTargets[name];
			if (obj){
				obj.fire(target,event);
			}
		}
		//});
		//this.log('_getClasses:exit');
	},
	log: function(s){
		CS.v3.Logger.log('addEvents:' + s);
	}
});


// GET TARGETS & WRAPS
CS.v3.componentTargets = {};
CS.v3.componentTargets = {
	'csToggle': {
		component:'',
		fire: function(target,event) {
		
			var attr = new CS.v3.ComponentAttributes(target);
			var targetWrap = target.up(0,'.csIcon');
			
			new CS.v3.ToggleDisplay(target,attr);
			
			target.toggleClassName('csToggleShow');

			if (targetWrap) {
				targetWrap.toggleClassName('csIconShow');
			}
			
		}
	},
	'csNavToggle': {
		component:'.csNav-y,.csNav-x',
		fire: function(target,event) {
		
			if (event.type == 'click' || event.type == 'keydown') {
				
				new CS.v3.Menu(event);
			}
			
			if (event.type == 'mouseover') {
				
				this.item = CS.v3.getParentElement(target,'LI');
				
				if (this.item && this.item.match('.csNavShow')) {return} //for mouseover only
				new CS.v3.Menu(event);
			}
		}
	},
	'csHidePanels': {
		component:'',
		fire: function(target,event,section) {
		
			var attr = new CS.v3.ComponentAttributes(target);
			var ar = attr.hideContent;
			var i = ar.length;
			var panel;
			var panelWrap;
			var panelHeading;
			//attr.hideContent.each(function(panel) {
			while(i--){
				panel = ar[i];
				panelWrap = CS.v3.getParentElementWithClass(panel,'.csPanel');
				panelHeading = CS.v3.getParentElementWithClass(panel,'.csPanelHeading');
				
				if (!panelWrap.match('.csPanelHide') && panelHeading.match('.csClick')) {new CS.v3.Panel(panel)}
			}
			//});
		}
	},
	'csShowPanels': {
		component:'',
		fire: function(target,event) {
		
			var attr = new CS.v3.ComponentAttributes(target);
			var ar = attr.showContent;
			var i = ar.length;
			var panel;
			var panelWrap;
			var panelHeading;
			//attr.showContent.each(function(panel) {
			while(i--){
				panel = ar[i];
				panelWrap = CS.v3.getParentElementWithClass(panel,'.csPanel');
				panelHeading = CS.v3.getParentElementWithClass(panel,'.csPanelHeading');
				
				if (panelWrap.match('.csPanelHide') && panelHeading.match('.csClick')) {new CS.v3.Panel(panel)}
			//});
			}
		}
	},
	'csPanelToggle': {
		component:'.csPanelHeading',
		fire: function(target,event) {
			new CS.v3.Panel(target);
		}
	},
	'csPanelToggleText': {
		component:'.csPanelHeading',
		fire: function(target,event) {
		
			new CS.v3.Panel(target);
		}
	},
	'csTabToggle': {
		component:'.csTabs-x,.csTabs-y',
		fire: function(target,event) {
			new CS.v3.Tabs(target);
		}
	},
	'csHintToggle': {
		component:'',
		fire: function(target,event) {
			new CS.v3.getHints(target);
		}
	},
	'csOverlayToggle': {
		component:'',
		fire: function(target,event) {
			var attr = new CS.v3.ComponentAttributes(target);
			new CS.v3.PanelOverlay(target,event,attr);
		}
	},
	'csOverlayClose': {
		component:'',
		fire: function(target,event,section) {
			new CS.v3.PanelPopClose(target,event);
		}
	},
	'csAddEntryRow': {
		component:'',
		fire: function(target,event) {
			new CS.v3.addAddEntryContent(target);
		}
	},
	'csRemove': {
		component:'',
		fire: function(target,event) {
			//new CS.v3.cancelAddEntryContent(target);
			var attr = new CS.v3.ComponentAttributes(target);
			attr.removeContentUp.remove();
		}
	},
	'csCancelEntryRow': {
		component:'',
		fire: function(target,event) {
			new CS.v3.cancelAddEntryContent(target);
			
			var attr = new CS.v3.ComponentAttributes(target);
			attr.removeContentUp.remove();
		}
	},
	'csFader': {
		component:'',
		fire: function(target,event) {
			var overlays = $$('.csOverlayContainer');
			//overlays.each(function(overlay) {
			var overlay;
			var close;
			var i = overlays.length;
			while(i--){
				overlay = overlays[i];
				close = CS.v3.down(overlay,'.csOverlayClose.');
				new CS.v3.PanelPopClose(close,event);
			}
			//});
		}
	}
}

/*** Effects ***/
CS.v3.ToggleDisplayEffect = Class.create(CS.v3.Base.prototype, {
	initialize: function(target,toggle,toggleTarget,wrap,toggleClass,defaultState) {
		this.target = target;
		this.toggle = toggle;
		this.wrap = wrap;
		this.toggleTarget = toggleTarget;
		this.toggleClass = toggleClass;
		
		// simple toggle
		if (!this.wrap.match('.csBlind') && !this.wrap.match('.csOpacity')) {
			this.toggleTarget.toggleClassName(this.toggleClass);
		}
		
		// blind up and down
		if (this.wrap.match('.csBlind') || this.wrap.match('.csAccordian')) {
		
			if (defaultState == 'hidden') {
				if (this.toggle.hasClassName(this.toggleClass)) {this._blindUp() 
				} else {this._blindDown();}
			}
			
			if (defaultState != 'hidden') {
				if (this.toggle.hasClassName(this.toggleClass)) {this._blindDown() 
				} else {this._blindUp();}
			}
		}
		
		// opacity
		if (this.wrap.match('.csOpacity')) {
		
			if (defaultState == 'hidden') {
				if (this.toggle.hasClassName(this.toggleClass)) {this._opacityHide() 
				} else {this._opacityShow();}
			}
			
			if (defaultState != 'hidden') {
				if (this.toggle.hasClassName(this.toggleClass)) {this._opacityShow() 
				} else {this._opacityHide();}
			}
		}
		
	},
	_blindDown: function() {
	
		this.height = this.toggleTarget.getDimensions();
		this.height = this.height.height;
		this.time = CS.v3.Base.prototype.getBlindDuration(this.toggleTarget);
	
		new Effect.BlindDown(this.toggleTarget, {duration: this.time, queue: {position: 'front', scope: 'hiddenLi'},
		
			beforeStart: function() {
			
				this.target.addClassName('csTargetShow');
				this.toggleTarget.style.display = 'none';
				this.toggleTarget.style.height = 'auto';
				this.toggle.toggleClassName(this.toggleClass);
			}.bind(this),
			
			afterFinish: function() {
				//ie 6 only items disappear without this
				this.toggleTarget.style.height = '';
				this.toggleTarget.style.display = 'block';
				//ie 6 only
				CS.v3.MenuState = null;
			}.bind(this)
		});
	},
	_blindUp: function() {
	
		this.height = this.toggleTarget.getDimensions();
		this.height = this.height.height;
		this.time = CS.v3.Base.prototype.getBlindDuration(this.toggleTarget);
	
		new Effect.BlindUp(this.toggleTarget, {duration: this.time, queue: {position: 'end', scope: 'shownLi'},
		
			//new
			beforeStart: function() {
				
				this.target.removeClassName('csTargetShow');
				this.toggleTarget.style.height = this.height;
				this.toggleTarget.style.overflow = 'hidden';
			}.bind(this),
			//new
			
			afterFinish: function() {
				
				this.toggle.toggleClassName(this.toggleClass);
				CS.v3.MenuState = null;
			}.bind(this)
		});
	},
	_opacityShow: function() {
	
		new Effect.Opacity(this.toggleTarget, {from: 0.0 , to: 1.0, duration:0.4,
		
			beforeStart: function() {
				
				this.target.addClassName('csTargetShow');
				this.toggle.toggleClassName(this.toggleClass);
			}.bind(this)
		});
	},
	_opacityHide: function() {
	
		new Effect.Opacity(this.toggleTarget, {from: 1.0 , to: 0.0, duration:0.4,
		
			afterFinish: function() {
				
				this.target.removeClassName('csTargetShow');
				this.toggle.toggleClassName(this.toggleClass);
			}.bind(this)
		});
	}
});


// New 3.0
CS.v3.ToggleDisplay = Class.create(CS.v3.Base.prototype, {
	initialize: function(toggle,attr,section) {
		/* effect */
		if (!toggle.match('.csOpacity') && !toggle.match('.csBlind')) {this.effect = 'show/hide';}
		if (toggle.match('.csBlind')) {this.effect = 'blind';}
		if (toggle.match('.csOpacity')) {this.effect = 'opacity';}
		
		this._toggleCollection(attr);
	},
	_toggleCollection: function(attr) {
		// All DOM
		var arShow = attr.showContent;
		var arHide = attr.hideContent;
		var arToggle = attr.toggleContent;
		arShow.each(function(el) {
			var toggleFunction = function() {
				el.removeClassName('csHide');
			};
			this._showAll(el,toggleFunction);
		
		}.bind(this));
		
		arHide.each(function(el) {
			var toggleFunction = function() {
				if (!el.hasClassName('.csHide')){// dedupe
					el.addClassName('csHide');
				}
			};
			this._hideAll(el,toggleFunction)
		
		}.bind(this));
		
		arToggle.each(function(el) {
			
			if (el.match('.csHide')) {
				
				var toggleFunction = function() {el.toggleClassName('csHide')};
				this._showAll(el,toggleFunction);
				
			} else {
			
				var toggleFunction = function() {el.toggleClassName('csHide')};
				this._hideAll(el,toggleFunction)
			}
			
		}.bind(this));
		
		// Up DOM
		var obj = attr.hideContentUp;
		if (obj) {
			if (!obj.hasClassName('.csHide')){//dedupe
				obj.addClassName('csHide');
			}
		}
	},
	_showAll: function(el,toggleFunction) {
	
		if (this.effect == 'show/hide') {toggleFunction()}
		if (this.effect == 'opacity') {CS.v3.ToggleEffect._opacityShow(el,toggleFunction);}
		if (this.effect == 'blind') {CS.v3.ToggleEffect._blindDown(el,toggleFunction)}
		
	},
	_hideAll: function(value,toggleFunction) {
	
		if (this.effect == 'show/hide') {toggleFunction()}
		if (this.effect == 'opacity') {CS.v3.ToggleEffect._opacityHide(el,toggleFunction)}
		if (this.effect == 'blind') {CS.v3.ToggleEffect._blindUp(el,toggleFunction)}
	},
	log: function(s){
		CS.v3.Logger.log("ToggleDisplay:" + s);
	}
});


CS.v3.ToggleEffect = {
	_opacityShow: function(toggleTarget,toggleFunction) {
	
		new Effect.Opacity(toggleTarget, {from: 0.0 , to: 1.0, duration:0.4,
		
			beforeStart: function() {
			
				toggleFunction();
				//this.toggle.toggleClassName(this.toggleClass);
			}.bind(this)
		});
	},
	_opacityHide: function(toggleTarget,toggleFunction) {
	
		new Effect.Opacity(toggleTarget, {from: 1.0 , to: 0.0, duration:0.4,
		
			afterFinish: function() {
				
				toggleFunction();
			}.bind(this)
		});
	},
	_blindDown: function(toggleTarget,toggleFunction) {
	
		this.height = toggleTarget.getDimensions();
		this.height = this.height.height;
		this.time = CS.v3.Base.prototype.getBlindDuration(toggleTarget);
	
		new Effect.BlindDown(toggleTarget, {duration: this.time, queue: {position: 'front', scope: 'hiddenLi'},
		
			beforeStart: function() {
				
				toggleTarget.style.display = 'none';
				toggleTarget.style.height = 'auto';
				//this.toggle.toggleClassName(this.toggleClass);
			}.bind(this),
			
			afterFinish: function() {
				//ie 6 only items disappear without this
				toggleTarget.style.height = '';
				toggleTarget.style.display = 'block';
				//ie 6 only
				CS.v3.MenuState = null;
			}.bind(this)
		});
	},
	_blindUp: function(toggleTarget,toggleFunction) {
	
		this.height = toggleTarget.getDimensions();
		this.height = this.height.height;
		this.time = CS.v3.Base.prototype.getBlindDuration(toggleTarget);
	
		new Effect.BlindUp(toggleTarget, {duration: this.time, queue: {position: 'end', scope: 'shownLi'},
		
			//new
			beforeStart: function() {
				
				toggleTarget.style.height = this.height;
				toggleTarget.style.overflow = 'hidden';
			}.bind(this),
			//new
			
			afterFinish: function() {
				//this.toggle.toggleClassName(this.toggleClass);
				CS.v3.MenuState = null;
			}.bind(this)
		});
	}
};

CS.v3.styleZIndex = {
	active : function(target,compNode) {
		if (compNode) {compNode.addClassName('csZindex');}
	
		//apply to context
		var getContextNodeAttr = target.readAttribute('data-csOverlayContextNode');
		
		if (getContextNodeAttr) {
			var getContextNode = CS.v3.up(target,getContextNodeAttr);
			
			if (getContextNode) {
				
				getContextNode.addClassName('csZindex');
			}
		}
	},
	inactive : function(target,compNode) {
		if (compNode) {compNode.removeClassName('csZindex');}
		
		//apply to context
		var getContextNodeAttr = target.readAttribute('data-csOverlayContextNode');
		
		if (getContextNodeAttr) {
			
			var getContextNode = CS.v3.up(target,getContextNodeAttr);
			
			if (getContextNode) {
				
				getContextNode.removeClassName('csZindex');
			}
		}
	},
	log: function (s) {
		CS.v3.Logger.log("styleZIndex:" + s);
	}
}


/* Reverses zindex layers*/
CS.v3.Components.zIndex = function(section,options) {new CS.v3.zIndex(section,options)};
CS.v3.zIndex = Class.create(CS.v3.Base.prototype, {
	initialize: function(el) {
		//this.log('initialize:init');
		this.tables = $$('table.csTable');
		this._addRowIndex();
		//this.log('initialize:exit');
	},
	_addRowIndex: function() {
		//this.log('_addRowIndex:init');
		this.tables.reverse();
		
		this.tables.each(function(table,n1) {
			var n1 = n1 + 100;
			
			this.trs = table.select('tr','.csRow');
			this.trs = this.trs.reverse();
			
			this.trs.each(function(tr,num) {
				
				this.z = num + 100;
				var tds = tr.select('td');
				
				tds.each(function(td) {
					
					var field = CS.v3.down(td,'DIV.csFields');
					var label = CS.v3.down(td,'DIV.csLabel');
					
					if (field) {
						
						field.setStyle({zIndex: this.z});
					}
					
					if (label) {
						
						label.setStyle({zIndex: this.z});
					}
					
					
				}.bind(this));
			
			}.bind(this));
			
		}.bind(this));
		//this.log('_addRowIndex:exit');
	},
	log: function (s) {
		CS.v3.Logger.log("zIndex:" + s);
	}
});
CS.v3.fireOnchange = function(el) {
	try{
		if(document.dispatchEvent) { // W3C
			var oEvent = document.createEvent("MouseEvents");
			oEvent.initMouseEvent('change', true, true,window, 1, 1, 1, 1, 1, false, false, false, false, 0, el);
			el.dispatchEvent( oEvent );
		} else {
			if(document.fireEvent) { // IE
				el.fireEvent('onchange');
			}
		}
	}
	catch(e){
		CS.v3.Logger.log('fireOnchange:e=' + e);
	}
};
CS.v3.up = function(el,arg,idx) {
	var rc;
	if(el){
		rc = el.up(arg);
	}
/*
	el = $(el);
	if (arg.length == 1) {
		rc = $(el.parentNode);
	} else if (Object.isNumber(arg)) {
		// return the nth parent , 0 is direct
		rc = el;
		do {
			rc = $(rc.parentNode);
		} while (rc && --arg >= 0);
		rc = $(rc);
	} else {
		var tagName;
		if (/^[^\.\*\s]+$/.test(arg)) {
			tagName = arg.toUpperCase();
			rc = CS.v3.getParentElement(el,arg);
		} else {
			if (/^\.[^\.\*\s]+$/.test(arg)) {
				rc = CS.v3.getParentElementWithClass(el,arg.substring(1));
			} else {
				if (/^[^\.\*\s]+\.[^\.\*\s]+$/.test(arg)) {
					var tagAndClass = arg.split('.');
					var tmp = el;
					tagName = tagAndClass[0].toUpperCase();
					do {
						tmp = $(CS.v3.up(tmp,tagName));
					} while (tmp && !tmp.hasClassName([tagAndClass[1]]));
					rc = tmp;
				}
			}
		}
		if (Object.isNumber(idx) && idx >0) {
			rc = CS.v3.up(rc, arg, idx-1);
		}
	}
*/
	return rc;
};
CS.v3.down = function(el,arg){
	var rc;
	if(el){
		rc = el.down(arg);
	}
	return rc;
};
CS.v3.getParentElement = function(el,tag){
	var parent = el;
	var mytag = tag.toUpperCase()
	do {
		parent = parent.parentNode;
	} while (parent && (mytag != parent.tagName ));
	if (parent) {
		return $(parent);
	}
};
CS.v3.getParentElementWithClass = function(el,cls){
/* var rc = CS.v3.up(el,cls); return rc; */
	var parent = el;
	if(cls){
		if(cls.startsWith('.')){
			cls = cls.substring(1);
		}
		var exit = false;
		var tag;
		do {
			parent = parent.parentNode;
			tag = parent.tagName;
			if(tag == 'HTML'){
				exit = true;
			}
		} while (!exit && parent && (!$(parent).hasClassName(cls)));
		if (parent) {
			return $(parent);
		}
	}
};
CS.v3.getParentElementWithClass_TEST = function(el,cls){
	var parent = el;
	if(cls){
		if (cls.startsWith('.')) {
			cls = cls.substring(1);
		}
		var re = new RegExp("(^|\\s)" + cls + "(\\s|$)");
		var classes;
		do {
			parent = parent.parentNode;
			classes = parent.className?parent.classname:null;
		} while (parent && !(classes && classes.length>0 && (classes==cls || re.test(classes))));
	}
	if (parent) {
		return $(parent);
	}
};
CS.v3.HTML = {
	errorBox: function() {return '<div class="csPanel csPanelError">' +
	'<div class="csPanelTopLeft"><div class="csPanelTopRight">' + 
	'<div class="csPanelContent"><div class="csPanelScroll">' +
	'<div class="csErrorMsg"></div>' +
	'</div></div>' +
	'</div></div>' +
	'<div class="csPanelBottomLeft"><div class="csPanelBottomRight"></div></div>' +
	'<div class="csChevron csChevronLeft"></div>' +
	'</div>'},
	errorBoxCount: '<div class="csPanel csFormStatus csPanelStatus csPanelErrors csBoxHide">' +
	'<div class="csPanelTopLeft"><div class="csPanelTopRight">' + 
	'<div class="csPanelContent"><div class="csPanelScroll">' +
	'<div class="csErrorMsg">' +
	'<h3>There are <span class="csCount"></span>&nbsp;errors with the page you are trying to submit.</h3>' +
	'</div>' +
	'</div></div>' +
	'</div></div>' +
	'<div class="csPanelBottomLeft"><div class="csPanelBottomRight"></div></div>' +
	'<div class="csChevron csChevronLeft"></div>' +
	'</div>',
	box: '<div id="box" class="pop hide"><div class="box box-em">' +
	'<div class="heading"><div class="col-right"><a class="control close" title="close" href="#"><span>X</span></a></div>' +
	'<h3 class="toggle"></h3></div>' +
	'<div class="chevron"></div>' +
	'<div class="content">Text</div></div></div><div id="fader" class="hide"></div>',
	ieCover: '<div class="ie6-cover"><iframe tabindex="-1" title="iframe for fixing ie bug" src="" scrolling="no" frameborder="0" border="0" framespacing="0" name=""></iframe></div>'
};
/* MOVED FROM i18n.js */
function StringBuffer(){
	this.buffer = [];
};
StringBuffer.prototype.append = function append(string){
	this.buffer.push(string);
	return this;
};
StringBuffer.prototype.toString = function toString(){
	return this.buffer.join("");
};
if(!CS.I18N){
	CS.I18N = {
		I18NValues: [],
		I18NDefaultLocale: 'default',
		findHash: function(key,locale){
			var b = this.isEmpty(locale);
			if(b){
				locale = this.I18NDefaultLocale;
			}
			var rc = key + '|' + locale;
			return rc;
		},
		isEmpty: function(x){
			var rc = false;
			if(x=='undefined' || x==null || x==undefined || x==''){
				rc = true;
			}
			return rc;
		},
		addProperty: function(key,locale,val){
			var hash = this.findHash(key,locale);
			this.I18NValues[hash] = val;
		}
	};
}
CS.v3.Logger = {
	error: function(s) {
		this.log('<em>' + s + '</em>');
	},
	log: function (s) {
		var el = $("log");
		if (el){
			el.innerHTML += ("<li>v3:" + s + "</li>");
		}
	}
}
CS.v3.I18N = {
  initialize: function(el){
	var rc = this.initializeLocale(el,'');
	return rc;
  },
  initializeLocale: function(el,locale){
	if(this.isEmpty(locale)){
		locale = this.walkUpTreeForLocale(el);
		if(this.isEmpty(locale)){
			locale = CS.I18N.I18NDefaultLocale;
		}
		this.setLocale(el,locale);
	}
	return locale;
  },
  isEmpty: function(x){
	return CS.I18N.isEmpty(x);
  },
  getTagName: function(el){
	var rc = '';
	if(el){
		rc = el.tagName;//testing  ('' + this.toUpper(el.tagName);
	}
	return rc;
  },
  arrayHelper: function(ar,val){
	var rc = '';
	if(ar!=null){
		var x = ar[val];
		if(!this.isEmpty(x)){
			rc = x;
		}
	}
	return rc;
  },
  walkUpTreeForLocale: function(el){
	var locale=this.getLocale(el);
	if(this.isEmpty(locale)){
		var startEl = el;
		var exit = false;
		var tag;
		while(this.isEmpty(locale) && exit==false){
			if(el){
				el = el.up();
				locale = this.getLocale(el);
				tag = this.getTagName(el);
				if(tag == 'HTML'){
					exit = true;
				}
			} else {
				exit = true;
			}
		}
		// add the language to the first element to simplify future searches.
		var bl = this.isEmpty(locale);
		if(!bl){
			this.setLocale(startEl,locale);
		}
	}
	return locale;
  },
  getLocale: function(el){
	var locale='';
	if(el){
		locale = el.readAttribute('lang');
		if(this.isEmpty(locale)){
			locale = el.readAttribute('xml:lang');
		}
	}
	return locale;
  },
  setLocale: function(el,locale){
	this.updateAttribute(el,'lang',locale);
	this.updateAttribute(el,'xml:lang',locale);
  },
  getYear_numeric: function(el,val){
	var x = this.convertNumber(el,val);
	var rc = this.zeroPad(el,x,4);
	return rc;
  },
  getNumbers: function(el){
	var rc = this.findProperty(el,'numbers');
	return rc;
  },
  getNumber: function(el,val){
	var ar = this.getNumbers(el);
	var size = ar.length;
	var i = parseInt(val);
	if(i<size){
		rc = ar[i];
	}
	return rc;
  },
  getSymbols: function(el){
	var rc = this.findProperty(el,'symbols');
	return rc;
  },
  getSymbol: function(el,val){
	var ar = this.getSymbols(el);
	var size = ar.length;
	var i = parseInt(val);
	if(i<size){
		rc = ar[i];
	}
	return rc;
  },
  getSymbol_thousands: function(el){
	return this.getSymbol(el,0);
  },
  getSymbol_decimal: function(el){
	return this.getSymbol(el,1);
  },
  getSymbol_time: function(el){
	return this.getSymbol(el,2);
  },
  getUnit: function(el,val){
	var rc = this.findProperty(el,'units_long');
	return rc;
  },
  getUnit_days: function(el){
	return this.getUnit(el,0);
  },
  getUnit_hours: function(el){
	return this.getUnit(el,1);
  },
  getUnit_minutes: function(el){
	return this.getUnit(el,2);
  },
  getUnit_seconds: function(el){
	return this.getUnit(el,3);
  },
  getUnit_milliseconds: function(el){
	return this.getUnit(el,4);
  },
  getCalculator: function(el){
	var rc = this.getNumbers(el);
	return rc;
  },
  calcOffset: function(symbol,days,hours,minutes,seconds,mms){
	var millis = mms;
	millis += 86400000*days;
	millis +=   360000*hours;
	millis +=    60000*minutes;
	millis +=     1000*seconds;
	if(symbol=='-'){
		millis = millis * -1;
	}
	return millis;
  },
  setDateObj:function(yr,mo,da){
	var rc = new Date(yr,mo-1,da);
	return rc;
  },
  createDate: function(val){
	var rc = null;
	if(this.isEmpty(val)){
		rc = new Date();
	} else {
		rc = new Date(val);
	}
	return rc;
  },
  offsetDate: function(offset,isUTC){
	var rc='';
	if(offset==0){
		rc = this.createDate();
	} else {
		var longDate = 0;
		if(isUTC){
			var utc = this.getUTC();
			longDate = utc + offset;
		} else {
			var dt = this.createDate();
			var now = dt.getTime();
			longDate = now + offset;
		}
		rc = this.createDate(longDate);
	}
	return rc;
  },
  localeSort: function(string1, string2) {
	return string1.toString().localeCompare(string2.toString());
  },
  timeDiff: function(dateNew, dateOld){
	var rc = 0;
	var b1 = this.isEmpty(dateOld);
	var b2 = this.isEmpty(dateNew);
	if(!b1 && !b2){
		rc = dateNew - dateOld;
	}
	return rc;
  },
  timeDiffPattern: function(el,millis, pattern){
	var days = 0;
	var hours = 0;
	var minutes = 0;
	var seconds = 0;
	if(millis>86400000){
		days = Math.floor(millis / 86400000);
		millis = millis - (days * 86400000);
	}
	if(millis>3600000){
		hours = Math.floor(millis / 3600000);
		millis = millis - (hours * 3600000);
	}
	if(millis>60000){
		minutes = Math.floor(millis / 60000);
		millis = millis - (minutes * 60000);
	}
	if(millis>1000){
		seconds = Math.floor(millis / 1000);
		millis = millis - (seconds * 1000);
	}
	var ampm=null;
	var tz = null;
	var rc = this.pattern_replace(el,pattern, tz, -1, -1, days, hours, minutes, seconds, millis, ampm);
	return rc;
  },
  timeDiffText: function(el,millis){
	var days = 0;
	var hours = 0;
	var minutes = 0;
	var seconds = 0;
	if(millis>86400000){
		days = Math.floor(millis / 86400000);
		millis = millis - (days * 86400000);
	}
	if(millis>3600000){
		hours = Math.floor(millis / 3600000);
		millis = millis - (hours * 3600000);
	}
	if(millis>60000){
		minutes = Math.floor(millis / 60000);
		millis = millis - (minutes * 60000);
	}
	if(millis>1000){
		seconds = Math.floor(millis / 1000);
		millis = millis - (seconds * 1000);
	}
	var buffer = [];
	if(days > 0){
		buffer.push( days );
		buffer.push( this.getUnit_days(el) );
	}
	if(hours > 0){
		buffer.push( this.zeroPad(el,hours, 2) );
		buffer.push( this.getUnit_hours(el) );
	 }
	if(minutes > 0){
		buffer.push( this.zeroPad(el,minutes,2) );
		buffer.push( this.getUnit_minutes(el) );
	}
	if(seconds > 0){
		buffer.push( this.zeroPad(el,seconds,2) );
		buffer.push( this.getUnit_seconds(el) );
	}
	if(millis > 0){
		 buffer.push(millis);
		 //buffer.push( this.getUnit_milliseconds(el) );
	}
	return buffer.join('');
	},
  zeroPad: function(el,x,len){
	var rc = new String(x + '');
	var zero = this.getNumber(el,0);
	var zlen = this.getLength(zero);
	if(zlen>0){// NOTE: this is a Sanity check for the I18N framework, we do not want to iterate forever if EMTPY!
		while(this.getLength(rc) < len){
			rc = new String(zero + rc);
		}
	}
	return rc;
  },
  zeroTrim: function(el,x,len){
	/* NOTE: this is currently intentionally designed to only trim ONE leading zero, it will likely be enhanced in the future */
	var rc = new String(x + '');
	var zero = this.getNumber(el,0);
	var zlen = this.getLength(zero);
	var c;
	var b;
	if(zlen>0){// NOTE: this is a Sanity check for the I18N framework, we do not want to iterate forever if EMTPY!
		c = rc.substring(0, 1);
		b = (c==zero);
		if(b){
			rc = rc.substring(1,rc.length);
		}
	}
	return rc;
  },
  convertNumber: function(el,x){
	var rc='';
	var b = this.isEmpty(x);
	if(!b){
		rc = x;
		var repVal;
		var i=10;
		while(i--){
			repVal = this.getNumber(el,i);
			rc = this.replaceString(rc,i,repVal);
		}
	}
	return rc;
  },
  unconvertNumber: function(el,x){
	var rc='';
	var b = this.isEmpty(x);
	if(!b){
		rc = x;
		var repVal;
		var i=10;
		while(i--){
			repVal = this.getNumber(el,i);
			rc = this.replaceString(rc,repVal,i);
		}
	}
	return rc;
  },
  repChar:function(x,oldChar,newChar){
	var rc = x + '';
	rc = rc.gsub(oldChar,newChar);
	return rc;
  },
  pattern_obj: function(el,pattern,dt){
	var rc = '';
	//var b = this.isEmpty(dt);
	if(dt){
		var yr = dt.getFullYear();
		var mo = dt.getMonth() + 1;
		var da = dt.getDate();
		var hr = dt.getHours();
		var mi = dt.getMinutes();
		var se = dt.getSeconds();
		var ms = dt.getMilliseconds();
		var tz = dt.getTimezoneOffset();
		var ampm = hr>12;
		rc = this.pattern_replace(el,pattern,tz,yr,mo,da,hr,mi,se,ms,ampm);
	}
	return rc;
  },
  pattern_cal: function(el,pattern,dt){
	//this.log('pattern_cal:init|pattern=' + pattern + '|dt=' + dt);
	var rc = '';
	if(dt){
		var yr = dt.getFullYear();
		var mo = dt.getMonth() + 1;
		var da = dt.getDate();
		var tz = dt.getTimezoneOffset();
		rc = this.pattern_replace(el,pattern,tz,yr,mo,da,-1,-1,-1,-1,false);
	}
	//this.log('pattern_cal:exit|rc=' + rc);
	return rc;
  },
  pattern_parse: function(el,pattern){
	var rc = new Array();
	var size = this.getLength(pattern);
	var str;
	var lastc;
	var c;
	for(var i=0;i<size;i++){
		c = pattern.charAt(i);//this.getCharAt(mypattern,i);
		if((c!=lastc) && (lastc!='')){
			rc.push(str);
			str = c;
		} else {
			str +=c;
		}
		lastc = c;
	}
	var b = this.isEmpty(str);
	if(!b){
		rc.push(str);
	}
	return rc;
  },
  pattern_replace: function(el,pattern,isTZ,isYR,isMO,isDA,isHR,isMN,isSE,isMS,ampm){
	//this.log('pattern_cal:replace|pattern=' + pattern);
	var ar1 = this.pattern_parse(el,pattern);
	var rc='';
	var i = this.getLength(pattern);
	if(i>0){
		var str;
		var obj;
		var ar2 = new Array(i);
		while(i--){
			str = ar1[i];
			switch(str){
				case "SSS":
					if(isMS>-1){
						var mms = this.convertNumber(el,isMS);
						obj = this.zeroPad(el,mms,3);
					}
					break;
				case "ss":
					if(isSE>-1){
						obj = this.getArrayValue(el,'ss',isSE);
					}
					break;
				case "mm":
					if(isMN>-1){
						obj = this.getArrayValue(el,'mm',isMN);
					}
					break;
				case "hh":
					if(isHR>-1){
						if(isHR>12){
							obj = this.getArrayValue(el,'HH',isHR-12);
						} else {
							obj = this.getArrayValue(el,'HH',isHR);
						}
					}
					break;
				case "HH":
					if(isHR>-1){
						obj = this.getArrayValue(el,'HH',isHR);
					}
					break;
				case "aa":
					if(isHR>-1){
						if(isHR>12){
							ampm=1;
						}
						obj = this.getArrayValue(el,'AA',ampm);
					}
					break;
				case "AA":
					if(isHR>-1){
						if(isHR>12){
							ampm=1;
							var aa = this.getArrayValue(el,'AA',ampm);
							obj = this.toUpper(aa);
						}
					}
					break;
				case "dd": // pass thru
				case "DD":
					if(isDA>-1){
						obj = this.getArrayValue(el,'DD',isDA-1);
					}
					break;
				case "MMMM": // pass thru
				case "MMM": // pass thru
				case "MM": // pass thru
					if(isMO>-1){
						obj = this.getArrayValue(el,str,isMO-1);
					}
					break;
				case "yyyy": // pass thru
				case "YYYY":	obj = this.getArrayYearValue(el,'YYYY',isYR);
					break;
				case "yy": // pass thru
				case "YY":		obj = this.getArrayYearValue(el,'YY',isYR);
					break;
				case "y": // pass thru
				case "Y":		obj = this.getArrayYearValue(el,'Y',isYR);
					break;
				case "GG":		obj = this.getArrayValue(el,'GG',1);// TODO implement 'BC' (0)
					break;
				case "ZZZZ":	obj = this.convertNumber(el,isTZ);
					break;
				case "EEEE":
					if(isYR > -1 && isMO > -1 && isDA > -1){
						var d = this.setDateObj(isYR,isMO,isDA);
						var e = d.getDay();
						obj = this.getArrayValue(el,'DDDD',e);
					}
					break;
				case "EEE":
					if(isYR > -1 && isMO > -1 && isDA > -1){
						var d = this.setDateObj(isYR,isMO,isDA);
						var e = d.getDay();
						obj = this.getArrayValue(el,'DDD',e);
					}
					break;
				case "WW":
					if(isYR > -1 && isMO > -1 && isDA > -1){
						var d = this.setDateObj(isYR,isMO,isDA);
						obj = this.getWeek(el,d);
					}
					break;
				case "JJJJ":
					if(isYR > -1 && isMO > -1 && isDA > -1){
						var d = this.setDateObj(isYR,isMO,isDA);
						obj = this.getJulian(d);
					}
					break;
				case "JJJ":
					if(isYR > -1 && isMO > -1 && isDA > -1){
						var d = this.setDateObj(isYR,isMO,isDA);
						obj = this.getJulianThisYear(d);
					}
					break;
				case ' ':
					obj = str;
					break;
				case ':':
					if(isHR>-1 && isMN>-1){
						obj = str;
					}
					break;
				case '.':
					if(isMS>-1){
						obj = str;
					}
					break;
				case '-':// passthru
				case '/':// passthru
				case ',':
					if(isYR > -1 && isMO > -1 && isDA > -1){
						obj = str;
					}
					break;
				case "d": // pass thru
				case "D": // pass thru
					if(isDA>-1){
						var tmp = this.getArrayValue(el,'DD',isDA-1);
						obj = this.zeroTrim(el,tmp,1);
					}
					break;
				case "M": 
					if(isMO>-1){
						var tmp = this.getArrayValue(el,'MM',isMO-1);
						obj = this.zeroTrim(el,tmp,1);
					}
					break;
				default:
					obj ='';
			}
			var b = this.isEmpty(obj);
			if(!b){
				ar2[i] = obj;
				ar1[i] = '';
			}
		}
		var x;
		var sb = new StringBuffer();
		var size = this.getLength(ar2);
		for(var j=0;j<size;j++){
			x = ar2[j];
			sb.append(x);
		}
		rc = sb.toString();
	}
	return rc;
  },
	calculateTickInterval: function(pattern){
		var rc = 0;
		var hrs = pattern.indexOf('hh') + pattern.indexOf('HH');
		var min = pattern.indexOf('mm'); // NOTE: 'MM' = months!
		var sec = pattern.indexOf('ss') + pattern.indexOf('SS');
		if(sec>0){
			rc = 1;
		} else {
			if(min>0){
				rc = 10;//seconds
			} else {
				if(hrs>0){
					rc = 60;//seconds
				}
			}
		}
		return rc;
	},
	deriveLocales: function(el){
		var locale=this.getLocale(el);
		var DASH = '-';
		var SCORE = '_';
		var clean = '';
		var b0 = this.isEmpty(locale);
		if(b0){
			locale = CS.I18N.I18NDefaultLocale;
		}
		var clean = locale.replace(DASH,SCORE);
		var ar = clean.split(SCORE);
		var language = ar[0];
		var country = ar[1];
		var variant = ar[2];
		var loc0 = '';
		var b1 = this.isEmpty(language);
		if(!b1){
			var loc1 = language;
			rc = new Array(loc1,loc0);
			var b2 = this.isEmpty(country);
			if(!b2){
				var loc2 = language + SCORE + country;
				rc = new Array(loc2,loc1,loc0);
				var b3 = this.isEmpty(variant);
				if(!b3){
					var loc3 = language + SCORE + country + SCORE + variant;
					rc = new Array(loc3,loc2,loc1,loc0);
				}
			}
		} else {
			rc = new Array(loc0);
		}
		return rc;
	},
	getDaysInMonth: function(mo,yr){
		var fullyear = parseInt(yr);
		if(fullyear<1){
			var dt = this.createDate();
			fullyear = dt.getFullYear();
		}
		var leap = this._isLeapYear(fullyear);
		var feb = 28;
		if(leap){
			feb = 29;
		}
		var ar = new Array(0,31,feb,31,30,31,30,31,31,30,31,30,31);
		var rc = ar[mo];
		return rc;
	},
	getJulian: function(dt){
		var rc = Math.floor((dt / 86400000) - (dt.getTimezoneOffset()/1440) + 2440587.5);
		return rc;
	},
	getJulianThisYear:function(dt){
		var target = this.getJulian(dt);
		var year = dt.getFullYear();
		var jan1 = this.setDateObj(year,1,1);//jan 1st
		var jan1j = this.getJulian(jan1);
		var rc = jan1j - target;
		return rc;
	},
	_isLeapYear: function(yr){
		var rc = !(yr%4) && (yr%100) || !(yr%400);
		return rc;
	},
	parseDateField: function(el,pattern,dt_now){
		//this.log('parseDateField:init|el=' + el + '|pattern=' + pattern);
		var val = this.getValue(el);
		var rc = this.parseDateFieldVal(el,val,pattern,dt_now);
		//this.log('parseDateField:exit|rc=' + rc);
		return rc;
	},
	parseDateFieldVal: function(el,val,pattern,dt_now){
		//this.log('parseDateFieldVal:pattern=' + pattern + '|val='+ val);
		if(this.isEmpty(dt_now)){
			dt_now = this.createDate();
		}
		var now_yr = dt_now.getFullYear();
		var now_mo = dt_now.getMonth() + 1;
		var now_da = dt_now.getDate();
		//var now_hrs = dt_now.getHours();
		//var now_mins = dt_now.getMinutes();
		//var now_secs = dt_now.getSeconds();
		var year = this.parseYear(el,val,pattern,now_yr);
		var month = this.parseMonth(el,val,pattern,now_mo);
		var day = this.parseDate(el,val,pattern,now_da);
		//var hour = this.parseDate(el,val,pattern,now_hrs);
		//var mins = this.parseDate(el,val,pattern,now_min);
		//var secs = this.parseDate(el,val,pattern,now_sec);
		var rc = this.setDateObj(year,month,day);
		//this.log('parseDateFieldVal:pattern=' + pattern + '|val=' + val + '|rc=' + rc);
		return rc;
	},
	parseYear: function(el,str,pattern,def){
		var rc = this.parseCommon(el,str,pattern,'Y',def);
		return rc;
	},
	parseMonth: function(el,str,pattern,def){
		//this.log('parseMonth:init');
		var rc = this.parseCommon(el,str,pattern,'M',def);
		//this.log('parseMonth:exit|rc=' + rc + '|str=' + str + '|pattern=' + pattern);
		return rc;
	},
	parseDate: function(el,str,pattern,def){
		var rc = this.parseCommon(el,str,pattern,'D',def);
		return rc;
	},
	parseHour: function(el,str,pattern,def){
		var rc = this.parseCommon(el,str,pattern,'h',def);
		return rc;
	},
	parseMinute: function(el,str,pattern,def){
		var rc = this.parseCommon(el,str,pattern,'m',def);
		return rc;
	},
	parseSecond: function(el,str,pattern,def){
		var rc = this.parseCommon(el,str,pattern,'s',def);
		return rc;
	},
	parseCommon: function(el,str,pattern,abbr,def){
		//this.log('parseCommon:init|pattern=' + pattern + '|str=' + str + '|abbr=' + abbr);
		var shortpattern = this.getShortPattern(pattern,abbr);
		var val = this.extractPatternValue(el,str,pattern,shortpattern,def);
		var rc = '';
		if(abbr=='Y'){
			rc = this.getArrayYearValue(el,shortpattern,val);
		} else {
			rc = val;
		}
		//this.log('parseCommon:exit|rc=' + rc);
		return rc;
	},
	getValue: function(el,inputValue){
		// NOTE: inputValue (when true) will effect the returncode from 'SELECT' items (the inputvalue in the HTML vs. the displayed text on the page), might also be useful for BUTTON and PASSWORD in the future
		//this.log('getValue:init|el=' + el);
		var rc = '';
		if(el){
			var tag = this.getTagName(el);
			if(tag=='INPUT' || tag=='BUTTON' || tag=='TEXTAREA'){
				//rc = el.value;
				var type = this.getType(el);
				if(type=='CHECKBOX'){
					var checked = this.isChecked(el);
					if(checked==true){
						rc = el.value;
					} 
				} else { 
					if(type=='RADIO'){
						rc = this.getRadioSelectedText(el);
					} else {
						rc = el.value;
					}
				}
			} else {
				if(tag=='SELECT'){
					if(inputValue==true){
						rc = this.getDropdownSelectedValue(el);
					} else {
						rc = this.getDropdownSelectedText(el);
					}
				} else {
					rc = this.getInnerText(el);
				}
			}
		}
		//this.log('getValue:exit|rc=' + rc);
		return rc;
	},
	setValue: function(el,str){
		//this.log('setValue:init|el=' + el);
		if(el){
			var tag = this.getTagName(el);
			if(tag=='INPUT' || tag=='BUTTON' || tag=='TEXTAREA'){
				var type = this.getType(el);
				if(type=='RADIO' || type=='CHECKBOX'){
					this.setRadioSelectedText(el,str);
				} else {
					el.value = str;
				}
			} else {
				if(tag=='SELECT'){
					this.setDropdownSelectedText(el,str);
				} else {
					el.update(str);
				}
			}
		}
		//this.log('setValue:exit');
	},
	getType: function(el){
		var rc='';
		if(el){
			rc = this.toUpper(el.readAttribute('type'));
		}
		return rc;
	},
	getDropdownSelectedValue: function(el){
		var rc = '';
		if(el){
			var selected = el.selectedIndex;
			rc = el.options[selected].value;
		}
		return rc;
	},
	getDropdownSelectedText: function(el){
		var rc = '';
		if(el){
			var selected = el.selectedIndex;
			rc = el.options[selected].text;
		}
		return rc;
	},
	setDropdownSelectedText: function(el,str){
		if(el){
			var options = el.options;
			var i = options.length;
			var obj;
			var txt;
			while(i--){
				obj = options[i];
				txt = obj.text;
				if(txt==str){
					el.selectedIndex = i;
					break;
				}
			}
		}
	},
	setRadioSelectedText: function(el,str){
		// TODO if there is ever a requirement
	},
	getRadioSelectedText: function(el){
		var rc = '';
		if(el){
			var nam = el.readAttribute('name');
			var formEl = CS.v3.getParentElement(el,'FORM');//el.up('FORM');
			var str = 'INPUT';//'INPUT[name=' + nam + ']';
			var ar = formEl.select(str);
			var i = ar.length;
			var inp;
			var objnam;
			var chk;
			while(i--){
				inp = ar[i];
				objnam = inp.readAttribute('name');
				if(objnam==nam){
					chk = this.isChecked(inp);
					if(chk){
						rc = inp.value;// NOTE: do not use getValue() as it is recursive with this!
						break;//test
					}
				}
			}
		}
		return rc;
	},
	isChecked: function(el){
		var rc = false;
		if(el){
			rc = el.checked;
		}
		return rc;
	},
	setDataAttribute: function(el,nam,val){
		this.updateAttribute(el,nam,val);
	},
	getDataAttribute: function(el,val,def){
		var x='';
		if(el){
			x = el.readAttribute(val);// HTML5 
		}
		if(this.isEmpty(x)){
			rc = def;
		} else {
			rc = x;
		}
		return rc;
	},
	updateAttribute: function(el,nam,val){
		if(el){
			try{
				if(el.hasAttribute(nam)){
					el.removeAttribute(nam);
				}
				el.writeAttribute(nam,val);
			}
			catch(e){
				this.log('updateAttribute:e=' + e + '|el=' + el);
			}
		}
	},
	setCustomAttributeDateTime: function(el,val){
		this.setDataAttribute(el,'data-csSort',val);// HTML5
	},
	getCustomAttributeDateTime: function(el,def){
		var rc = this.getDataAttribute(el,'data-csSort',def);// HTML5 
		return rc;
	},
	setCustomAttributePattern: function(el,val){
		this.setDataAttribute(el,'data-csPattern',val);// HTML5
	},
	getCustomAttributePattern: function(el,def){
		var rc = this.getDataAttribute(el,'data-csPattern',def);// HTML5 
		return rc;
	},
	getCustomAttributeBaseYear: function(el){
		var def = this.findProperty(el,'baseyear'); //0
		var rc = this.getDataAttribute(el,'data-csBaseyear',def);// HTML5
		return rc;
	},
	getUTC: function(){
		var dt = this.createDate();
		var now = dt.getTime();
		var min = dt.getTimezoneOffset();
		var offset = this.calcOffset('',0,0,min,0,0);
		var utc = now + offset;
		//var x = this.getClientTZOffset();
		//var diff = now-utc;
		return utc;
	},
	getClientTZOffset: function(){
		var dt = this.createDate();
		var min = dt.getTimezoneOffset();
		var rc = this.calcOffset('',0,0,min,0,0);
		return rc;
	},
	getCustomAttributeOffset: function(el,def,pattern){
		var rc = 0;
		var str = el.readAttribute('data-csOffset'); // HTML5
		if(this.isEmpty(str)){
			//str = this.getClientTZOffset();
			//this.setCustomAttributeOffset(str);
			rc = def;
		} else {
			var b = this.isEmpty(pattern);
			if(!b){
				var p = this.toLower(pattern);
				var x = this.extractPatternValue(el,str,p,'x','');
				var d = this.extractPatternValue(el,str,p,'dd',0);
				var h = this.extractPatternValue(el,str,p,'hh',0);
				var m = this.extractPatternValue(el,str,p,'mm',0);
				var s = this.extractPatternValue(el,str,p,'ss',0);
			
				rc = this.calcOffset(x,d,h,m,s,0);
				//this.log('getCustomAttributeOffset:mmsoffset=' + p + '|h=' + h + '|m=' + m + '|s=' + s + '|x=' + x + '|rc=' + rc);
			} else {
				var min = parseInt(str);
				rc = this.calcOffset('',0,0,min,0,0);
			}
		}
		return rc;
	},
	extractPatternValue: function(el,val,str,pattern,def){
		//this.log('extractPatternValue:init|val=' + val);
		var rc = '';
		var bval = this.isEmpty(val);
		if(!bval){
			var bstr = this.isEmpty(str);
			if(!bstr){
				var bpat = this.isEmpty(pattern);
				if(!bpat){
					var idx = str.indexOf(pattern);
					if(idx>-1){
						var size;
						if((pattern=='MMM') || (pattern=='MMMM')){
							if(idx>1){
								idx = idx-1;//setback for some delims
							}
							size = this.getLength(str) - idx;
						} else {
							size = this.getLength(pattern);
						}
						//this.log('extractPatternValue:pattern=' + pattern + '|val=' + val + '|str=' + str + '|idx=' + idx + '|size=' + size);
						var pat = str.substring(idx,idx+size);
						var bp = this.isEmpty(pat);
						if(!bp){
							try{
								/* NOTE: in future use el and getArray  for I18N externalization! */
								var delims = this.findProperty(el,'date_delimiters');
								if(delims){
									var x = val.substring(idx,idx+size);
									while(this.containsDelimiters(x,delims)){
										idx++;
										x = val.substring(idx,idx+size);
									}
								}
							}
							catch(e){
								this.log('extractPatternValue:e=' + e);
							}
							//this.log('extractPatternValue:x=' + x + '|c=' + c);
							rc = this.matchArrayValue(el,pattern,x); // test
						}
					}
				}
			}
		}
		if(this.isEmpty(rc)){
			rc = def;
		}
		//this.log('extractPatternValue:exit|rc=' + rc);
		return rc;
	},
	containsDelimiters: function(str,ar){
		//this.log('containsDelimiters:init|str=' + str);
		var rc = false;
		var i = ar.length;
		var obj;
		while(i--){
			obj = ar[i];
			if(str.indexOf(obj)>-1){ 
				rc = true;
				break;
			}
		}
		//this.log('containsDelimiters:exit|rc=' + rc);
		return rc;
	},
	getShortPattern: function(str,pattern){
 		var rc = '';
		var bstr = this.isEmpty(str);
		if(!bstr){
			var bpat = this.isEmpty(pattern);
			if(!bpat){
				var idx_start=str.indexOf(pattern);
				var size = this.getLength(str);
				var idx_stop = idx_start;
				var x;
				for(var i=idx_start-1;i<=size;i++){
					x = str.indexOf(pattern,i);
					if(x>=idx_start){
						idx_stop = i;
					}
				}
				var part = str.substring(idx_start,idx_stop+1);
				rc = new String(part);
			}
		}
		return rc;
	},
	setCustomAttributeOffset: function(el,val){
		this.setDataAttribute(el,'data-csOffset',val);
	},
	getWeek: function(el,dt){
		var d=this.createDate(dt.valueOf());
		var dayNr=(d.getDay()+6)%7;
		d.setDate(d.getDate()-dayNr+3);
		var year=d.getFullYear();
		var jan4=this.setDateObj(year,1,4);//jan4
		var dayDiff=(d-jan4)/86400000;
		var weekNum=(1+Math.ceil(dayDiff/7) - 4); // -4 for bug fix? 
		var rc=this.convertNumber(el,weekNum);
		return rc;
	},
	matchArrayValue: function(el,pattern,val){
		//this.log('matchArrayValue:init|pattern=' + pattern + '|val=' + val);
		var rc = '';
		var ar = this.findArray(el,pattern);
		if(ar==null){
			rc = val;//usually for YYYY or YY
		} else {
			var pval = this.getLength(val);
			var plen = this.getLength(pattern);
			if(pval<plen){
				val = this.zeroPad(el,val,plen);
			}
			var i = this.getLength(ar);
			var lc = this.toLower(val);
			var item;
			var ilc;
			while(i--){
				item = ar[i];
				ilc = this.toLower(item);
				if(ilc==lc){
					rc = i + 1;
					break;
				}
				// TODO consider adding a 'possibilities' array and use it if only 1, else best match.
			}
		}
		//this.log('matchArrayValue:exit|rc=' + rc);
		return rc;
	},
	toLower: function(val){
		var rc = '';
		if(val){
			rc = val.toLowerCase();
		}
		return rc;
	},
	toUpper: function(val){
		var rc = '';
		if(val){
			rc = val.toUpperCase();
		}
		return rc;
	},
	getLength: function(obj){
		var type='';
		var rc = 0;
		var b = this.isEmpty(obj);
		if(!b){
			type = typeof(obj);
			rc = obj.length;
			if(type == 'string'){
				// as above
			} else {
				if(type == 'object'){
					// future work for objects
				} else {
					if(type == 'number'){
						var str = new String(obj);
						rc = str.length;
						//this.log('getLength():got a Number:' + obj + '|type=' + type);
					} else {
						// future work?
						this.log('getLength():got an unknown:' + obj + '|type=' + type);
					}
					
				}
			}
		}
		return rc;
	},
	findArray: function(el,pattern){
		var rc = null;
		var key = null;
		if(pattern=='MMMM'){ key='months_long'; } else {
			if(pattern=='MMM'){ key='months_short'; } else {
				if((pattern=='MM')||(pattern=='M')){ key='months_numeric'; } else {
					if(pattern=='DDDD'){ key='days_long'; } else {
						if(pattern=='DDD'){ key='days_short'; } else {
							if((pattern=='DD')||(pattern=='D')){ key='days_numeric'; } else {
								if((pattern=='HH') || (pattern=='hh')){ key='hours_numeric'; } else {
									if(pattern=='mm'){ key='minutes_numeric'; } else {
										if((pattern=='SS') || (pattern=='ss')){ key='seconds_numeric'; } else {
											if((pattern=='AA') || (pattern=='aa')){ key='time_am_pm'; } else {
												if((pattern=='GG') || (pattern=='gg')){ key='eras'; } else {
													if((pattern=='YYYY') || (pattern=='YY') || (pattern=='Y') ){ key = null; } else {
														if((pattern=='-') || (pattern=='+')){ key='numeric'; } else {
															this.log('findArray:bad pattern:' + pattern);
														}
													}
												}
											}
										}
									}
								}
							}
						}
					}
				}
			}
		}
		if(key!=null){
			rc = this.findProperty(el,key);
		}
		return rc;
	},
	getArrayYearValue: function(el,pattern,val){
		//this.log('getArrayYearValue:enter:val=[' + val + ']');
		if(val == 0){
			var todayVal = CS.v3.I18N.createDate();
			val = todayVal.getFullYear();
		}
		var x = this.getCustomAttributeBaseYear(el);
		var baseyear = parseInt(x);
		//var str = this.rightString(val,2);
		var i = parseInt(val);
		if(i < baseyear){
			val = 100 + i;
		}
		var patstr = new String(pattern);
		var size = this.getLength(patstr);
		var str = this.rightString(val,size);
		var rc = this.convertNumber(el,str);
		//this.log('getArrayYearValue:exit:rc=[' + rc + ']');
		return rc;
	},
	getArrayValue: function(el,pattern,val){
		//this.log('getArrayValue:init|pattern=' + pattern + '|val=' + val);
		var ar = this.findArray(el,pattern);
		var rc = this.arrayHelper(ar,val);
		//this.log('getArrayValue:exit|rc=' + rc);
		return rc;
	},
	equalDates: function(dt1,dt2){
		var rc = false;
		//try{
			var yr1 = dt1.getFullYear();
			var yr2 = dt2.getFullYear();
			if(yr1==yr2){
				var mo1 = dt1.getMonth();
				var mo2 = dt2.getMonth();
				if(mo1==mo2){
					var da1 = dt1.getDate();
					var da2 = dt2.getDate();
					if(da1==da2){
						rc = true;
					}
				}
			}
		//}
		//catch(e){
			// likely undefined date
		//}
		return rc;
	},
	addError: function(el){
		if(el){
			if (!el.hasClassName('csError')){
				el.addClassName('csError');
			}
		}
	},
	removeError: function(el){
		if(el){
			if (el.hasClassName('csError')){
				el.removeClassName('csError');
			}
		}
	},
	parseInputDate: function(el){
		var val = this.getValue(el);
		var dt_now = this.createDate();
		var pattern = this.getCustomAttributePattern(el,'');
		var rc = this.parseDateFieldVal(el, val, pattern, dt_now);
		return rc;
	},
	addProperty: function(key,locale,val){
		CS.I18N.addProperty(key,locale,val);
	},
	findProperty: function(el,key){
		var rc = null;
		var ar = this.deriveLocales(el);
		var size = this.getLength(ar);
		var i = 0;
		var locale;
		while(rc==null && i<size){
			locale = ar[i];
			rc = this.findPropertyLocale(key,locale);
			i++;
		}
		return rc;
	},
	findPropertyLocale: function(key,locale){
		var hash = this.findHash(key,locale);
		var rc = CS.I18N.I18NValues[hash];
		return rc;
	},
	findHash: function(key,locale){
		return CS.I18N.findHash(key,locale);
	},
	reverseString: function(val) {
		var rc = '';
		if (val){
			var revstr = '';
			var str = new String(val);
			var x = this.getLength(str);
			var s;
			while(x--){
				s = this.getCharAt(str,x);
				revstr += s;
			}
			rc = revstr;
		}
		return rc;
	},
	trimString: function(str){
		str = str.replace(/^\s+/, '');
		for(var i = str.length - 1; i >= 0; i--){
			if (/\S/.test(str.charAt(i))) {
				str = str.substring(0, i + 1);
				break;
			}
		}
		return str;
	},
	getCharAt:function(str,i){
		var rc = '';
		if(i < str.length){
			rc = str.charAt(i);
		}
		return rc;
	},
	setCharAt:function(str,i,chr) {
		var rc = '';
		if(i > str.length-1){
			rc = str;
		} else {
			rc = str.substr(0,i) + chr + str.substr(i+1);
		}
		return rc;
	},
	replaceString:function(str,oldVal,newVal){
		var rc = str.toString();
		var b = this.isEmpty(str);
		if(!b){
			var old = str;
			var changed = true;
			// loop until all are replaced
			while(changed){
				rc = rc.replace(oldVal,newVal);
				if(rc==old){
					changed = false;
				} else {
					//changed = true;
					old = rc;
				}
			}
		}
		return rc;
	},
	getInnerText: function(el){
		var rc = '';
		if(el){
			var str = el.textContent;
			var b = this.isEmpty(str);
			if(!b){
				rc = str;
			} else {
				var txt = el.innerText;
				rc = txt;
			}
		}
		return rc;
	},
	setInnerText: function(el,str){
		if (el) {
			if (typeof el.textContent != 'undefined'){
				el.textContent = str;
			} else {
				if (typeof el.innerText != 'undefined'){
					el.innerText = str;
				} else {
					if (typeof el.removeChild != 'undefined'){
						while (el.hasChildNodes()) {
							el.removeChild(el.lastChild);
						}
						el.appendChild(document.createTextNode(str));
					}
				}
			}
		}
	},
	getCurrentSize: function(el){
		var val = this.getValue(el);
		var str = this.getLength(val);
		var rc = parseInt(str);
		return rc;
	},
	truncateString: function(val,maxsize){
		var rc = val;
		if(this.getLength(val)>maxsize){
			// TODO this will require future work for surrogate/supplemental Unicode bytes!
			rc = val.substring(0,maxsize);
		}
		return rc;
	},
	rightString: function(str,size){
		var rev = this.reverseString(str);
		var trunc = this.truncateString(rev,size);
		var rc = this.reverseString(trunc);
		return rc;
	},
	assertId: function(el,suffix){
		//this.log('assertId:el=' + el);
		var rc = this.createUniqueIdName(el);
		/*
		var rc = '';
		var id = el.readAttribute('id');
		if(id){
			rc = id;
		} else {
			var nam = el.readAttribute('name');
			if(id){
				rc = nam;
				this.updateAttribute(el,'id',nam);
			} else {
				// create a dynamic ID (safety net)
				var str = this.createUniqueIdName(el,suffix);
				rc = str;
				this.updateAttribute(el,'id',str);
			}
		}
		*/
		//this.log('assertId:rc=' + rc);
		return rc;
	},
	createUniqueIdName: function(el,suffix){
		// NOTE: this is only a safety net, and should not be relied on!
		//var tag = this.getTagName(el);
		//var rc = tag + new Date().getTime() + suffix;// + Math.random();
		var rc = Element.identify(el);
		return rc;
	},
	mergeArrays: function(ar1, ar2){
		//this.log('mergeArrays:init');
		var rc = null;
		var size1 = this.getLength(ar1);
		var size2 = this.getLength(ar2);
		if(size1>0){
			if(size2>0){
				var tmp = ar1;
				var obj;
				var i = size2;
				while(i--){
					obj = ar2[i];
					tmp.push(obj);
				}
				rc = Array.uniq(tmp);
			} else {
				rc = ar1;
			}
		} else {
			rc = ar2;
		}
		//this.log('mergeArrays:exit');
		return rc;
	},
	log: function (s) {
		CS.v3.Logger.log("I18N:" + s);
	}
};
if(!CS.Validators){
	CS.Validators = [];
}
CS.v3.I18N.addProperty('months_short','',new Array("Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"));
CS.v3.I18N.addProperty('months_long','', new Array("January","February","March","April","May","June","July","August","September","October","November","December"));
CS.v3.I18N.addProperty('months_numeric','', new Array("01","02","03","04","05","06","07","08","09","10","11","12"));
CS.v3.I18N.addProperty('days_short','', new Array("S","M","T","W","T","F","S"));
CS.v3.I18N.addProperty('days_long','', new Array("Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"));
CS.v3.I18N.addProperty('days_numeric','', new Array("01","02","03","04","05","06","07","08","09","10","11","12","13","14","15","16","17","18","19","20","21","22","23","24","25","26","27","28","29","30","31"));
CS.v3.I18N.addProperty('days_suffix','', new Array("1st","2nd","3rd","4th","5th","6th","7th","8th","9th","10th","11th","12th","13th","14th","16th","17th","18th","19th","20th","21st","22nd","23rd","24th","25th","26th","27th","28th","29th","30th","31st"));
CS.v3.I18N.addProperty('hours_numeric','', new Array("00","01","02","03","04","05","06","07","08","09","10","11","12","13","14","15","16","17","18","19","20","21","22","23"));
CS.v3.I18N.addProperty('minutes_numeric','', new Array("00","01","02","03","04","05","06","07","08","09","10","11","12","13","14","15","16","17","18","19","20","21","22","23","24","25","26","27","28","29","30","31","32","33","34","35","36","37","38","39","40","41","42","43","44","45","46","47","48","49","50","51","52","53","54","55","56","57","58","59"));
CS.v3.I18N.addProperty('seconds_numeric','', new Array("00","01","02","03","04","05","06","07","08","09","10","11","12","13","14","15","16","17","18","19","20","21","22","23","24","25","26","27","28","29","30","31","32","33","34","35","36","37","38","39","40","41","42","43","44","45","46","47","48","49","50","51","52","53","54","55","56","57","58","59"));
CS.v3.I18N.addProperty('time_am_pm','', new Array("AM","PM"));
CS.v3.I18N.addProperty('eras','', new Array("BC","AD"));
CS.v3.I18N.addProperty('baseyear','', "1970");
CS.v3.I18N.addProperty('numbers','', new Array("0","1","2","3","4","5","6","7","8","9"));
CS.v3.I18N.addProperty('characters','', new Array("A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","X","Y","Z"));
CS.v3.I18N.addProperty('units_long','', new Array("day(s)","hour(s)","minute(s)","second(s)","mms"));
CS.v3.I18N.addProperty('units_short','', new Array("D","H","M","S","mms"));
CS.v3.I18N.addProperty('symbols','', new Array(",",".",":"));
CS.v3.I18N.addProperty('numeric','', new Array("-","+"));
CS.v3.I18N.addProperty('date_delimiters','', new Array("/","-",".",","," "));
CS.v3.I18N.addProperty('currency','', null);
/* FR */
CS.v3.I18N.addProperty('months_short','fr',new Array("janv", "fevr", "mars", "avr", "mai", "juin", "juil", "aout", "sept", "oct", "nov", "dec"));
CS.v3.I18N.addProperty('months_long','fr', new Array("janvier", "fevrier", "mars", "avril", "mai", "juin", "juillet", "aout", "septembre", "octobre", "novembre", "decembre"));
CS.v3.I18N.addProperty('days_long','fr', new Array("dimanche", "lundi", "mardi", "mercredi", "jeudi", "vendredi", "samedi"));
CS.v3.I18N.addProperty('days_short','fr', new Array("D","L","M","M","J","V","S"));

